28
Since Playlist Organizer 2.6 (foo_plorg) was broken when updating to foobar2000 v2 I've tried other playlist managers such as SMP Playlist and this Playlist Organizer (aka foo_plorg) replacement.
But, with the amount of playlists I have, I found the replacement foo_plorg slow to load with foobar and in the case of SMP which isn't that slow it doesn't have treeview and with the amount of playlist I have, it's impossible to use efficiently so I see no benefit in it any more and there's too many bugs with it and just overly complex to make it usable.
I just find the built in Playlist Swither much faster overall and it has most of what I need. It really is only missing the count for the files in each playlist for me. I can live without a tree view as long as it's quicker than anything else.
So, for now, I'm going to use the standard Playlist Switcher until the original foo_plorg is updated.
The only downside for me is that there's no easy way to sort the playlists, so I've written a small .ps1 file to sort the contents of the index.txt.
Here's the code with explanations on how to install it and to a toolbar in columns UI.
<#
_Sort Playlist.ps1
.SYNOPSIS
This program sorts the 'index.txt'
.NOTES RELEASES AND UPDATES
First Release - 2024.05.26 by stevehero
.DESCRIPTION
This program sorts the 'index.txt' file located here on my machine at least:
W:\Apps (Portable)\Music Apps\foobar2000\profile\playlists-v2.0
Tested using a portable installation, so this should work with regular
installs.
.CAVEATS
You need to restart foobar2000 to see the updated order.
.NOTES INSTALLING
Copy this code and save it to a "_Sort Playlist.ps1" file and place it in the
playlist folder.
The playlist folder can be located by searching for the index.txt file where
foobar2000 is installed.
There should be a bunch of files like these below:
playlist-00B9060C-EC93-4499-BCDC-6C688C392125-props.sqlite
playlist-00B9060C-EC93-4499-BCDC-6C688C392125.fplite
playlist-00C7A713-B487-48DC-9EE0-93E72FCBF94D-props.sqlite
playlist-00C7A713-B487-48DC-9EE0-93E72FCBF94D.fplite
.EXAMPLE ADDING TO A TOOLBAR IN FOOBAR USING COLUMNS UI
Note: I don't know if this is possible with the vanilla install.
1. Install run services component:
https://www.foobar2000.org/components/view/foo_run
2. With foobar2000 open, go to:
File>Preferences>Tools>Run Services
3. Click A̲dd
4. Label:
Sort Playlists '('The index.txt File')'
5. Path: Paste this (Replace the location of the .ps1 file to yours) Ensure
that the path is wrapped in quotes and any ( or ) are wrapped with
semi-colons like '(' and ')'.
cmd /c start /min "" powershell -WindowStyle Hidden -ExecutionPolicy Bypass -File "W:\Apps '('Portable')'\Music Apps\foobar2000\profile\playlists-v2.0\_Sort Playlists.ps1"
6. Using columns UI for this step.
7. Right-click on the toolbar area and click Button Options.
8. Click Add>Click Context menu items
9. Select "Active Selection" for the item group. I've tried "None" here but it
needs something to be selected to run this program.
10. Under command scroll down to you see
Run service/Sort Playlists '('The index.txt File')'
11. From here it's fairly self-explanatory to set an icon or custom text for
the toolbar. I used display mode: Text and checked the custom text
checkbox and for that is used "Sort Playlists".
12. You can order the button by dragging it to your desired location on the
toolbar.
13. Click "OK".
14. Then click that on the toolbar. The index.txt file will be sorted but not
show correctly until foobar2000 is restarted.
.NOTES DISCLAIMER
Use at your own risk and pretty please, DO NOT MODIFY.
#>
#####
##### FUNCTIONS CODE BELOW
##### FUNCTIONS CODE BELOW
##### FUNCTIONS CODE BELOW
#####
Function Show-MessageBox_UI_Independant {
<#
.SYNOPSIS
Show a messagebox modal message box even when it's not used with an UI.
.DESCRIPTION
Shows a messagebox that can be modal which the standard one doesn't and can be
used independently of a UI such as a stand-alone script.
Add-Type -AssemblyName PresentationFramework
$msgBoxInput = [System.Windows.MessageBox]::Show("Message", 'Title','OK')
.NOTES
Author: stevehero
Date Created: 2024.05.26
Tested with PowerShell 5.1 and 7.1.
Posted the other example here: https://stackoverflow.com/questions/51066978/convert-to-json-with-comments-from-powershell
.BUGS: NA
.TODO: NA
.PARAMETER Modal
Switch to show messagebox as Modal, which means it stays on top of all other
applications until the user clicks a button.
.PARAMETER Title
The title of the messagebox that appears in the title bar of the dialog.
.PARAMETER Message
The main message of the messagebox.
.PARAMETER Buttons
The Buttons to show, please see below.
Member Value Description
OKOnly 0 Displays OK button only.
OKCancel 1 Displays OK and Cancel buttons.
AbortRetryIgnore 2 Displays Abort, Retry, and Ignore buttons.
YesNoCancel Displays Yes, No, and Cancel buttons.
YesNo Displays Yes and No buttons.
RetryCancel Displays Retry and Cancel buttons.
Critical 16 Displays Critical Message icon.
Question 32 Displays Warning Query icon.
Exclamation Displays Warning Message icon.
Information Displays Information Message icon.
DefaultButton1 0 First button is default.
DefaultButton2 256 Second button is default.
DefaultButton3 512 Third button is default.
ApplicationModal 0 Application is modal. The user must respond to the message box before continuing work in the current application.
SystemModal System is modal. All applications are suspended until the user responds to the message box.
MsgBoxSetForeground Specifies the message box window as the foreground window.
MsgBoxRight Text is right-aligned.
MsgBoxRtlReading 1048576 Specifies text should appear as right-to-left reading on Hebrew and Arabic systems.
.INPUTS
None. You cannot pipe objects to this.
.OUTPUTS
Based on the button you press, this returns these below.
OK
Cancel
Abort
Retry
Ignore
Yes
No
To incorporate that into you main program, you can do something like this:
$resultMsg = Show-MessageBox_UI_Independant -Modal -Title "Hi there!" -Message "Important message goes here`nImportant message goes here." -Buttons "OkCancel,DefaultButton1"
if ($resultMsg -eq 'OK') {Write-Host "It's okay to press me.."}
.EXAMPLE Shows a Modal messagebox that stays on top of all other app until the user clicks a button
PS> Show-MessageBox_UI_Independant -Modal -Title "Hi there!" -Message "Important message goes here`nImportant message goes here." -Buttons "OkCancel"
.EXAMPLE Show a normal messagebox
PS> Show-MessageBox_UI_Independant -Title "Hi there!" -Message "Important message goes here`nImportant message goes here." -Buttons "OkCancel"
.EXAMPLE Show a normal messagebox with the default button being the OK button
PS> Show-MessageBox_UI_Independant Title "Hi there!" -Message "Important message goes here`nImportant message goes here." -Buttons "OkCancel,DefaultButton1"
#>
[CmdletBinding()]
Param (
[Parameter(Mandatory = $false)]
[string]$Title = 'MessageBox in PowerShell',
[Parameter(Mandatory = $true)]
[string]$Message,
[Parameter(Mandatory = $false)]
[string]$Buttons = 'OKCancel',
[Parameter(Mandatory = $false)]
[ValidateRange(1, 3)]
[int]$DefaultButton = 1,
[Parameter(Mandatory = $false)]
[Switch]$Modal = $false
)
# Determine the modal parameter
if ($Modal -eq $true) { $ModalOn = 'SystemModal,' } else { $ModalOn = '' }
Add-Type -AssemblyName System.Windows.Forms
[void][System.Windows.Forms.Application]::EnableVisualStyles()
[void][System.Reflection.Assembly]::LoadWithPartialName("Microsoft.VisualBasic")
[Microsoft.VisualBasic.Interaction]::MsgBox($Message, "$($ModalOn)$($Buttons)", $Title)
}
################################################################################
# Get-PSScriptPath function (Must be at the top)
################################################################################
Function Get-PSScriptPath {
<#
.SYNOPSIS
Returns the current file path of the .ps1 or compiled .exe with Win-PS2EXE.
.DESCRIPTION
This will return the path of the file. This will work when the .ps1 file is
converted with Win-PS2EXE
.NOTES
Author: stevehero
Date Created: 2021.05.03
Tested with PowerShell 5.1 and 7.1.
Posted here: https://stackoverflow.com/q/60121313/8262102
.PARAMETER None
NA
.INPUTS
None. You cannot pipe objects to Get-PSScriptPath.
.OUTPUTS
Returns the current file path of the .ps1 or compiled .exe with Win-PS2EXE.
.EXAMPLE (When run from a .ps1 file)
PS> Get-PSScriptPath
PS> C:\Users\Desktop\temp.ps1
.EXAMPLE (When run from a compiled .exe file with Win-PS2EXE.
PS> Get-PSScriptPath
PS> C:\Users\Desktop\temp.exe
#>
if ([System.IO.Path]::GetExtension($PSCommandPath) -eq '.ps1') {
$psScriptPath = $PSCommandPath
}
else {
# This enables the script to be compiled and get the directory of it.
$psScriptPath = [System.Diagnostics.Process]::GetCurrentProcess().MainModule.FileName
}
return $psScriptPath
}
#####
##### MAIN PROGRAM START
##### MAIN PROGRAM START
##### MAIN PROGRAM START
#####
# Define the input filename
$inputFileName = "index.txt"
# Define the output filename (You can change this to test before you try this program)
$outputFileName = "index.txt"
# Define the path to the input file
$inputFilePath = (Split-Path -LiteralPath (Get-PSScriptPath)) + "\" + $inputFileName
# Define the path to the output file
$outputFilePath = (Split-Path -LiteralPath (Get-PSScriptPath)) + "\" + $outputFileName
# Read all lines from the input file (Uses encoding to not mess up special characters)
$lines = Get-Content -Encoding UTF8 -LiteralPath $inputFilePath
# Extract the sortable key after the first colon and sort the lines
$sortedLines = $lines | Sort-Object {
# Split the line at the first occurrence of the colon
$lineParts = $_ -split ':', 2
if ($lineParts.Length -gt 1) {
# Use the part after the first colon for sorting
$lineParts[1].Trim()
} else {
# Fall back in case there is no colon in the line
$_
}
}
# Write the sorted lines to the output file (Uses encoding to not mess up special characters)
$sortedLines | Set-Content -Encoding UTF8 -Path $outputFilePath
# Show message box to restart foobar2000 to see the changes
Show-MessageBox_UI_Independant -Modal -Title "Playlist File Sorted..." -Message ("Playlist File $inputFileName sorted:`n`n$outputFilePath`n`n(Please restart foobar2000 to see the changes)") -Buttons "OkOnly"
#####
##### MAIN PROGRAM END
##### MAIN PROGRAM END
##### MAIN PROGRAM END
#####
What you'll see when you run program.