No internet connection
  1. Home
  2. How to

Select and Delete All Inactive Tracks

By Gabriel Lundh @Gabriel_Lundh
    2021-10-13 18:16:47.861Z

    Hi!
    I'm making a script to remove all inactive tracks in a session, delete unused playlists and clear all unused audio files.
    The latter parts I can find looking in the forum, but selecting and removing all inactive tracks seems to be really hard.

    I've come across @Kitch 's script for loging tracks states, which seems to be a good beginning, but I can't seem to go from there. Any help would be super appreciated!

    function isTrackEnabled(trackName) {
        const track = sf.ui.proTools.trackGetByName({ name: trackName }).track
    
        const isInactive = track.buttons.whoseTitle.is("Mute").first.value.value.startsWith('inactive')
    
        return {
            trackName: trackName,
            isInactive: isInactive
        }
    }
    
    function main() {
        sf.ui.proTools.appActivateMainWindow();
    
        const selectedTrackNames = sf.ui.proTools.selectedTrackNames
    
        let trackActiveStates = [];
    
        selectedTrackNames.forEach(trackName => {
            let result = isTrackEnabled(trackName);
    
            log(result)
    
            trackActiveStates.push(result);
        });
    
        log(trackActiveStates);
    
    }
    
    main();
    
    Solved in post #2, click to view
    • 29 replies

    There are 29 replies. Estimated reading time: 71 minutes

    1. Kitch Membery @Kitch2021-10-13 20:18:20.698Z

      Hi @Gabriel_Lundh,

      This will selected inactive audio tracks from a selection. But will not work on tracks without "Mute" buttons (ie Master, VCA, MIDI, Basic Folder etc). I've left out the delete portion of the script... I'll let you ad that :-)

      function isTrackActive(trackName) {
          const track = sf.ui.proTools.trackGetByName({ name: trackName }).track
      
          const muteBtn = track.buttons.whoseTitle.is("Mute").first;
      
          let isInactive = muteBtn.exists ? track.buttons.whoseTitle.is("Mute").first.value.value.startsWith('inactive') : false;
      
          return {
              trackName: trackName,
              isInactive: isInactive
          }
      }
      
      function main() {
          sf.ui.proTools.appActivateMainWindow();
      
          const selectedTrackNames = sf.ui.proTools.selectedTrackNames;
      
          const trackActiveStates = selectedTrackNames.map(trackName => isTrackActive(trackName));
      
          const inactiveTrackNames = trackActiveStates.filter(track => track.isInactive).map(track => track.trackName);
      
          sf.ui.proTools.trackSelectByName({ names: inactiveTrackNames });
      }
      
      main();
      

      You may want to take a different approach and use the "Track List Pop-up" to show only "Inactive Tracks like this

      And then after selecting and deleting the tracks, click "Restore Previously Shown Tracks".

      I hope that helps

      Rock on!

      PS Great to see you in the webinar today :-)

      ReplySolution
      1. GGabriel Lundh @Gabriel_Lundh
          2021-10-14 12:49:07.678Z

          Hi Kitch!
          So fun to see you yesterday, and great hearing a bit about your background!
          Thanks for this, super helpful! This script helps me handling with tracks in folders, as it deselects routing folders which have inactive tracks in them, so that they are not deleted.
          So big thanks for this, I'll post the script once It's done.

          All the best,
          Gabriel

          1. Kitch Membery @Kitch2021-10-14 17:12:05.429Z

            Great to meet you too legend!!! Glad I could help :-)

          2. In reply toKitch:
            GGabriel Lundh @Gabriel_Lundh
              2021-10-14 17:02:49.828Z

              Hi @Kitch !

              I just wanted to say that I finally figured the whole script out. There came up some serious road bumps while doing the master script, but I managed to get around them by stealing code from around the brilliant forum!
              I take no credit for the functions, everything is made from all you geniuses!!
              I'll share it here!

              function saveSessionAsNewVersion() {
                  //First save the current version
                  sf.ui.proTools.getMenuItem('File', 'Save').elementClick({}, function () { }); //can be disabled
              
                  //Get our filename without extension
                  var fileNameWithoutExtension = sf.ui.proTools.mainWindow.invalidate().sessionPath.split('/').slice(-1)[0].split('.').slice(0, -1).join('.');
              
                  //Create a new name (get the name and suffixed number - if your session name was 'My Session 42' then save 'My Session ' in grps[1] and '42' in grps[2])
                  var grps = fileNameWithoutExtension.match(/^(.+?)(\d+)$/);
              
                  //Construct a new name based on the prefix and the number (+1), followed by the '.ptx' suffix. If there was no number, just add ' 2'
                  var newNumber = !grps || grps.length === 0 || isNaN(Number(grps[2])) ? '_2' : ((Number(grps[2]) + 1) + '');
                  var newName = (grps ? grps[1] : (fileNameWithoutExtension)) + newNumber + '.ptx';
              
                  //Invoke File Save As.
                  sf.ui.proTools.getMenuItem('File', 'Save As...').elementClick();
              
                  //Wait for the Save dialog to appear
                  var dlg = sf.ui.proTools.windows.invalidate().whoseTitle.is('Save').first.elementWaitFor().element;
              
                  //Enter the new name
                  dlg.textFields.first.value.value = newName;
              
                  //Click Save
                  dlg.buttons.whoseTitle.is('Save').first.elementClick();
              }
              
              function selectAllFolderTracks() {
                var visibleTracks = sf.ui.proTools.trackGetVisibleTracks().names
                var firstTrackFound;
                let foundTracks = [];
              
                while (true) {
                  sf.ui.proTools.trackDeselectAll();
                  for (var i = 0; i < visibleTracks.length; i++) {
                    var trackIsFolder = sf.ui.proTools.trackGetByName({ name: visibleTracks[i] }).track.children.whoseRole.is("AXDisclosureTriangle").whoseTitle.is('Open Folder')
              
                    if (trackIsFolder.exists)
                      if (trackIsFolder) {
                        if (!firstTrackFound) { // Scroll to first track found
                          sf.ui.proTools.trackGetByName({ name: visibleTracks[i], }).track.trackScrollToView();
                          firstTrackFound = !firstTrackFound;
                        } else {
                          sf.ui.proTools.trackSelectByName({ names: [visibleTracks[i]], deselectOthers: false });
                        }
                        foundTracks.push(visibleTracks[i]);
                      }
                  } if (foundTracks.length !== 0) {
                    break;
                  } else if (foundTracks.length == 0) {
                    
                    return "exit";
                    
                    
                  }
                }
              }
              
              function openFolderTracks() {
                sf.ui.proTools.appActivateMainWindow();
                while (true) {
                  var temp;
                  temp = selectAllFolderTracks();
                  if (temp == "exit"){
                    return 0;
                  }
                  const selectedTracks = sf.ui.proTools.selectedTrackNames
                  if (selectedTracks.length >= 1) {
                    if (selectedTracks.length == 1) {
                      sf.ui.proTools.selectedTrack.folderTrackSetOpen({
                        targetValue: 'Enable',
                        onError: 'Continue'
                      });
                    } if (selectedTracks.length >= 2) {
                      for (var i = 0; i < selectedTracks.length; i++) {
                        sf.ui.proTools.invalidate().trackGetByName({ name: selectedTracks[i] }).track.folderTrackSetOpen({
                          targetValue: 'Enable',
                        });
                        
                      }
                    }
                  }
                }
              }
              
              function setGroupActive(groupName, targetValue) {
                  let grp = sf.ui.proTools.mainWindow.groupListView.childrenByRole('AXRow').map(r => {
                      let btn = r.childrenByRole('AXCell').allItems[1].buttons.first;
                      return {
                          groupName: r.childrenByRole('AXCell').allItems[1].buttons.first.title.value.split(/-\s/)[1],
                          btn,
                          isActive: btn.title.invalidate().value.indexOf('Active ') === 0,
                          row: r,
                      };
                  }).filter(g => g.groupName === groupName)[0];
                  if (!grp) throw `Group with name "${groupName}" was not found`;
                  if (grp.isActive !== !!targetValue)
                      grp.btn.elementClick();
              }
              
              function isTrackActive(trackName) {
                  const track = sf.ui.proTools.trackGetByName({ name: trackName }).track
              
                  const muteBtn = track.buttons.whoseTitle.is("Mute").first;
              
                  let isInactive = muteBtn.exists ? track.buttons.whoseTitle.is("Mute").first.value.value.startsWith('inactive') : false;
              
                  return {
                      trackName: trackName,
                      isInactive: isInactive
                  }
              }
              
              function selectInactiveTracks() {
                  sf.ui.proTools.appActivateMainWindow();
              
                  const selectedTrackNames = sf.ui.proTools.selectedTrackNames;
              
                  const trackActiveStates = selectedTrackNames.map(trackName => isTrackActive(trackName));
              
                  const inactiveTrackNames = trackActiveStates.filter(track => track.isInactive).map(track => track.trackName);
              
                  sf.ui.proTools.trackSelectByName({ names: inactiveTrackNames });
              }
              
              function dismissDialog(dialogText, buttonName) {
                  const dlg = sf.ui.proTools.confirmationDialog;
                  //Wait 100ms for dialog box to appear
                 dlg.elementWaitFor({
                      timeout: 100,
                      pollingInterval: 10,
                      onError: 'Continue'
                  });
              
                  if (dlg.children.whoseRole.is("AXStaticText").whoseValue.contains(dialogText).first.exists) {
                      dlg.buttons.whoseTitle.is(buttonName).first.elementClick();
              
                      dlg.elementWaitFor({
                          waitType: 'Disappear',
                          timeout: 100,
                          pollingInterval: 10,
                          onError: 'Continue'
                      });
                  }
              }
              
              function dismissDialog2(dialogText, buttonName) {
                  const dlg = sf.ui.proTools.confirmationDialog;
                  //Wait 100ms for dialog box to appear
                 dlg.elementWaitFor({
                      timeout: 100,
                      pollingInterval: 10,
                      onError: 'Continue'
                  });
              
                  if (dlg.children.whoseRole.is("AXStaticText").whoseValue.contains(dialogText).first.exists) {
                      dlg.buttons.whoseTitle.is(buttonName).first.elementClick();
              
                      dlg.elementWaitFor({
                          waitType: 'Disappear',
                          timeout: 100,
                          pollingInterval: 10,
                          onError: 'Continue'
                      });
                  }
              }
              
              function dismissDialog3(dialogText, buttonName) {
                  const dlg = sf.ui.proTools.confirmationDialog;
                  //Wait 100ms for dialog box to appear
                 dlg.elementWaitFor({
                      timeout: 100,
                      pollingInterval: 10,
                      onError: 'Continue'
                  });
              
                  if (dlg.children.whoseRole.is("AXStaticText").whoseValue.contains(dialogText).first.exists) {
                      dlg.buttons.whoseTitle.is(buttonName).first.elementClick();
              
                      dlg.elementWaitFor({
                          waitType: 'Disappear',
                          timeout: 100,
                          pollingInterval: 10,
                          onError: 'Continue'
                      });
                  }
              }
              
              
              function selectAllTracks() {
                  const groupsList = sf.ui.proTools.mainWindow.tables.whoseTitle.is("Group List").first;
                  const firstRow = groupsList.childrenByRole("AXRow");
                  const firstCell = firstRow.first.childrenByRole("AXCell").first.buttons.first;
              
                  firstCell.elementClick();
              }
              
              
              function goToStartOfSession() {
                  sf.ui.proTools.transportEnsureCluster();
              
                  const trannsportCluster = sf.ui.proTools.mainWindow.transportViewCluster;
                  const transportButtons = trannsportCluster.groups.whoseTitle.is("Normal Transport Buttons").first;
                  transportButtons.buttons.whoseTitle.is("Return to Zero").first.elementClick();
              }
              
              
              
              
              function setWindowView() {
                  sf.ui.proTools.menuClick({ menuPath: ["View", "Other Displays", "Track List"], targetValue: "Enable" });
                  sf.ui.proTools.menuClick({ menuPath: ["View", "Other Displays", "Clip List"], targetValue: "Enable" });
                  sf.ui.proTools.mainWindow.buttons.whoseTitle.is("Track List pop-up").first.popupMenuSelect({
                      menuPath: ["Show All Tracks"],
                  });
              
                  function showItems() {
                      function show(item) {
                          sf.ui.proTools.mainWindow.popupButtons.whoseTitle.is('Clip List').first.popupMenuSelect({
                              menuPath: ["Show", item], targetValue: "Enable"
                          });
                      }
                      show("Audio")
                      show("MIDI")
                      show("Video")
                      show("Groups")
                      show("Auto-Created")
                  }
                  showItems()
              }
              
              
              
              
              /**
              * @param {string} trackType - All track types included on trackTypes array
              */
              function deleteUnusedPlaylists(trackType) {
              
                  // Check if there are any tracks of trackType
                  const trackTypeExists = sf.ui.proTools.visibleTrackHeaders.some(x => x.title.invalidate().value.includes(trackType))
              
                  if (trackTypeExists) {
              
                      // Get name of first track of trackType
                      const firstTrackByTypeName = sf.ui.proTools.visibleTrackHeaders.filter(x => x.title.invalidate().value.includes(trackType))[0].normalizedTrackName
              
                      // Find track by name
                      const getFirstTrackByTypeName = sf.ui.proTools.trackGetByName({ name: firstTrackByTypeName }).track
              
                      // Scrool track if needed
                      getFirstTrackByTypeName.trackScrollToView()
              
                      // Delete unused menu
                      getFirstTrackByTypeName.popupButtons.whoseTitle.is("Playlist selector").first.popupMenuSelect({ menuPath: ["Delete Unused..."] });
              
                      // Delete unused window
                      const deleteUnusedWin = sf.ui.proTools.windows.whoseTitle.is("Delete Unused Playlists").first
              
                      if (deleteUnusedWin.exists) {
                          const deleteUnusedWinTable = deleteUnusedWin.tables.first.children.whoseRole.is("AXRow")
              
                          // Select all unused playlists
                          deleteUnusedWinTable.map(x => x.children.first.children.whoseRole.is("AXStaticText").first.elementClick())
              
                          // Click delete Btn
                          deleteUnusedWin.buttons.whoseTitle.is("Delete").first.elementClick();
                      };
                  };
              };
              
              
              function deletePlaylistesMain() {
              
                  sf.ui.proTools.appActivateMainWindow();
              
                  //  show Track list, Clip list and All tracks
                  setWindowView()
                  
              
                  // Clear all items from clip list
                  
              
                  //  delete unused playlists, needs to be done on all track types
                  const trackTypes = [
                      "Video Track",
                      "MIDI Track",
                      "Inst Track",
                      "Audio Track"
                  ]
              
                  trackTypes.forEach(deleteUnusedPlaylists)
              
              }
              
              
              
              
              function saveAndClose() {
              
                  while (true) {
              
                      //// wait for complete tasks
                      if (sf.ui.proTools.windows.whoseTitle.is('Task Manager').first.children.whoseRole.is("AXStaticText").first.invalidate().value.value == "0 items")
              
                          //// save and exit procedures
                          if ((sf.ui.proTools.mainWindow.invalidate().sessionPath !== null || sf.ui.proTools.getMenuItem('File', 'Close Session').isEnabled)
                              || sf.ui.proTools.confirmationDialog.exists) {
              
                              sf.ui.proTools.waitForNoModals();
              
                              sf.ui.proTools.menuClick({ menuPath: ["File", "Save"] });
              
                              sf.ui.proTools.menuClick({ menuPath: ["File", "Close Session"] });
              
                              if (sf.ui.proTools.confirmationDialog.invalidate().buttons.whoseTitle.is('Save').first.exists) {
                                  sf.ui.proTools.confirmationDialog.buttons.whoseTitle.is('Save').first.elementClick();
                                  sf.ui.proTools.confirmationDialog.elementWaitFor({ waitType: "Disappear", onError: "Continue" });
                              }
                              if (sf.ui.proTools.confirmationDialog.invalidate().buttons.whoseTitle.is('Cancel').first.exists) {
                                  sf.ui.proTools.confirmationDialog.buttons.whoseTitle.is('Cancel').first.elementClick();
                                  sf.ui.proTools.confirmationDialog.elementWaitFor({ waitType: "Disappear", onError: "Continue" });
                              }
              
                              sf.ui.proTools.waitForNoModals();
              
                          } else {
                              break
                          }
                      sf.wait({ intervalMs: 500 })
                  }
              }
              
              
              function waitForOpenSession(m1, m2) {
              
                  while (!sf.ui.proTools.getMenuItem(m1, m2).isEnabled) {
                      // Reset menu
                      sf.keyboard.press({ keys: "left" });
              
                      sf.wait({ intervalMs: 100 });
                  }
              }
              
              
              function saveCloseAndOpenAgain (){
                  saveAndClose()
                  
                  sf.ui.proTools.mainWindow.elementWaitFor({ waitType: "Disappear", timeout: -1 });
              
                  sf.file.open({
                      path: sessionDir
              
                  });
              
                  //  Wait fo menus to become enabled, thus sessioon is fully opened
                  waitForOpenSession('File', 'Save');
              
              }
              
              
              saveSessionAsNewVersion();
              
              sf.ui.proTools.appActivateMainWindow
              
              openFolderTracks();
              
              var popupMenu = sf.ui.proTools.trackOpenListPopupMenu().popupMenu;
                  popupMenu.menuClickPopupMenu({
                  menuPath: ["Show Only", "Inactive Tracks"],
              });
              
              setGroupActive("<ALL>", true);
              
              sf.ui.proTools.mainWindow.buttons.whoseTitle.is("Edit Keyboard Focus").first.mouseClickElement({
                  relativePosition: {"x":-10,"y":7},
                  anchor: "BottomLeft",
              });
              
              setGroupActive("<ALL>", false);
              
              selectInactiveTracks();
              
              sf.ui.proTools.trackDelete();
              
              dismissDialog("Active clips were found","Delete");
              
              dismissDialog2("The track","Delete");
              
              var popupMenu = sf.ui.proTools.trackOpenListPopupMenu().popupMenu;
                  popupMenu.menuClickPopupMenu({
                  menuPath: ["Show All Tracks"],
              });
              
              deletePlaylistesMain()
              
              sf.ui.proTools.menuClick({
                menuPath: ["View","Other Displays","Clip List"],
                targetValue: "Enable",
              });
              
              sf.ui.proTools.mainWindow.popupButtons.whoseTitle.is('Clip List').first.popupMenuSelect({
                  menuPath: ["Select","\"Select Unused\" Ignores Parent Clip"],
                  targetValue: "Disable",
              });
              
              sf.keyboard.press({
                  keys: "cmd+shift+u",
              });
              
              sf.ui.proTools.mainWindow.popupButtons.whoseTitle.is('Clip List').first.popupMenuSelect({
                  menuPath: ["Clear..."],
                  
              });
              
              dismissDialog3("REMOVE","Remove");
              
              
              /// Need task manager to close sessions
              if (!sf.ui.proTools.getMenuItem("Window", "Task Manager").isMenuChecked) {
                  sf.ui.proTools.menuClick({ menuPath: ["Window", "Task Manager"], targetValue: "Enable" });
              }
              var sessionDir = sf.ui.proTools.mainWindow.sessionPath
              
              saveCloseAndOpenAgain();
              
              sf.ui.proTools.menuClick({
                menuPath: ["View","Other Displays","Clip List"],
                targetValue: "Enable",
              });
              
              
              sf.keyboard.press({
                  keys: "cmd+shift+u",
              });
              
              sf.ui.proTools.mainWindow.popupButtons.whoseTitle.is('Clip List').first.popupMenuSelect({
                  menuPath: ["Clear..."],
                  
              });
              
              dismissDialog3("REMOVE","Remove");
              
              sf.keyboard.press({ keys: "left" });
              
              sf.ui.proTools.menuClick({
                  menuPath: ["Window","Task Manager"],
                  targetValue: "Disable",
              });
              1. Kitch Membery @Kitch2021-10-14 17:18:27.506Z

                Wow! Epic! I’ll have a closer look at it later.

                Nice work!

            • In reply toGabriel_Lundh:

              @Kitch were you able to get this to work? didn't work on my system but would LOVE this option. Thanks for building it @Gabriel_Lundh

              1. Kitch Membery @Kitch2022-01-11 08:00:42.501Z

                Hi @Brett_Ryan_Stewart,

                Which script are you trying to run? Were you seeing an error message when running the script?

                Rock on!

                1. GGabriel Lundh @Gabriel_Lundh
                    2022-01-11 09:38:27.396Z

                    Hi @Brett_Ryan_Stewart !
                    Please let us know - the script is working here - BUT - I still have to put the time in and figure out all the possible Dialog boxes that could potentially pop up.
                    If you've for example just removed a clip, that is in your undo que, the script fails as I've not put in a dismiss Dialog for that yet. I just press OK and run the script again if it fails - as it's rather quick :)

                    @Kitch, do you have any idea on how to dismiss all potential dialogs that could pop up during this script? I've been using your script for this as you can see - but it is a lot of potential and trying to figure out the right order of these potential dialogs that makes this script so hard to make bullet proof.

                    Thanks!

                    All the best,
                    Gabriel

                    1. @Gabriel_Lundh @Kitch strangely today it worked! Very cool! It did pop up an error if this is helpful...
                      Could not click popup menu item (Select and Delete Inactive Tracks: Line 219)

                      That said, there weren't any leftover popups on the screen.

                      1. GGabriel Lundh @Gabriel_Lundh
                          2022-01-12 11:02:22.544Z

                          Perfect @Brett_Ryan_Stewart ! Interesting that that failed - could have been something that messed with the clip list. I'll try and make this more bullet proof in the coming days! Let's see if the brilliant @Kitch has any idea of making a generic "close all potential pop up dialogs" option.

                          All the best,
                          Gabriel

                          1. Dig that man! Hey is this going to be in the store? JW because I'll wanna to stay abreast to updates :-)

                            1. In reply toGabriel_Lundh:
                              Kitch Membery @Kitch2022-01-12 19:51:20.922Z

                              You're too kind :-)

                              I do have an idea on how to attempt this but I won't be able to get around to it for the next couple of weeks. Bump me in this thread in a couple of weeks and I'll see what I can do :-)

                              Rock on!

                              1. In reply toGabriel_Lundh:
                                Kitch Membery @Kitch2022-01-12 20:08:33.393Z2022-01-12 22:21:23.077Z

                                One thing I'm noticing in your script is that you've duplicated the dismissDialog function three times ie dismissDialog, dismissDialog2, dismissDialog3. You only need the first function;

                                Here is a super quick refactor to remove them. I also created a main function so the script is a little easier to read.

                                function saveSessionAsNewVersion() {
                                    //First save the current version
                                    sf.ui.proTools.getMenuItem('File', 'Save').elementClick({}, function () { }); //can be disabled
                                
                                    //Get our filename without extension
                                    var fileNameWithoutExtension = sf.ui.proTools.mainWindow.invalidate().sessionPath.split('/').slice(-1)[0].split('.').slice(0, -1).join('.');
                                
                                    //Create a new name (get the name and suffixed number - if your session name was 'My Session 42' then save 'My Session ' in grps[1] and '42' in grps[2])
                                    var grps = fileNameWithoutExtension.match(/^(.+?)(\d+)$/);
                                
                                    //Construct a new name based on the prefix and the number (+1), followed by the '.ptx' suffix. If there was no number, just add ' 2'
                                    var newNumber = !grps || grps.length === 0 || isNaN(Number(grps[2])) ? '_2' : ((Number(grps[2]) + 1) + '');
                                    var newName = (grps ? grps[1] : (fileNameWithoutExtension)) + newNumber + '.ptx';
                                
                                    //Invoke File Save As.
                                    sf.ui.proTools.getMenuItem('File', 'Save As...').elementClick();
                                
                                    //Wait for the Save dialog to appear
                                    var dlg = sf.ui.proTools.windows.invalidate().whoseTitle.is('Save').first.elementWaitFor().element;
                                
                                    //Enter the new name
                                    dlg.textFields.first.value.value = newName;
                                
                                    //Click Save
                                    dlg.buttons.whoseTitle.is('Save').first.elementClick();
                                }
                                
                                function selectAllFolderTracks() {
                                    var visibleTracks = sf.ui.proTools.trackGetVisibleTracks().names
                                    var firstTrackFound;
                                    let foundTracks = [];
                                
                                    while (true) {
                                        sf.ui.proTools.trackDeselectAll();
                                        for (var i = 0; i < visibleTracks.length; i++) {
                                            var trackIsFolder = sf.ui.proTools.trackGetByName({ name: visibleTracks[i] }).track.children.whoseRole.is("AXDisclosureTriangle").whoseTitle.is('Open Folder')
                                
                                            if (trackIsFolder.exists)
                                                if (trackIsFolder) {
                                                    if (!firstTrackFound) { // Scroll to first track found
                                                        sf.ui.proTools.trackGetByName({ name: visibleTracks[i], }).track.trackScrollToView();
                                                        firstTrackFound = !firstTrackFound;
                                                    } else {
                                                        sf.ui.proTools.trackSelectByName({ names: [visibleTracks[i]], deselectOthers: false });
                                                    }
                                                    foundTracks.push(visibleTracks[i]);
                                                }
                                        } if (foundTracks.length !== 0) {
                                            break;
                                        } else if (foundTracks.length == 0) {
                                
                                            return "exit";
                                        }
                                    }
                                }
                                
                                function openFolderTracks() {
                                    sf.ui.proTools.appActivateMainWindow();
                                    while (true) {
                                        var temp;
                                        temp = selectAllFolderTracks();
                                        if (temp == "exit") {
                                            return 0;
                                        }
                                        const selectedTracks = sf.ui.proTools.selectedTrackNames
                                        if (selectedTracks.length >= 1) {
                                            if (selectedTracks.length == 1) {
                                                sf.ui.proTools.selectedTrack.folderTrackSetOpen({
                                                    targetValue: 'Enable',
                                                    onError: 'Continue'
                                                });
                                            } if (selectedTracks.length >= 2) {
                                                for (var i = 0; i < selectedTracks.length; i++) {
                                                    sf.ui.proTools.invalidate().trackGetByName({ name: selectedTracks[i] }).track.folderTrackSetOpen({
                                                        targetValue: 'Enable',
                                                    });
                                                }
                                            }
                                        }
                                    }
                                }
                                
                                function setGroupActive(groupName, targetValue) {
                                    let grp = sf.ui.proTools.mainWindow.groupListView.childrenByRole('AXRow').map(r => {
                                        let btn = r.childrenByRole('AXCell').allItems[1].buttons.first;
                                        return {
                                            groupName: r.childrenByRole('AXCell').allItems[1].buttons.first.title.value.split(/-\s/)[1],
                                            btn,
                                            isActive: btn.title.invalidate().value.indexOf('Active ') === 0,
                                            row: r,
                                        };
                                    }).filter(g => g.groupName === groupName)[0];
                                
                                    if (!grp) throw `Group with name "${groupName}" was not found`;
                                
                                    if (grp.isActive !== !!targetValue)
                                        grp.btn.elementClick();
                                }
                                
                                function isTrackActive(trackName) {
                                    const track = sf.ui.proTools.trackGetByName({ name: trackName }).track
                                
                                    const muteBtn = track.buttons.whoseTitle.is("Mute").first;
                                
                                    let isInactive = muteBtn.exists ? track.buttons.whoseTitle.is("Mute").first.value.value.startsWith('inactive') : false;
                                
                                    return {
                                        trackName: trackName,
                                        isInactive: isInactive
                                    }
                                }
                                
                                function selectInactiveTracks() {
                                    sf.ui.proTools.appActivateMainWindow();
                                
                                    const selectedTrackNames = sf.ui.proTools.selectedTrackNames;
                                    const trackActiveStates = selectedTrackNames.map(trackName => isTrackActive(trackName));
                                    const inactiveTrackNames = trackActiveStates.filter(track => track.isInactive).map(track => track.trackName);
                                
                                    sf.ui.proTools.trackSelectByName({ names: inactiveTrackNames });
                                }
                                
                                function dismissDialog(dialogText, buttonName) {
                                    const dlg = sf.ui.proTools.confirmationDialog;
                                    //Wait 100ms for dialog box to appear
                                    dlg.elementWaitFor({
                                        timeout: 100,
                                        pollingInterval: 10,
                                        onError: 'Continue'
                                    });
                                
                                    if (dlg.children.whoseRole.is("AXStaticText").whoseValue.contains(dialogText).first.exists) {
                                        dlg.buttons.whoseTitle.is(buttonName).first.elementClick();
                                
                                        dlg.elementWaitFor({
                                            waitType: 'Disappear',
                                            timeout: 100,
                                            pollingInterval: 10,
                                            onError: 'Continue'
                                        });
                                    }
                                }
                                
                                function selectAllTracks() {
                                    const groupsList = sf.ui.proTools.mainWindow.tables.whoseTitle.is("Group List").first;
                                    const firstRow = groupsList.childrenByRole("AXRow");
                                    const firstCell = firstRow.first.childrenByRole("AXCell").first.buttons.first;
                                
                                    firstCell.elementClick();
                                }
                                
                                function goToStartOfSession() {
                                    sf.ui.proTools.transportEnsureCluster();
                                
                                    const trannsportCluster = sf.ui.proTools.mainWindow.transportViewCluster;
                                    const transportButtons = trannsportCluster.groups.whoseTitle.is("Normal Transport Buttons").first;
                                    transportButtons.buttons.whoseTitle.is("Return to Zero").first.elementClick();
                                }
                                
                                function setWindowView() {
                                    sf.ui.proTools.menuClick({ menuPath: ["View", "Other Displays", "Track List"], targetValue: "Enable" });
                                    sf.ui.proTools.menuClick({ menuPath: ["View", "Other Displays", "Clip List"], targetValue: "Enable" });
                                    sf.ui.proTools.mainWindow.buttons.whoseTitle.is("Track List pop-up").first.popupMenuSelect({
                                        menuPath: ["Show All Tracks"],
                                    });
                                
                                    function showItems() {
                                        function show(item) {
                                            sf.ui.proTools.mainWindow.popupButtons.whoseTitle.is('Clip List').first.popupMenuSelect({
                                                menuPath: ["Show", item], targetValue: "Enable"
                                            });
                                        }
                                        show("Audio")
                                        show("MIDI")
                                        show("Video")
                                        show("Groups")
                                        show("Auto-Created")
                                    }
                                    showItems()
                                }
                                
                                /**
                                * @param {string} trackType - All track types included on trackTypes array
                                */
                                function deleteUnusedPlaylists(trackType) {
                                    // Check if there are any tracks of trackType
                                    const trackTypeExists = sf.ui.proTools.visibleTrackHeaders.some(x => x.title.invalidate().value.includes(trackType))
                                
                                    if (trackTypeExists) {
                                
                                        // Get name of first track of trackType
                                        const firstTrackByTypeName = sf.ui.proTools.visibleTrackHeaders.filter(x => x.title.invalidate().value.includes(trackType))[0].normalizedTrackName
                                
                                        // Find track by name
                                        const getFirstTrackByTypeName = sf.ui.proTools.trackGetByName({ name: firstTrackByTypeName }).track
                                
                                        // Scrool track if needed
                                        getFirstTrackByTypeName.trackScrollToView()
                                
                                        // Delete unused menu
                                        getFirstTrackByTypeName.popupButtons.whoseTitle.is("Playlist selector").first.popupMenuSelect({ menuPath: ["Delete Unused..."] });
                                
                                        // Delete unused window
                                        const deleteUnusedWin = sf.ui.proTools.windows.whoseTitle.is("Delete Unused Playlists").first
                                
                                        if (deleteUnusedWin.exists) {
                                            const deleteUnusedWinTable = deleteUnusedWin.tables.first.children.whoseRole.is("AXRow")
                                
                                            // Select all unused playlists
                                            deleteUnusedWinTable.map(x => x.children.first.children.whoseRole.is("AXStaticText").first.elementClick())
                                
                                            // Click delete Btn
                                            deleteUnusedWin.buttons.whoseTitle.is("Delete").first.elementClick();
                                        };
                                    };
                                };
                                
                                function deletePlaylistesMain() {
                                    sf.ui.proTools.appActivateMainWindow();
                                
                                    //  show Track list, Clip list and All tracks
                                    setWindowView()
                                
                                    // Clear all items from clip list
                                
                                    //  delete unused playlists, needs to be done on all track types
                                    const trackTypes = [
                                        "Video Track",
                                        "MIDI Track",
                                        "Inst Track",
                                        "Audio Track"
                                    ]
                                
                                    trackTypes.forEach(deleteUnusedPlaylists)
                                }
                                
                                function saveAndClose() {
                                    while (true) {
                                        //// wait for complete tasks
                                        if (sf.ui.proTools.windows.whoseTitle.is('Task Manager').first.children.whoseRole.is("AXStaticText").first.invalidate().value.value == "0 items")
                                
                                            //// save and exit procedures
                                            if ((sf.ui.proTools.mainWindow.invalidate().sessionPath !== null || sf.ui.proTools.getMenuItem('File', 'Close Session').isEnabled)
                                                || sf.ui.proTools.confirmationDialog.exists) {
                                
                                                sf.ui.proTools.waitForNoModals();
                                
                                                sf.ui.proTools.menuClick({ menuPath: ["File", "Save"] });
                                
                                                sf.ui.proTools.menuClick({ menuPath: ["File", "Close Session"] });
                                
                                                if (sf.ui.proTools.confirmationDialog.invalidate().buttons.whoseTitle.is('Save').first.exists) {
                                                    sf.ui.proTools.confirmationDialog.buttons.whoseTitle.is('Save').first.elementClick();
                                                    sf.ui.proTools.confirmationDialog.elementWaitFor({ waitType: "Disappear", onError: "Continue" });
                                                }
                                                if (sf.ui.proTools.confirmationDialog.invalidate().buttons.whoseTitle.is('Cancel').first.exists) {
                                                    sf.ui.proTools.confirmationDialog.buttons.whoseTitle.is('Cancel').first.elementClick();
                                                    sf.ui.proTools.confirmationDialog.elementWaitFor({ waitType: "Disappear", onError: "Continue" });
                                                }
                                
                                                sf.ui.proTools.waitForNoModals();
                                
                                            } else {
                                                break
                                            }
                                        sf.wait({ intervalMs: 500 })
                                    }
                                }
                                
                                function waitForOpenSession(m1, m2) {
                                    while (!sf.ui.proTools.getMenuItem(m1, m2).isEnabled) {
                                        // Reset menu
                                        sf.keyboard.press({ keys: "left" });
                                
                                        sf.wait({ intervalMs: 100 });
                                    }
                                }
                                
                                function saveCloseAndOpenAgain(sessionDir) {
                                    saveAndClose()
                                
                                    sf.ui.proTools.mainWindow.elementWaitFor({ waitType: "Disappear", timeout: -1 });
                                
                                    sf.file.open({ path: sessionDir });
                                
                                    //  Wait fo menus to become enabled, thus sessioon is fully opened
                                    waitForOpenSession('File', 'Save');
                                }
                                
                                function main() {
                                    saveSessionAsNewVersion();
                                
                                    sf.ui.proTools.appActivateMainWindow();
                                
                                    openFolderTracks();
                                
                                    var popupMenu = sf.ui.proTools.trackOpenListPopupMenu().popupMenu;
                                    popupMenu.menuClickPopupMenu({
                                        menuPath: ["Show Only", "Inactive Tracks"],
                                    });
                                
                                    setGroupActive("<ALL>", true);
                                
                                    sf.ui.proTools.mainWindow.buttons.whoseTitle.is("Edit Keyboard Focus").first.mouseClickElement({
                                        relativePosition: { "x": -10, "y": 7 },
                                        anchor: "BottomLeft",
                                    });
                                
                                    setGroupActive("<ALL>", false);
                                
                                    selectInactiveTracks();
                                
                                    sf.ui.proTools.trackDelete();
                                
                                    dismissDialog("Active clips were found", "Delete");
                                
                                    dismissDialog("The track", "Delete");
                                
                                    var popupMenu = sf.ui.proTools.trackOpenListPopupMenu().popupMenu;
                                    popupMenu.menuClickPopupMenu({
                                        menuPath: ["Show All Tracks"],
                                    });
                                
                                    deletePlaylistesMain()
                                
                                    sf.ui.proTools.menuClick({
                                        menuPath: ["View", "Other Displays", "Clip List"],
                                        targetValue: "Enable",
                                    });
                                
                                    sf.ui.proTools.mainWindow.popupButtons.whoseTitle.is('Clip List').first.popupMenuSelect({
                                        menuPath: ["Select", "\"Select Unused\" Ignores Parent Clip"],
                                        targetValue: "Disable",
                                    });
                                
                                    sf.keyboard.press({
                                        keys: "cmd+shift+u",
                                    });
                                
                                    sf.ui.proTools.mainWindow.popupButtons.whoseTitle.is('Clip List').first.popupMenuSelect({
                                        menuPath: ["Clear..."],
                                    });
                                
                                    dismissDialog("REMOVE", "Remove");
                                
                                    /// Need task manager to close sessions
                                    if (!sf.ui.proTools.getMenuItem("Window", "Task Manager").isMenuChecked) {
                                        sf.ui.proTools.menuClick({ menuPath: ["Window", "Task Manager"], targetValue: "Enable" });
                                    }
                                    var sessionDir = sf.ui.proTools.mainWindow.sessionPath
                                
                                    saveCloseAndOpenAgain(sessionDir);
                                
                                    sf.ui.proTools.menuClick({
                                        menuPath: ["View", "Other Displays", "Clip List"],
                                        targetValue: "Enable",
                                    });
                                
                                    sf.keyboard.press({ keys: "cmd+shift+u", });
                                
                                    sf.ui.proTools.mainWindow.popupButtons.whoseTitle.is('Clip List').first.popupMenuSelect({
                                        menuPath: ["Clear..."],
                                    });
                                
                                    dismissDialog("REMOVE", "Remove");
                                
                                    sf.keyboard.press({ keys: "left" });
                                
                                    sf.ui.proTools.menuClick({
                                        menuPath: ["Window", "Task Manager"],
                                        targetValue: "Disable",
                                    });
                                }
                                
                                main();
                                

                                Rock on!

                                1. GGabriel Lundh @Gabriel_Lundh
                                    2022-01-12 22:04:07.579Z

                                    I know I say it alot, but You ROCK @Kitch !
                                    Such an informative and solid rearrangement that will give me a lot of assets to build better scripts in the future. Thanks also for the Dissmiss Dialogue head-up, really helpful reminder of the power of functions!

                                    I'll bump you in a few weeks - can't wait to see what you could cook up for the dialogs.
                                    All the best,
                                    Gabriel

                                    1. Kitch Membery @Kitch2022-01-12 22:07:06.956Z

                                      Back at you mate!!! :-)

                                      1. In reply toGabriel_Lundh:
                                        Kitch Membery @Kitch2022-01-12 22:12:46.236Z

                                        One other small note;

                                        In the main function the line of code;

                                        sf.ui.proTools.appActivateMainWindow
                                        

                                        should be changed to;

                                        sf.ui.proTools.appActivateMainWindow()
                                        

                                        as appActivateMainWindow() is a method not a property. Without the () it will do nothing

                                        :-)

                                        1. GGabriel Lundh @Gabriel_Lundh
                                            2022-01-12 22:19:33.076Z

                                            Hahahah, thinking back, I remember that that specific line was the first piece of code I wrote in soundflow from scratch, as an exersice - otherwise I've always copied from a macro to Java or from the forum, hahah! Learning by doing...
                                            Thanks as always, Kitch!!

                                            All the best,
                                            Gabriel

                                            1. Kitch Membery @Kitch2022-01-12 22:20:47.200Z

                                              Keep up the great work @Gabriel_Lundh!

                                              1. GGabriel Lundh @Gabriel_Lundh
                                                  2022-02-01 11:49:11.904Z

                                                  Hey master @Kitch !
                                                  Hope you've gotten some rest after the brilliant work of the new Soundflow release!
                                                  I just wanted to bump you here per our conversation above regarding the dialogs.
                                                  Do you need me to compile all potential pop-ups or do you have another way around this?

                                                  Let me know what I can do to assist you!
                                                  Thanks as always!
                                                  Best,
                                                  Gabriel

                                                  1. Kitch Membery @Kitch2022-02-01 21:49:19.790Z

                                                    Hi @Gabriel_Lundh,

                                                    Thanks for the kind words! Glad you are liking SF5. :-)

                                                    Yes if you can compile a list of the popups that would be great. Here is the information I'll need for each dialog.

                                                    Dialog screenshot:
                                                    Dialog window title:
                                                    Dialog description text:
                                                    Button you want pressed to dismiss:
                                                    Steps to make the Dialog appear:

                                                    Rock on!

                                                    1. GGabriel Lundh @Gabriel_Lundh
                                                        2022-02-06 16:57:12.677Z

                                                        Hey @Kitch !
                                                        Hope you are doing well!
                                                        I've been wanting to get to this earlier, but could not until today.
                                                        I just tried to recreate all the potential issues of dialogs and after adding one more - the script seems to works quite solid.
                                                        I have added a "Set track size" to small as this throws off the delete playlist function - and that solved a lot of problems.

                                                        So for now I think this is quite solid - I will try it in the field for a few days and see if it works in the real world!

                                                        Here is the "final" script as of now:

                                                        function saveSessionAsNewVersion() {
                                                            //First save the current version
                                                            sf.ui.proTools.getMenuItem('File', 'Save').elementClick({}, function () { }); //can be disabled
                                                        
                                                            //Get our filename without extension
                                                            var fileNameWithoutExtension = sf.ui.proTools.mainWindow.invalidate().sessionPath.split('/').slice(-1)[0].split('.').slice(0, -1).join('.');
                                                        
                                                            //Create a new name (get the name and suffixed number - if your session name was 'My Session 42' then save 'My Session ' in grps[1] and '42' in grps[2])
                                                            var grps = fileNameWithoutExtension.match(/^(.+?)(\d+)$/);
                                                        
                                                            //Construct a new name based on the prefix and the number (+1), followed by the '.ptx' suffix. If there was no number, just add ' 2'
                                                            var newNumber = !grps || grps.length === 0 || isNaN(Number(grps[2])) ? '_2' : ((Number(grps[2]) + 1) + '');
                                                            var newName = (grps ? grps[1] : (fileNameWithoutExtension)) + newNumber + '.ptx';
                                                        
                                                            //Invoke File Save As.
                                                            sf.ui.proTools.getMenuItem('File', 'Save As...').elementClick();
                                                        
                                                            //Wait for the Save dialog to appear
                                                            var dlg = sf.ui.proTools.windows.invalidate().whoseTitle.is('Save').first.elementWaitFor().element;
                                                        
                                                            //Enter the new name
                                                            dlg.textFields.first.value.value = newName;
                                                        
                                                            //Click Save
                                                            dlg.buttons.whoseTitle.is('Save').first.elementClick();
                                                        }
                                                        
                                                        function setTrackHeight(size) {
                                                        
                                                            // Get name of last track (which has to be the print track)
                                                            var lastTrackName = sf.ui.proTools.trackNames.slice(-1)[0];
                                                        
                                                            // Scroll the track into view
                                                            sf.ui.proTools.trackSelectByName({ deselectOthers: true, names: [lastTrackName] });
                                                            sf.ui.proTools.selectedTrack.trackScrollToView();
                                                            
                                                            var f = sf.ui.proTools.selectedTrack.frame;
                                                            var popupMenu = sf.ui.proTools.selectedTrack.popupMenuOpenFromElement({
                                                                relativePosition: { x: f.w - 10, y: 5 },    
                                                                isOption: true,
                                                            }).popupMenu;
                                                            popupMenu.menuClickPopupMenu({
                                                                menuPath: [size]
                                                            });
                                                        }
                                                        
                                                        function selectAllFolderTracks() {
                                                            var visibleTracks = sf.ui.proTools.trackGetVisibleTracks().names
                                                            var firstTrackFound;
                                                            let foundTracks = [];
                                                        
                                                            while (true) {
                                                                sf.ui.proTools.trackDeselectAll();
                                                                for (var i = 0; i < visibleTracks.length; i++) {
                                                                    var trackIsFolder = sf.ui.proTools.trackGetByName({ name: visibleTracks[i] }).track.children.whoseRole.is("AXDisclosureTriangle").whoseTitle.is('Open Folder')
                                                        
                                                                    if (trackIsFolder.exists)
                                                                        if (trackIsFolder) {
                                                                            if (!firstTrackFound) { // Scroll to first track found
                                                                                sf.ui.proTools.trackGetByName({ name: visibleTracks[i], }).track.trackScrollToView();
                                                                                firstTrackFound = !firstTrackFound;
                                                                            } else {
                                                                                sf.ui.proTools.trackSelectByName({ names: [visibleTracks[i]], deselectOthers: false });
                                                                            }
                                                                            foundTracks.push(visibleTracks[i]);
                                                                        }
                                                                } if (foundTracks.length !== 0) {
                                                                    break;
                                                                } else if (foundTracks.length == 0) {
                                                        
                                                                    return "exit";
                                                                }
                                                            }
                                                        }
                                                        
                                                        function openFolderTracks() {
                                                            sf.ui.proTools.appActivateMainWindow();
                                                            while (true) {
                                                                var temp;
                                                                temp = selectAllFolderTracks();
                                                                if (temp == "exit") {
                                                                    return 0;
                                                                }
                                                                const selectedTracks = sf.ui.proTools.selectedTrackNames
                                                                if (selectedTracks.length >= 1) {
                                                                    if (selectedTracks.length == 1) {
                                                                        sf.ui.proTools.selectedTrack.folderTrackSetOpen({
                                                                            targetValue: 'Enable',
                                                                            onError: 'Continue'
                                                                        });
                                                                    } if (selectedTracks.length >= 2) {
                                                                        for (var i = 0; i < selectedTracks.length; i++) {
                                                                            sf.ui.proTools.invalidate().trackGetByName({ name: selectedTracks[i] }).track.folderTrackSetOpen({
                                                                                targetValue: 'Enable',
                                                                            });
                                                                        }
                                                                    }
                                                                }
                                                            }
                                                        }
                                                        
                                                        function setGroupActive(groupName, targetValue) {
                                                            let grp = sf.ui.proTools.mainWindow.groupListView.childrenByRole('AXRow').map(r => {
                                                                let btn = r.childrenByRole('AXCell').allItems[1].buttons.first;
                                                                return {
                                                                    groupName: r.childrenByRole('AXCell').allItems[1].buttons.first.title.value.split(/-\s/)[1],
                                                                    btn,
                                                                    isActive: btn.title.invalidate().value.indexOf('Active ') === 0,
                                                                    row: r,
                                                                };
                                                            }).filter(g => g.groupName === groupName)[0];
                                                        
                                                            if (!grp) throw `Group with name "${groupName}" was not found`;
                                                        
                                                            if (grp.isActive !== !!targetValue)
                                                                grp.btn.elementClick();
                                                        }
                                                        
                                                        function isTrackActive(trackName) {
                                                            const track = sf.ui.proTools.trackGetByName({ name: trackName }).track
                                                        
                                                            const muteBtn = track.buttons.whoseTitle.is("Mute").first;
                                                        
                                                            let isInactive = muteBtn.exists ? track.buttons.whoseTitle.is("Mute").first.value.value.startsWith('inactive') : false;
                                                        
                                                            return {
                                                                trackName: trackName,
                                                                isInactive: isInactive
                                                            }
                                                        }
                                                        
                                                        function selectInactiveTracks() {
                                                            sf.ui.proTools.appActivateMainWindow();
                                                        
                                                            const selectedTrackNames = sf.ui.proTools.selectedTrackNames;
                                                            const trackActiveStates = selectedTrackNames.map(trackName => isTrackActive(trackName));
                                                            const inactiveTrackNames = trackActiveStates.filter(track => track.isInactive).map(track => track.trackName);
                                                        
                                                            sf.ui.proTools.trackSelectByName({ names: inactiveTrackNames });
                                                        }
                                                        
                                                        function dismissDialog(dialogText, buttonName) {
                                                            const dlg = sf.ui.proTools.confirmationDialog;
                                                            //Wait 100ms for dialog box to appear
                                                            dlg.elementWaitFor({
                                                                timeout: 100,
                                                                pollingInterval: 10,
                                                                onError: 'Continue'
                                                            });
                                                        
                                                            if (dlg.children.whoseRole.is("AXStaticText").whoseValue.contains(dialogText).first.exists) {
                                                                dlg.buttons.whoseTitle.is(buttonName).first.elementClick();
                                                        
                                                                dlg.elementWaitFor({
                                                                    waitType: 'Disappear',
                                                                    timeout: 100,
                                                                    pollingInterval: 10,
                                                                    onError: 'Continue'
                                                                });
                                                            }
                                                        }
                                                        
                                                        function selectAllTracks() {
                                                            const groupsList = sf.ui.proTools.mainWindow.tables.whoseTitle.is("Group List").first;
                                                            const firstRow = groupsList.childrenByRole("AXRow");
                                                            const firstCell = firstRow.first.childrenByRole("AXCell").first.buttons.first;
                                                        
                                                            firstCell.elementClick();
                                                        }
                                                        
                                                        function goToStartOfSession() {
                                                            sf.ui.proTools.transportEnsureCluster();
                                                        
                                                            const trannsportCluster = sf.ui.proTools.mainWindow.transportViewCluster;
                                                            const transportButtons = trannsportCluster.groups.whoseTitle.is("Normal Transport Buttons").first;
                                                            transportButtons.buttons.whoseTitle.is("Return to Zero").first.elementClick();
                                                        }
                                                        
                                                        function setWindowView() {
                                                            sf.ui.proTools.menuClick({ menuPath: ["View", "Other Displays", "Track List"], targetValue: "Enable" });
                                                            sf.ui.proTools.menuClick({ menuPath: ["View", "Other Displays", "Clip List"], targetValue: "Enable" });
                                                            sf.ui.proTools.mainWindow.buttons.whoseTitle.is("Track List pop-up").first.popupMenuSelect({
                                                                menuPath: ["Show All Tracks"],
                                                            });
                                                        
                                                            function showItems() {
                                                                function show(item) {
                                                                    sf.ui.proTools.mainWindow.popupButtons.whoseTitle.is('Clip List').first.popupMenuSelect({
                                                                        menuPath: ["Show", item], targetValue: "Enable"
                                                                    });
                                                                }
                                                                show("Audio")
                                                                show("MIDI")
                                                                show("Video")
                                                                show("Groups")
                                                                show("Auto-Created")
                                                            }
                                                            showItems()
                                                        }
                                                        
                                                        /**
                                                        * @param {string} trackType - All track types included on trackTypes array
                                                        */
                                                        function deleteUnusedPlaylists(trackType) {
                                                            // Check if there are any tracks of trackType
                                                            const trackTypeExists = sf.ui.proTools.visibleTrackHeaders.some(x => x.title.invalidate().value.includes(trackType))
                                                        
                                                            if (trackTypeExists) {
                                                        
                                                                // Get name of first track of trackType
                                                                const firstTrackByTypeName = sf.ui.proTools.visibleTrackHeaders.filter(x => x.title.invalidate().value.includes(trackType))[0].normalizedTrackName
                                                        
                                                                // Find track by name
                                                                const getFirstTrackByTypeName = sf.ui.proTools.trackGetByName({ name: firstTrackByTypeName }).track
                                                        
                                                                // Scrool track if needed
                                                                getFirstTrackByTypeName.trackScrollToView()
                                                        
                                                                // Delete unused menu
                                                                getFirstTrackByTypeName.popupButtons.whoseTitle.is("Playlist selector").first.popupMenuSelect({ menuPath: ["Delete Unused..."] });
                                                        
                                                                // Delete unused window
                                                                const deleteUnusedWin = sf.ui.proTools.windows.whoseTitle.is("Delete Unused Playlists").first
                                                        
                                                                if (deleteUnusedWin.exists) {
                                                                    const deleteUnusedWinTable = deleteUnusedWin.tables.first.children.whoseRole.is("AXRow")
                                                        
                                                                    // Select all unused playlists
                                                                    deleteUnusedWinTable.map(x => x.children.first.children.whoseRole.is("AXStaticText").first.elementClick())
                                                        
                                                                    // Click delete Btn
                                                                    deleteUnusedWin.buttons.whoseTitle.is("Delete").first.elementClick();
                                                                };
                                                            };
                                                        };
                                                        
                                                        function deletePlaylistesMain() {
                                                            sf.ui.proTools.appActivateMainWindow();
                                                        
                                                            //  show Track list, Clip list and All tracks
                                                            setWindowView()
                                                        
                                                            // Clear all items from clip list
                                                        
                                                            //  delete unused playlists, needs to be done on all track types
                                                            const trackTypes = [
                                                                "Video Track",
                                                                "MIDI Track",
                                                                "Inst Track",
                                                                "Audio Track"
                                                            ]
                                                        
                                                            trackTypes.forEach(deleteUnusedPlaylists)
                                                        }
                                                        
                                                        function saveAndClose() {
                                                            while (true) {
                                                                //// wait for complete tasks
                                                                if (sf.ui.proTools.windows.whoseTitle.is('Task Manager').first.children.whoseRole.is("AXStaticText").first.invalidate().value.value == "0 items")
                                                        
                                                                    //// save and exit procedures
                                                                    if ((sf.ui.proTools.mainWindow.invalidate().sessionPath !== null || sf.ui.proTools.getMenuItem('File', 'Close Session').isEnabled)
                                                                        || sf.ui.proTools.confirmationDialog.exists) {
                                                        
                                                                        sf.ui.proTools.waitForNoModals();
                                                        
                                                                        sf.ui.proTools.menuClick({ menuPath: ["File", "Save"] });
                                                        
                                                                        sf.ui.proTools.menuClick({ menuPath: ["File", "Close Session"] });
                                                        
                                                                        if (sf.ui.proTools.confirmationDialog.invalidate().buttons.whoseTitle.is('Save').first.exists) {
                                                                            sf.ui.proTools.confirmationDialog.buttons.whoseTitle.is('Save').first.elementClick();
                                                                            sf.ui.proTools.confirmationDialog.elementWaitFor({ waitType: "Disappear", onError: "Continue" });
                                                                        }
                                                                        if (sf.ui.proTools.confirmationDialog.invalidate().buttons.whoseTitle.is('Cancel').first.exists) {
                                                                            sf.ui.proTools.confirmationDialog.buttons.whoseTitle.is('Cancel').first.elementClick();
                                                                            sf.ui.proTools.confirmationDialog.elementWaitFor({ waitType: "Disappear", onError: "Continue" });
                                                                        }
                                                        
                                                                        sf.ui.proTools.waitForNoModals();
                                                        
                                                                    } else {
                                                                        break
                                                                    }
                                                                sf.wait({ intervalMs: 500 })
                                                            }
                                                        }
                                                        
                                                        function waitForOpenSession(m1, m2) {
                                                            while (!sf.ui.proTools.getMenuItem(m1, m2).isEnabled) {
                                                                // Reset menu
                                                                sf.keyboard.press({ keys: "left" });
                                                        
                                                                sf.wait({ intervalMs: 100 });
                                                            }
                                                        }
                                                        
                                                        function saveCloseAndOpenAgain(sessionDir) {
                                                            saveAndClose()
                                                        
                                                            sf.ui.proTools.mainWindow.elementWaitFor({ waitType: "Disappear", timeout: -1 });
                                                        
                                                            sf.file.open({ path: sessionDir });
                                                        
                                                            //  Wait fo menus to become enabled, thus sessioon is fully opened
                                                            waitForOpenSession('File', 'Save');
                                                        }
                                                        
                                                        function main() {
                                                            saveSessionAsNewVersion();
                                                        
                                                            sf.ui.proTools.appActivateMainWindow();
                                                        
                                                            setTrackHeight("small")
                                                        
                                                            openFolderTracks();
                                                        
                                                            var popupMenu = sf.ui.proTools.trackOpenListPopupMenu().popupMenu;
                                                            popupMenu.menuClickPopupMenu({
                                                                menuPath: ["Show Only", "Inactive Tracks"],
                                                            });
                                                        
                                                            setTrackHeight("small")
                                                        
                                                            setGroupActive("<ALL>", true);
                                                        
                                                            sf.ui.proTools.mainWindow.buttons.whoseTitle.is("Edit Keyboard Focus").first.mouseClickElement({
                                                                relativePosition: { "x": -10, "y": 7 },
                                                                anchor: "BottomLeft",
                                                            });
                                                        
                                                            setGroupActive("<ALL>", false);
                                                            
                                                        
                                                            selectInactiveTracks();
                                                        
                                                            sf.ui.proTools.trackDelete();
                                                        
                                                            dismissDialog("A folder and all", "Delete");
                                                        
                                                            dismissDialog("Active clips were found", "Delete");
                                                        
                                                            dismissDialog("The track", "Delete");
                                                        
                                                            var popupMenu = sf.ui.proTools.trackOpenListPopupMenu().popupMenu;
                                                            popupMenu.menuClickPopupMenu({
                                                                menuPath: ["Show All Tracks"],
                                                            });
                                                        
                                                            deletePlaylistesMain()
                                                        
                                                            sf.ui.proTools.menuClick({
                                                                menuPath: ["View", "Other Displays", "Clip List"],
                                                                targetValue: "Enable",
                                                            });
                                                        
                                                            sf.ui.proTools.mainWindow.popupButtons.whoseTitle.is('Clip List').first.popupMenuSelect({
                                                                menuPath: ["Select", "\"Select Unused\" Ignores Parent Clip"],
                                                                targetValue: "Disable",
                                                            });
                                                        
                                                            sf.keyboard.press({
                                                                keys: "cmd+shift+u",
                                                            });
                                                        
                                                            sf.ui.proTools.mainWindow.popupButtons.whoseTitle.is('Clip List').first.popupMenuSelect({
                                                                menuPath: ["Clear..."],
                                                            });
                                                        
                                                            dismissDialog("REMOVE", "Remove");
                                                        
                                                            /// Need task manager to close sessions
                                                            if (!sf.ui.proTools.getMenuItem("Window", "Task Manager").isMenuChecked) {
                                                                sf.ui.proTools.menuClick({ menuPath: ["Window", "Task Manager"], targetValue: "Enable" });
                                                            }
                                                            var sessionDir = sf.ui.proTools.mainWindow.sessionPath
                                                        
                                                            saveCloseAndOpenAgain(sessionDir);
                                                        
                                                            sf.ui.proTools.menuClick({
                                                                menuPath: ["View", "Other Displays", "Clip List"],
                                                                targetValue: "Enable",
                                                            });
                                                        
                                                            sf.keyboard.press({ keys: "cmd+shift+u", });
                                                        
                                                            sf.ui.proTools.mainWindow.popupButtons.whoseTitle.is('Clip List').first.popupMenuSelect({
                                                                menuPath: ["Clear..."],
                                                            });
                                                        
                                                            dismissDialog("REMOVE", "Remove");
                                                        
                                                            sf.keyboard.press({ keys: "left" });
                                                        
                                                            sf.ui.proTools.menuClick({
                                                                menuPath: ["Window", "Task Manager"],
                                                                targetValue: "Disable",
                                                            });
                                                            sf.keyboard.press({ keys: "enter", });
                                                        }
                                                        
                                                        main();
                                                        
                                                        

                                                        Thanks as always for your help!
                                                        All the best,
                                                        Gabriel

                                                        1. @Gabriel_Lundh Just wanted to report back that this new script seems to work pretty seamless so far. Thank you!!

                                                          1. GGabriel Lundh @Gabriel_Lundh
                                                              2022-02-19 11:23:16.040Z

                                                              @Brett_Ryan_Stewart Hi man! Thank you for reporting back! I've found some additional bugs that I will look into - for example if the first inactive track is an Instrument track, the script fails to remove the inactive tracks... I'll let you know once it's updated!

                                                              Have a great weekend!

                                                            • In reply toGabriel_Lundh:
                                                              PPhilip weinrobe @Philip_weinrobe
                                                                2024-01-24 17:30:42.977Z

                                                                Hi!
                                                                I've been trying to implement this script into a larger "session flattening" process I am working on.
                                                                I am kinda clumsy with the code though!

                                                                Can you (or someone!) help me figure out a way to remove the following parts of this script:

                                                                1. The beginning save-as function. (I have my own save-as function I am going to use instead)
                                                                2. The ending "close session" process. (I have additional steps I want to take!)

                                                                Thank you!
                                                                Philip

                                                                1. SSreejesh Nair @Sreejesh_Nair
                                                                    2024-01-25 15:21:45.317Z

                                                                    Maybe you could try commenting out line 310 and 378 with // to check?

                                        2. S
                                          In reply toGabriel_Lundh:
                                          Sean McDonald @Sean_McDonald5
                                            2024-07-25 20:15:05.953Z

                                            Hi guys!
                                            Did a search for the script, and luckily you talented people are working on it.

                                            But after installing the latest version, I am getting this error.
                                            Perhaps it’s something I screwed up when copying and pasting?
                                            I tried twice, and I’m getting the same results each time.

                                            1. S
                                              In reply toGabriel_Lundh:
                                              Sean McDonald @Sean_McDonald5
                                                2024-08-28 04:21:45.271Z

                                                Hello All,
                                                Just bumping my experiences with this script, any idea what I might be doing wrong?
                                                thanks in advance!

                                                1. GGabriel Lundh @Gabriel_Lundh
                                                    2024-08-28 14:55:03.032Z

                                                    Hi @Sean_McDonald5 !
                                                    Sorry for not getting back to you here!
                                                    The first thing that throws the script now is the new "Save Session As" instead of "Save As" in the new Pro Tools, - so you can change that on Line 17.
                                                    Then I seem to get additional errors after this in the new Pro Tools which were not quick to fix...
                                                    Unfortunately, I'm not using this script any more as I more often Select the tracks I want to keep, then I do a Save Copy in with "Selected Tracks Only"...

                                                    But I might have time to look this over later this week, I'll keep you updated in that case!

                                                    Thanks and have a great day!

                                                    1. SSean McDonald @Sean_McDonald5
                                                        2024-08-28 16:35:59.361Z

                                                        Thanks!👍👍🙏🙏