Why doesn't this work?

I’m posting this script here because it’s kind of nifty, and there’s one part that’s not working and I can’t figure out why.

In short the script uses the “path to” Scripting Addition to figure out all the paths to special folders that can be opened at runtime, then provides the user a list (in Myriad Tables) of the good paths. The user can mark any of the paths as favorites, and can also select any of the paths. The ones selected will open in the finder. The ones marked favorites are the only ones that will be shown the next time the script is run. But the user will also have the option of generating a new list.

The part that doesn’t work is that when the user has picked favorites, but decides to generate the full list, the script forgets the favorites.

Here is where the script fails. FavoriteFolders is a property containing the user’s previous favorites.

If a path is in the FavoriteFolders list its first item will be true and it will display with a checkmark.

Instead, none of the items keep the checkmark.

   if thisFolderInfo is in favoriteFolders then
               set the end of workedPathsList to thisFolderInfo
            else
               set item 1 of thisFolderInfo to false
               set the end of workedPathsList to thisFolderInfo
            end if

Here’s the entire script:

use AppleScript version "2.4"
use scripting additions
use script "Myriad Tables Lib"
property favoriteFolders : {}

if favoriteFolders is {} then
   set selectedFolders to my SelectAllFolders()
else
   set selectedFolders to my SelectFromFavoriteFolders()
end if
tell application "Finder"
   
   repeat with thisFolder in selectedFolders
      set folderAlias to item 4 of thisFolder as alias
      open folderAlias
   end repeat
   activate
end tell

on SelectFromFavoriteFolders()
   set tableData to favoriteFolders
   
   -- set table parameters
   set tableTitle to "Open Folders"
   set tablePrompt to "Select the folder(s) you would like to open"
   set multipleSections to true
   set addOrDelete to false
   set editableColumns to {1}
   set columnHeadings to {"Favorite", "Domain", "Decription", "Path"}
   set rowNumbering to false
   set initiallySelectedRows to {}
   set emptySelectionAllowed to true
   set rowTemplate to item 1 of tableData
   set givingUpAfter to 600
   
   --display table with data
   set tableData to make new table with data tableData ¬
      with title tableTitle ¬
      with prompt tablePrompt ¬
      multiple selections allowed multipleSections ¬
      can add and delete addOrDelete ¬
      editable columns editableColumns ¬
      column headings columnHeadings ¬
      row numbering rowNumbering ¬
      initially selected rows initiallySelectedRows ¬
      empty selection allowed emptySelectionAllowed ¬
      row template rowTemplate
   
   modify table tableData ¬
      OK button name ¬
      "OK" OK button is default true ¬
      cancel button name ¬
      "Cancel" extra button name ¬
      "Select From Full List"
   
   set tableResult to display table tableData ¬
      giving up after givingUpAfter ¬
      with extended results
   set userButton to button number of tableResult
   set selectedFolders to values selected of tableResult
   set allFolders to values returned of tableResult
   if userButton is 2 then
      return SelectAllFolders()
   end if
   set favoriteFolders to {}
   repeat with thisFolder in allFolders
      if item 1 of thisFolder is true then
         set the end of favoriteFolders to thisFolder as item
      end if
   end repeat
   return selectedFolders
end SelectFromFavoriteFolders

on SelectAllFolders()
   set allFolders to {apple menu, application support, applications folder, control panels, control strip modules, desktop, desktop pictures folder, documents folder, downloads folder, extensions, favorites folder, Folder Action scripts, fonts, help, home folder, internet plugins, keychain folder, launcher items folder, library folder, modem scripts, movies folder, music folder, pictures folder, preferences, printer descriptions, printer drivers, printmonitor, public folder, scripting additions folder, scripts folder, services folder, shared documents, shared libraries, shutdown folder, sites folder, speakable items, startup disk, startup items, stationery, system folder, system preferences, temporary items, trash, users folder, utilities folder, voices, workflows folder}
   set allDomains to {user domain, system domain, local domain, network domain, Classic domain}
   set allFoldersText to {"apple menu", "application support", "applications folder", "control panels", "control strip modules", "desktop", "desktop pictures folder", "documents folder", "downloads folder", "extensions", "favorites folder", "Folder Action scripts", "fonts", "help", "home folder", "internet plugins", "keychain folder", "launcher items folder", "library folder", "modem scripts", "movies folder", "music folder", "pictures folder", "preferences", "printer descriptions", "printer drivers", "printmonitor", "public folder", "scripting additions folder", "scripts folder", "services folder", "shared documents", "shared libraries", "shutdown folder", "sites folder", "speakable items", "startup disk", "startup items", "stationery", "system folder", "system preferences", "temporary items", "trash", "users folder", "utilities folder", "voices", "workflows folder"}
   set allDomainsText to {"user domain", "system domain", "local domain", "network domain", "Classic domain"}
   set workedPaths to {"Paths that worked"}
   set failedPaths to {"", "Paths that failed"}
   set workedPathsList to {}
   set AppleScript's text item delimiters to {tab}
   repeat with y from 1 to the count of allDomains
      set thisDomain to item y of allDomains
      
      repeat with x from 1 to count of allFolders
         repeat 1 times
            set thisFolder to item x of allFolders
            set thisFolderString to item x of allFoldersText
            set thisDomainString to item y of allDomainsText
            try
               set thisPath to path to thisFolder from thisDomain as alias
            on error errMsg number errNum
               set the end of failedPaths to {thisDomainString, thisFolderString, errMsg} as text
               exit repeat
            end try
            set thisFolderInfo to {true, thisDomainString, thisFolderString, thisPath as text}
            
            
            if thisFolderInfo is in favoriteFolders then
               set the end of workedPathsList to thisFolderInfo
            else
               set item 1 of thisFolderInfo to false
               set the end of workedPathsList to thisFolderInfo
            end if
         end repeat
      end repeat
   end repeat
   
   set AppleScript's text item delimiters to {return}
   {workedPaths, failedPaths} as text
   
   -- set table data 
   set tableData to workedPathsList
   
   -- set table parameters
   set tableTitle to "Open Folders"
   set tablePrompt to "Select the folder(s) you would like to open"
   set multipleSections to true
   set addOrDelete to false
   set editableColumns to {1}
   set columnHeadings to {"Favorite", "Domain", "Decription", "Path"}
   set rowNumbering to false
   set initiallySelectedRows to {}
   set emptySelectionAllowed to true
   set rowTemplate to item 1 of tableData
   set givingUpAfter to 600
   
   --display table with data
   set tableResult to display table with data tableData ¬
      with title tableTitle ¬
      with prompt tablePrompt ¬
      multiple selections allowed multipleSections ¬
      can add and delete addOrDelete ¬
      editable columns editableColumns ¬
      column headings columnHeadings ¬
      row numbering rowNumbering ¬
      initially selected rows initiallySelectedRows ¬
      empty selection allowed emptySelectionAllowed ¬
      row template rowTemplate ¬
      giving up after givingUpAfter
   
   set selectedFolders to values selected of tableResult
   set allFolders to values returned of tableResult
   set favoriteFolders to {}
   repeat with thisFolder in allFolders
      if item 1 of thisFolder is true then
         set the end of favoriteFolders to thisFolder as item
      end if
   end repeat
   return selectedFolders
end SelectAllFolders

I plan to add to this the paths to the various script library folders; paths to the various application scripts folders; paths to scripts folders for applications in the Scripts menu.

Any suggestions welcome

 set the listOfLists to {{true, "text", 1}, {"false", "string", "2"}}

{true, "text", 1} is in the listOfLists --false
{"false", "string", "2"} is in the listOfLists --false

I could have sworn this worked, but I guess not.

Try this:

set the listOfLists to {{true, "text", 1}, {"false", "string", "2"}}

{{true, "text", 1}} is in the listOfLists --true
{{"false", "string", "2"}} is in the listOfLists --true

Two suggestions:

  • Get rid of Classic domain. It’s well past its use-by date. Things like printmonitor, printer descriptions, stationery and modem scripts could probably go too.

  • Each item always returns something for the user domain. You could shorten the list by ignoring all other domains where the path returned is the same as that for the user domain.

Those are good suggestions. Part of what I was doing was seeing everything Path To could generate. Next I’ll figure out how to cull the results. (I was surprised classic domain was even in there.)

Here’s another version that has a few more folders added and a bunch removed. (Classic domain; unused folders; duplicates) .I’m probably going to rewrite the main handlers to make it a bit smoother and easier to follow and easier to add other folders (Application’s script folders, for example. (I’ll also remove the ThisIsInThatList hander)

I haven’t tested it on a system that doesn’t have SD installed. I’ll do that tonight to make sure that part works.

use AppleScript version "2.4"
use scripting additions
use script "Myriad Tables Lib"
property favoriteFolders : {}
property failedPathsText : ""
property failedPaths : {}

if favoriteFolders is {} then
   set selectedFolders to my SelectAllFolders()
else
   set selectedFolders to my SelectFromFavoriteFolders()
end if
tell application "Finder"
   
   repeat with thisFolder in selectedFolders
      set folderAlias to item 4 of thisFolder as alias
      open folderAlias
      set the current view of window 1 to list view
   end repeat
   if selectedFolders is not {} then activate
end tell

on SelectAllFolders()
   --set allFolders to {apple menu, application support, applications folder, control panels, control strip modules, desktop, desktop pictures folder, documents folder, downloads folder, extensions, favorites folder, Folder Action scripts, fonts, help, home folder, internet plugins, keychain folder, launcher items folder, library folder, modem scripts, movies folder, music folder, pictures folder, preferences, printer descriptions, printer drivers, printmonitor, public folder, scripting additions folder, scripts folder, services folder, shared documents, shared libraries, shutdown folder, sites folder, speakable items, startup disk, startup items, stationery, system folder, system preferences, temporary items, trash, users folder, utilities folder, voices, workflows folder}
   --set allFoldersText to {"apple menu", "application support", "applications folder", "control panels", "control strip modules", "desktop", "desktop pictures folder", "documents folder", "downloads folder", "extensions", "favorites folder", "Folder Action scripts", "fonts", "help", "home folder", "internet plugins", "keychain folder", "launcher items folder", "library folder", "modem scripts", "movies folder", "music folder", "pictures folder", "preferences", "printer descriptions", "printer drivers", "printmonitor", "public folder", "scripting additions folder", "scripts folder", "services folder", "shared documents", "shared libraries", "shutdown folder", "sites folder", "speakable items", "startup disk", "startup items", "stationery", "system folder", "system preferences", "temporary items", "trash", "users folder", "utilities folder", "voices", "workflows folder"}
   --set allDomains to {user domain, system domain, local domain, network domain, Classic domain}
   --set allDomainsText to {"user domain", "system domain", "local domain", "network domain", "Classic domain"}
   --printmonitor, printer descriptions, stationery and modem scripts could probably go too.
   
   set allFolders to {application support, applications folder, desktop, desktop pictures folder, documents folder, downloads folder, favorites folder, Folder Action scripts, fonts, help, home folder, internet plugins, keychain folder, library folder, movies folder, music folder, pictures folder, preferences, public folder, scripting additions folder, scripts folder, services folder, shared documents, shared libraries, sites folder, speakable items, startup disk, startup items, system folder, system preferences, temporary items, trash, users folder, utilities folder, voices, workflows folder}
   set allFoldersText to {"application support", "applications folder", "desktop", "desktop pictures folder", "documents folder", "downloads folder", "favorites folder", "Folder Action scripts", "fonts", "help", "home folder", "internet plugins", "keychain folder", "library folder", "movies folder", "music folder", "pictures folder", "preferences", "public folder", "scripting additions folder", "scripts folder", "services folder", "shared documents", "shared libraries", "sites folder", "speakable items", "startup disk", "startup items", "system folder", "system preferences", "temporary items", "trash", "users folder", "utilities folder", "voices", "workflows folder"}
   
   set allDomains to {user domain, system domain, local domain, network domain}
   set allDomainsText to {"user domain", "system domain", "local domain", "network domain"}
   
   set workedPaths to {"Paths that worked"}
   set failedPaths to {"", "Paths that failed"}
   set workedPathsList to {}
   set justPaths to {}
   local workedPathsList
   set workedPathsList to my GetSDScriptFolders()
   
   set AppleScript's text item delimiters to {tab}
   repeat with y from 1 to the count of allDomains
      local thisFolderInfo
      set thisDomain to item y of allDomains
      
      repeat with x from 1 to count of allFolders
         repeat 1 times
            set thisFolder to item x of allFolders
            set thisFolderString to item x of allFoldersText
            set thisDomainString to item y of allDomainsText
            set thisPath to my GetPaths(thisFolder, thisFolderString, thisDomain, thisDomainString)
            if thisPath is "" then exit repeat
            if thisPath is not in justPaths then
               set the end of justPaths to thisPath
               set the end of workedPaths to {thisDomainString, thisFolderString, thisPath as text} as text
               set thisFolderInfo to {true, thisDomainString, thisFolderString, thisPath as text}
               
               if ThisIsInThatList(thisFolderInfo, favoriteFolders) then
                  set the end of workedPathsList to thisFolderInfo
               else
                  set item 1 of thisFolderInfo to false
                  set the end of workedPathsList to thisFolderInfo
               end if
            end if
            
            if thisFolder is library folder then
               try
                  set thisPath to ((thisPath as text) & "Script Libraries:") as alias
               on error errMsg number errNum
                  exit repeat
               end try
               set thisFolderString to thisFolderString & "'s Script Libraries"
               if thisPath is not in justPaths then
                  set the end of justPaths to thisPath
                  
                  set the end of workedPaths to {thisDomainString, thisFolderString, thisPath as text} as text
                  set thisFolderInfo to {true, thisDomainString, thisFolderString, thisPath as text}
                  
                  if ThisIsInThatList(thisFolderInfo, favoriteFolders) then
                     set the end of workedPathsList to thisFolderInfo
                  else
                     set item 1 of thisFolderInfo to false
                     set the end of workedPathsList to thisFolderInfo
                  end if
               end if
            else if thisFolder is scripts folder then
               try
                  set thisPath to ((thisPath as text) & "applications:") as alias
               on error errMsg number errNum
                  exit repeat
               end try
               set thisFolderString to thisFolderString & "'s Applications
 Folder"
               set folderStringRoot to thisFolderString & "'s Applications
 --"
               set AppleScript's text item delimiters to {tab}
               if thisPath is not in justPaths then
                  set the end of justPaths to thisPath
                  set the end of workedPaths to {thisDomainString, thisFolderString, thisPath as text} as text
                  set thisFolderInfo to {true, thisDomainString, thisFolderString, thisPath as text}
                  
                  if ThisIsInThatList(thisFolderInfo, favoriteFolders) then
                     set the end of workedPathsList to thisFolderInfo
                  else
                     set item 1 of thisFolderInfo to false
                     set the end of workedPathsList to thisFolderInfo
                  end if
               end if
               tell application "Finder"
                  set applicationScriptFolders to every folder of thisPath as alias list
                  repeat with thisAppScriptFolder in applicationScriptFolders
                     set folderName to the name of thisAppScriptFolder
                     set thisFolderString to folderStringRoot & folderName
                     set scriptFolderPath to thisAppScriptFolder as alias
                     if scriptFolderPath is not in justPaths then
                        set the end of justPaths to scriptFolderPath
                        set the end of workedPaths to {thisDomainString, thisFolderString, scriptFolderPath as text} as text
                        set thisFolderInfo to {true, thisDomainString, thisFolderString, scriptFolderPath as text}
                        
                        if my ThisIsInThatList(thisFolderInfo, favoriteFolders) then
                           set the end of workedPathsList to thisFolderInfo
                        else
                           set item 1 of thisFolderInfo to false
                           set the end of workedPathsList to thisFolderInfo
                        end if
                     end if
                     
                  end repeat
                  
               end tell
            end if
         end repeat
      end repeat
   end repeat
   
   set AppleScript's text item delimiters to {return}
   set failedPathsText to {workedPaths, failedPaths} as text
   
   -- set table data 
   set tableData to workedPathsList
   
   -- set table parameters
   set tableTitle to "Complete list of folders"
   set tablePrompt to "Select the folder(s) you would like to open" & return & return & "Checked items will be saved for the Favorites Window"
   set multipleSections to true
   set addOrDelete to false
   set editableColumns to {1}
   set columnHeadings to {"Favorite", "Domain", "Description", "Path"}
   set rowNumbering to false
   set initiallySelectedRows to {}
   set emptySelectionAllowed to true
   set rowTemplate to item 1 of tableData
   set givingUpAfter to 600
   
   --display table with data
   set tableResult to display table with data tableData ¬
      with title tableTitle ¬
      with prompt tablePrompt ¬
      multiple selections allowed multipleSections ¬
      can add and delete addOrDelete ¬
      editable columns editableColumns ¬
      column headings columnHeadings ¬
      row numbering rowNumbering ¬
      initially selected rows initiallySelectedRows ¬
      empty selection allowed emptySelectionAllowed ¬
      row template rowTemplate ¬
      giving up after givingUpAfter
   
   set selectedFolders to values selected of tableResult
   set allFolders to values returned of tableResult
   set favoriteFolders to {}
   repeat with thisFolder in allFolders
      if item 1 of thisFolder is true then
         set the end of favoriteFolders to thisFolder as item
      end if
   end repeat
   return selectedFolders
end SelectAllFolders

on SelectFromFavoriteFolders()
   set tableData to favoriteFolders
   -- set table parameters
   set tableTitle to "Favorites Window"
   set tablePrompt to "Select the folder(s) you would like to open" & return & return & "Checked items will be saved for the Favorites Window"
   
   set multipleSections to true
   set addOrDelete to false
   set editableColumns to {1}
   set columnHeadings to {"Favorite", "Domain", "Decription", "Path"}
   set rowNumbering to false
   set initiallySelectedRows to {}
   set emptySelectionAllowed to true
   set rowTemplate to item 1 of tableData
   set givingUpAfter to 600
   
   --display table with data
   set tableData to make new table with data tableData ¬
      with title tableTitle ¬
      with prompt tablePrompt ¬
      multiple selections allowed multipleSections ¬
      can add and delete addOrDelete ¬
      editable columns editableColumns ¬
      column headings columnHeadings ¬
      row numbering rowNumbering ¬
      initially selected rows initiallySelectedRows ¬
      empty selection allowed emptySelectionAllowed ¬
      row template rowTemplate
   
   modify table tableData ¬
      OK button name ¬
      "OK" OK button is default true ¬
      cancel button name ¬
      "Cancel" extra button name ¬
      "Select From Full List"
   
   set tableResult to display table tableData ¬
      giving up after givingUpAfter ¬
      with extended results
   set userButton to button number of tableResult
   set selectedFolders to values selected of tableResult
   set allFolders to values returned of tableResult
   if userButton is 2 then
      return SelectAllFolders()
   end if
   set favoriteFolders to {}
   repeat with thisFolder in allFolders
      if item 1 of thisFolder is true then
         set the end of favoriteFolders to thisFolder as item
      end if
   end repeat
   return selectedFolders
end SelectFromFavoriteFolders

on GetPaths(thisFolder, thisFolderString, thisDomain, thisDomainString)
   try
      set thisPath to path to thisFolder from thisDomain as alias
   on error errMsg number errNum
      set the end of failedPaths to {thisDomainString, thisFolderString, errMsg} as text
      return ""
   end try
end GetPaths

on ThisIsInThatList(this, thatList)
   if the class of thatList is not list then return false
   if thatList = {} then return false
   if this = {} or this = "" then return false
   repeat with x from 1 to count of thatList
      if this = item x of thatList then return true
   end repeat
   return false
end ThisIsInThatList

on GetSDScriptFolders()
   set SDsFolders to {}
   using terms from application "Script Debugger"
      try
         application "Script Debugger"
      on error
         return {}
      end try
      tell application "Script Debugger"
         set SDScriptsFolder to scripts menu folder as alias
         set the end of SDsFolders to {true, "User Domain", "Script Debugger Scripts", SDScriptsFolder as text}
         set SDClippingsFolder to clippings menu folder as alias
         set the end of SDsFolders to {true, "User Domain", "Script Debugger Clippings Folder", SDClippingsFolder as text}
         set SDTemplatesFolder to templates folder as alias
         set the end of SDsFolders to {true, "User Domain", "Script Debugger Templates", SDTemplatesFolder as text}
      end tell
   end using terms from
   return SDsFolders
end GetSDScriptFolders