knowledge, passion and patience on making MediaMonkey the best music manager around.
I hope that it's now my turn to make something useful for the community. So I would be very happy to achieve this with the release of this script.
Any suggestions and comments are welcome.
This Script is inspired by and based upon trixmoto's "BackButton.vbs".
The original script can be found at: http://www.mediamonkey.com/forum/viewtopic.php?t=8483
Thanks to trixmoto for making so many useful scripts and his permission to publish this modification to his script!
Description:
Script creates buttons/menuentries, which allow to navigate in a list of recently played tracks.
This is especially useful when tracks are played in random order (shuffle mode) or when "jumping around"
in the now playing list.
Hence the name "ShuffleNavigate".
Notes:
- The script is not yet tested in MediaMonkey 3.0
- If you experience memory problems, then try to disable menuentries or buttons and reduce the number of listentries (especially iMaxJumpEntries)
Installation:
1) Create a textfile nameed "ShuffleNavigate.vbs" in the folder "..\MediaMonkey\scripts\Auto\"
2) Copy the code from below and paste it into "ShuffleNavigate.vbs"
3) Modify any of the default values (see usage tips below)
4) Locate your scripts.ini in the folder "..\MediaMonkey\scripts\". Open the scripts.ini and add the following lines:
5) MediaMonkey needs to be restarted to activate the script[ShuffleNavigateMain]
FileName=Auto\ShuffleNavigate.vbs
ProcName=ShuffleNavigateMain
Order=38
DisplayName=ShuffleNavigateMain
Description=ShuffleNavigateMain
Language=VBScript
ScriptType=2
Usage tips:
iMaxHistorySize = 10 -> Maximum number of remembered songs in history
iMaxJumpEntries = 10 -> Maximum number of songs in the submenu called by pressing the button in the toolbar
Do not set the value too high, as I fear, that it would consume to much memory!
So try to increase the value in small steps.
bJumpButtonMode = True -> If True then pressing the button in the toolbar shows a submenu for direct songselection
If False then pressing the button in the toolbar selects/plays the first listentry
iMaxHintLines = 10 -> Maximum number of entries listed in buttonhints (tooltips)
bClearHistory = True -> If True then history will be erased on startup
bBrowserMode = False -> If True then the behavior of the forward history is comparable to internet browsers. So forward history is cleared, when the currently played track changes.
If False then forward history remembers every track skipped by moving backwards.
sBackShortCut = "Ctrl+Alt+B" -> Set this according to your preferences.
sForShortCut = "Ctrl+Alt+F" Depends on locale! Maybe you must use Strg (german) instead of Ctrl.
bShowButton = True -> Set it to False to avoid the creation of toolbarbuttons
bShowMenu = True -> Set it to False to hide the play menu entries
bShowInPopupMenu = True -> Set it to False to avoid the creation of entries in the NP popupmenu
bShowMessages = False -> Supress end of list messages. This value is just a relict of trixmoto's script and has no real function by now. But maybe it will be used in future.
sBackCaption = "Previous" -> Caption should be localized.
sForCaption = "Next" But if you prefer a different caption or localization didn't work, you can change it here.
sBackIcon = "41" -> All menuentries and buttons use the Mediamonkey standardicon "41"
sForIcon = "42" Let me know, if you want to use user-definable icons.
bDebug = False -> True = Output() writes into logfile .\scripts\Auto\ShuffleNavigate.vbs.log.
Only useful for developers. Currently only the start of a procedure or function is logged.
bLogAppend = False -> False = Logfile will be deleted on Startup
Todos:
- Setting of script parameters via option sheet
- Creation of a script installer (I don't know the commonly used installer, so I have to check out it's usage first)
- Adding submenus to the mainmenuentries and the popupmenus to allow direct selection
- Test in MediaMonkey 3.x
Code: Select all
'+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
'+ MediaMonkey Auto Script +
'+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
'
' NAME: ShuffleNavigate 1.0
'
' AUTHOR: SHR
'
' DATE : 24/03/2007
'
' DESCRIPTION: Script creates buttons/menuentries, which allow to navigate in a
' list of recently played tracks. This is especially useful when
' tracks are played in random order (shuffle mode).
' Hence the name "ShuffleNavigate". ;-)
'
' SUPPORT FORUM: http://www.mediamonkey.com/forum/viewtopic.php?t=16702
'
' NOTE: Script is inspired by and based upon trixmoto's "BackButton.vbs".
' Original script can be found at:
' http://www.mediamonkey.com/forum/viewtopic.php?t=8483
' Thanks to trixmoto for making so many useful scripts and his
' permission to publish this version!
'
' INSTALL: Copy to Scripts\Auto directory and add the following section to
' Scripts.ini.
' You must remove the comments ('). Set the order value as needed.
' This script uses default values
'
' [ShuffleNavigateMain]
' FileName=Auto\ShuffleNavigate.vbs
' ProcName=ShuffleNavigateMain
' Order=38
' DisplayName=ShuffleNavigateMain
' Description=ShuffleNavigateMain
' Language=VBScript
' ScriptType=2
'
'-------------------------------------------------------------------------------
'>> ForumURL: http://www.mediamonkey.com/forum/viewtopic.php?t=16702
'>> ScriptName: ShuffleNavigate
'>> VersionNumber: 1.0
'>> Author: SHR
'>>>>EndOfProperties
'-------------------------------------------------------------------------------
Option Explicit
'+ declarations +
Dim sNavigateMode
Dim obtnBack, obtnFor, omnuBack, omnuFor
Dim opopNPBack, opopNPFor, opopTLBack, opopTLFor
'-------------------------------------------------------------------------------
'+++ default values +++
'-------------------------------------------------------------------------------
Dim iMaxHistorySize : iMaxHistorySize = 10 ' maximum number of songs in history
Dim iMaxJumpEntries : iMaxJumpEntries = 10 ' maximum number of songs in submenu
Dim bJumpButtonMode : bJumpButtonMode = True ' True = Use submenu for selection
Dim iMaxHintLines : iMaxHintLines = 10 ' maximum number of songs in buttonhints
Dim bClearHistory : bClearHistory = True ' True = Clear history on startup
Dim bBrowserMode : bBrowserMode = False ' If True then the behavior of the forward
' history is comparable to internet browsers
Dim sBackShortCut : sBackShortCut = "Strg+Alt+B" ' Depends on locale! Maybe you
Dim sForShortCut : sForShortCut = "Strg+Alt+F" ' must use Strg instead of Ctrl
Dim bShowButton : bShowButton = True ' False = Don't create toolbarbuttons
Dim bShowMenu : bShowMenu = True ' False = Menu entries will be hidden
Dim bShowInPopupMenu : bShowInPopupMenu = True ' False = Don't show in NP popup
Dim bShowMessages : bShowMessages = False ' False = Supress end of list messages
Dim sBackCaption : sBackCaption = "Previous" ' Choose whatever makes sense to you
Dim sForCaption : sForCaption = "Next" ' Choose whatever makes sense to you
Dim sBackIcon : sBackIcon = "41" ' Default icon "41"
Dim sForIcon : sForIcon = "42" ' Default icon "42"
Dim bDebug : bDebug = False ' True = Output() writes into logfile
Dim bLogAppend : bLogAppend = False ' False = Logfile will be deleted on Startup
'-------------------------------------------------------------------------------
'-------------------------------------------------------------------------------
' +++ Subroutines +++
'-------------------------------------------------------------------------------
'+ Called when MediaMonkey is started +
'-------------------------------------------------------------------------------
Sub OnStartup()
Dim sBackHistory, sForHistory
Dim asEntries
If Not bLogAppend Then Output "OutputCommand=DeleteLogfile"
Output "On Startup(): started"
'+ Create menu entries +
If bShowMenu Then
Call SDB.UI.AddMenuItemSep(SDB.UI.Menu_Play,2,-1)
End If
' these are always created, but hidden if bShowMenu = False
Call CreateMI("omnu", "Back")
Call CreateMI("omnu", "For")
'+ Create buttons +
If bShowButton then
Call CreateMI("obtn", "Back")
Call CreateMI("obtn", "For")
End If
'+ Create popupmenu entries +
If bShowInPopupMenu Then
Call CreateMI("opopNP", "Back")
Call CreateMI("opopNP", "For")
Call CreateMI("opopTL", "Back")
Call CreateMI("opopTL", "For")
End If
'+ read saved history and initialize +
If bClearHistory Then
SDB.IniFile.stringValue("ShuffleNavigate","BackButtonHistory") = ""
sBackHistory = ""
SDB.IniFile.stringValue("ShuffleNavigate","ForButtonHistory") = ""
sForHistory = ""
Else
sBackHistory = SDB.IniFile.stringValue("ShuffleNavigate","BackButtonHistory")
sForHistory = SDB.IniFile.stringValue("ShuffleNavigate","ForButtonHistory")
End If
If bBrowserMode Then
SDB.IniFile.stringValue("ShuffleNavigate","ForButtonHistory") = ""
End If
'+ Set initial state of all menuitems +
Dim i, asList
asList = Split("Back|sBackHistory|For|sForHistory", "|")
For i = 0 to UBound(asList) Step 2
asList(i+1) = SDB.IniFile.stringValue("ShuffleNavigate", asList(i) & "ButtonHistory")
If asList(i+1) = "" Or asList(i+1) = "|" Then
Call ChangeState(asList(i), False)
Else
asEntries = Split(asList(i+1),"|")
If UBound(asEntries)=0 Then
Call ChangeState(asList(i), False)
Else
Call ChangeState(asList(i), True)
End If
End If
Next
End Sub
'-------------------------------------------------------------------------------
'+ Capture "OnClick" events and trigger ShuffleNavigate routine +
'-------------------------------------------------------------------------------
Sub OnBackButton(obtnClicked)
Output "OnBackButton(obtnClicked): started"
Call ShuffleNavigate ("Back",1)
End Sub
'-------------------------------------------------------------------------------
Sub OnForButton(obtnClicked)
Output "OnForButton(obtnClicked): started"
Call ShuffleNavigate ("For",1)
End Sub
'-------------------------------------------------------------------------------
Sub OnJumpBackButton(obtnClicked)
Dim iCycle, sCaption
sCaption = obtnClicked.Caption
Output "OnJumpBackButton(obtnClicked): started"
iCycle = left(sCaption, Instr(sCaption,":")-1)
Call ShuffleNavigate ("Back", iCycle)
End Sub
'-------------------------------------------------------------------------------
Sub OnJumpForButton(obtnClicked)
Dim iCycle, sCaption
sCaption = obtnClicked.Caption
Output "OnJumpForButton(obtnClicked): started"
iCycle = left(sCaption, Instr(sCaption,":")-1)
Call ShuffleNavigate ("For", iCycle)
End Sub
'-------------------------------------------------------------------------------
'+ ShuffleNavigate is called by "OnClick" events +
'-------------------------------------------------------------------------------
Sub ShuffleNavigate(sMode, iCycle)
Dim sHistory, sSaveHistory, sTrackID, sTrackIDToSave
Dim iPos, asEntries, iMaxEntries
Dim sHistoryToRead, sHistoryToSave
Dim sDirection1, sDirection2
Output "ShuffleNavigate(sMode, iCycle): started"
SDB.IniFile.stringValue("ShuffleNavigate","NavigateMode") = sMode
Select Case sMode
Case "Back"
sHistoryToRead = "BackButtonHistory"
sHistoryToSave = "ForButtonHistory"
sDirection1 = "Back"
sDirection2 = "For"
Case "For"
sHistoryToRead = "ForButtonHistory"
sHistoryToSave = "BackButtonHistory"
sDirection1 = "For"
sDirection2 = "Back"
Case Else
Exit Sub
End Select
sHistory = SDB.IniFile.stringValue("ShuffleNavigate",sHistoryToRead)
If sHistory = "" Then
If bShowMessages Then
iPos = SDB.MessageBox("Sorry, there are no tracks in the History to go to.",mtInformation,Array(mbOk))
End If
SDB.IniFile.stringValue("ShuffleNavigate","NavigateMode") = ""
Call ChangeState(sDirection1, False)
Exit Sub
End If
' get track to play
asEntries = Split(Mid(sHistory,2,Len(sHistory)-2),"|")
iMaxEntries = UBound(asEntries)
Dim iDo
Select Case sMode
Case "For"
If iMaxEntries >= 0 Then
For iDo = 0 To iCycle-1
sTrackID = Int(asEntries(iMaxEntries - iDo))
If sTrackIDToSave = "" Then
sTrackIDToSave = Int(asEntries(iMaxEntries - iDo))
Else
sTrackIDToSave = sTrackIDToSave & "|" & Int(asEntries(iMaxEntries - iDo))
End If
Next
If iMaxEntries = 0 Then
Call ChangeState(sDirection1, False)
End If
Else
If bShowMessages Then
iPos = SDB.MessageBox("Sorry, there are no tracks in the History to go to.",mtInformation,Array(mbOk))
End If
SDB.IniFile.stringValue("ShuffleNavigate","NavigateMode") = ""
Call ChangeState(sDirection1, False)
Exit Sub
End If
Case "Back"
If iMaxEntries > 0 Then
For iDo = 0 To iCycle-1
sTrackID = Int(asEntries(iMaxEntries-1-iDo))
If sTrackIDToSave = "" Then
sTrackIDToSave = Int(asEntries(iMaxEntries - iDo))
Else
sTrackIDToSave = sTrackIDToSave & "|" & Int(asEntries(iMaxEntries - iDo))
End If
Next
If iMaxEntries - iDo + 1 = 1 Then
Call ChangeState(sDirection1, False)
End If
Else
If bShowMessages Then
iPos = SDB.MessageBox("Sorry, there are no tracks in the History to go to.",mtInformation,Array(mbOk))
End If
SDB.IniFile.stringValue("ShuffleNavigate","NavigateMode") = ""
Call ChangeState(sDirection1, False)
Exit Sub
End If
End Select
Dim found
found = False
If SDB.Player.CurrentSong.ID = sTrackID Then
found = True
Else
Dim list, itm, i
Set list = SDB.Player.CurrentSongList
For i = 0 To list.Count-1
Set itm = list.Item(i)
If itm.ID = sTrackID Then
SDB.Player.CurrentSongIndex = CLng(i)
found = True
Exit For
End If
Next
' Search and add song
If Not found Then
Dim sSQL,iter
sSQL = "AND (Songs.ID="&sTrackID&")"
Set iter = SDB.Database.QuerySongs(sSQL)
If Not iter.EOF Then
SDB.Player.PlaylistAddTrack(iter.Item)
SDB.Player.CurrentSongIndex = list.Count
found = True
End If
End If
End If
' update history
If found Then
sHistory = Left(sHistory,Len(sHistory)-(Len(sTrackIDToSave)+1))
Call ChangeState(sDirection2, True)
sSaveHistory = SDB.IniFile.stringValue("ShuffleNavigate",sHistoryToSave)
If sSaveHistory = "" Or sSaveHistory = "|" Then
sSaveHistory = "|" & sTrackIDToSave & "|"
Else
' only append if sTrackIDToSave not last in sSaveHistory
If Not Right(sSaveHistory,Len(sTrackIDToSave)+2)="|" & sTrackIDToSave & "|" Then
sSaveHistory = sSaveHistory & sTrackIDToSave & "|"
End If
End If
asEntries = split(sSaveHistory,"|")
If sMode = "For" Then iMaxHistorySize = iMaxHistorySize + 1
If Ubound(asEntries) > iMaxHistorySize + 1 Then
sSaveHistory = ""
For i = Ubound(asEntries) - (iMaxHistorySize) to Ubound(asEntries)
sSaveHistory = sSaveHistory & "|" & asEntries(i)
Next
End If
SDB.IniFile.stringValue("ShuffleNavigate",sHistoryToSave) = sSaveHistory
call UpdateUI(sSaveHistory, sDirection2)
Else
If bShowMessages Then
iPos = SDB.MessageBox("Sorry, the track could not be found.",mtInformation,Array(mbOk))
End If
sHistory = Left(sHistory,Len(sHistory)-(Len(sTrackID)+Len(sTrackIDToSave)+2))
' only append if sTrackIDToSave not last in sHistory
If Not Right(sHistory,Len(sTrackIDToSave)+2)="|" & sTrackIDToSave & "|" Then
sHistory = sHistory & sTrackIDToSave & "|"
End If
End If
If sHistory = "" Or sHistory = "|" Then
Call ChangeState(sDirection1, False)
SDB.IniFile.stringValue("ShuffleNavigate",sHistoryToRead) = ""
call UpdateUI("", sDirection1)
Else
SDB.IniFile.stringValue("ShuffleNavigate",sHistoryToRead) = sHistory
call UpdateUI(sHistory, sDirection1)
End If
End Sub
'-------------------------------------------------------------------------------
'+ ShuffleNavigateMain is called, when a new track is played +
'-------------------------------------------------------------------------------
Sub ShuffleNavigateMain()
Dim sBackHistory, sTempHistory, obtn, asEntries, iMaxEntries, sTrackID
sNavigateMode = SDB.IniFile.stringValue("ShuffleNavigate","NavigateMode")
Output "ShuffleNavigateMain(): started"
Select Case sNavigateMode
Case "Back"
SDB.IniFile.stringValue("ShuffleNavigate","NavigateMode") = ""
Case "For"
SDB.IniFile.stringValue("ShuffleNavigate","NavigateMode") = ""
Case Else
sBackHistory = SDB.IniFile.stringValue("ShuffleNavigate","BackButtonHistory")
sTrackID = SDB.Player.CurrentSong.ID
' save sBackHistory for later use
sTempHistory = sBackHistory
If sBackHistory = "" Then
sBackHistory = "|" & sTrackID & "|"
Else
sBackHistory = sBackHistory & sTrackID & "|"
End If
Call ChangeState("Back", True)
asEntries = Split(Mid(sBackHistory,2,Len(sBackHistory)-2),"|")
iMaxEntries = UBound(asEntries)
If iMaxEntries > 0 Then
If asEntries(iMaxEntries-1) = asEntries(iMaxEntries) Then
' ignore track
sBackHistory = sTempHistory
If iMaxEntries = 1 Then
Call ChangeState("Back", False)
End If
Else
If iMaxEntries > iMaxHistorySize Then
sBackHistory = Mid(sBackHistory,Instr(2,sBackHistory,"|"))
End If
End If
Else
Call ChangeState("Back", False)
End If
SDB.IniFile.stringValue("ShuffleNavigate","BackButtonHistory") = sBackHistory
Call UpdateUI(sBackHistory,"Back")
If bBrowserMode Then
Call ChangeState("For", False)
SDB.IniFile.stringValue("ShuffleNavigate","ForButtonHistory") = ""
Call UpdateUI("","For")
End If
End Select
End Sub
'-------------------------------------------------------------------------------
' +++ Functions +++
'-------------------------------------------------------------------------------
'+ Set property .Enabled to (de-)activate menu items +
'-------------------------------------------------------------------------------
Function ChangeState(sDirection, bState)
Dim obtn, omnu, opopNP, opopTL
Output "ChangeState(sDirection, bState): started"
Set obtn = SDB.Objects("obtn" & sDirection)
Set omnu = SDB.Objects("omnu" & sDirection)
Set opopNP = SDB.Objects("opopNP" & sDirection)
Set opopTL = SDB.Objects("opopTL" & sDirection)
omnu.Enabled = bState
If bShowButton then
obtn.Enabled = bState
End If
If bShowInPopupMenu Then
opopNP.Enabled = bState
opopTL.Enabled = bState
End If
End Function
'-------------------------------------------------------------------------------
'+ Called by 'On Startup()' to create all menuitems
'-------------------------------------------------------------------------------
Function CreateMI(sMIType, sDirection)
Dim oMI, oMSI
Dim bUseScript : bUseScript = True
Output "CreateMI(sMIType, sDirection): started"
Select Case sMIType
Case "omnu"
Set oMI = SDB.UI.AddMenuItem(SDB.UI.Menu_Play,3,-1)
oMI.Visible = bShowMenu
Case "obtn"
If bJumpButtonMode Then
Set oMI = SDB.UI.AddMenuItemSub(SDB.UI.Menu_TbStandard,2,-1)
Dim iCounter
For iCounter = 1 to iMaxJumpEntries
Set oMSI = SDB.UI.AddMenuItem(oMI,0,0)
With oMSI
.Visible = False
.UseScript = Script.ScriptPath
.OnClickFunc = "OnJump" & sDirection & "Button"
End With
SDB.Objects("Jump" & sDirection & iCounter) = oMSI
Next
bUseScript = False
Else
Set oMI = SDB.UI.AddMenuItem(SDB.UI.Menu_TbStandard,2,-1)
End If
Case "opopNP"
Set oMI = SDB.UI.AddMenuItem(SDB.UI.Menu_Pop_NP,1,-1)
Case "opopTL"
Set oMI = SDB.UI.AddMenuItem(SDB.UI.Menu_Pop_TrackList,2,-1)
End Select
Select Case sDirection
Case "Back"
With oMI
.Caption = SDB.Localize(sBackCaption)
.ShortCut = sBackShortCut
.IconIndex = sBackIcon
End With
Case "For"
With oMI
.Caption = SDB.Localize(sForCaption)
.ShortCut = sForShortCut
.IconIndex = sForIcon
End With
End Select
With oMI
If bUseScript Then
.UseScript = Script.ScriptPath
.OnClickFunc = "On" & sDirection & "Button"
End If
.Enabled = False
End With
Set SDB.Objects(sMIType & sDirection) = oMI
End Function
'-------------------------------------------------------------------------------
'+ Update hints, captions and submenuentries +
'-------------------------------------------------------------------------------
Function UpdateUI(sTrackList, sHintMode)
Dim oArtist, obtnTBB, oRS
Dim sArtistname, sTitle, sSQL, asTracks
Dim i, iPos
Output "UpdateUI(sTrackList, sHintMode): started"
If bShowButton Then
Select Case sHintMode
Case "Back"
Set obtnTBB = SDB.Objects("obtnBack")
Case "For"
Set obtnTBB = SDB.Objects("obtnFor")
Case Else
Exit Function
End Select
If bJumpButtonMode Then
Dim obtnJumpButton
For i = 1 To iMaxJumpEntries
Set obtnJumpButton = SDB.Objects("Jump" & sHintMode & i)
If Not obtnJumpButton is Nothing then
With obtnJumpButton
.Visible = False
End With
End If
Next
End If
obtnTBB.Hint = ""
asTracks = split(sTrackList, "|")
iPos = 0
For i = UBound(asTracks) to 0 Step -1
If asTracks(i)<>"" Then
If i = UBound(asTracks)-1 And sHintMode = "Back" Then
' Skip first Entry
Else
iPos = iPos + 1
sSQL = "AND (Songs.ID=" & asTracks(i) & ")"
Set oRS = SDB.Database.QuerySongs(sSQL)
If Not oRS.EOF Then
set oArtist = oRS.Item.Artist
sArtistName = oArtist.Name
sTitle = oRS.Item.Title
If sTitle = "" then sTitle = "Unknown"
If sArtistName = "" then sArtistName = "Unknown"
If iMaxHintLines >= iPos Then
obtnTBB.Hint = obtnTBB.Hint & iPos & ": '" & sTitle & "' - '" & sArtistName & "' [" & asTracks(i) & "]" & "'" & vbcrlf
End If
If bJumpButtonMode And iMaxJumpEntries >= iPos Then
Set obtnJumpButton = SDB.Objects("Jump" & sHintMode & iPos)
If Not obtnJumpButton is Nothing then
With obtnJumpButton
.Caption = iPos & ": '" & sTitle & "' - '" & sArtistName & "' [" & asTracks(i) & "]"
.Visible = True
End With
End If
End If
End If
End If
End If
Next
End If
End Function
'-------------------------------------------------------------------------------
'+ Used to write messages into Logfile, when bDebug = True in default section +
'-------------------------------------------------------------------------------
Function Output(sText)
Dim oFSO, oLog, sCommand
Const ForWriting = 2
Const ForAppending = 8
Set oFSO = CreateObject("Scripting.FileSystemObject")
If Instr(sText, "OutputCommand=")>0 then sCommand = Mid(sText, Instr(sText, "=")+1)
Select Case sCommand
Case "DeleteLogfile"
If oFSO.FileExists(Script.ScriptPath & ".log") Then oFSO.DeleteFile(Script.ScriptPath & ".log")
Case Else
If bDebug Then
Set oFSO = CreateObject("Scripting.FileSystemObject")
Set oLog = oFSO.OpenTextFile(Script.ScriptPath & ".log", ForAppending, True)
oLog.WriteLine(sText)
oLog.Close
Set oLog = Nothing
End If
End Select
End Function
'-------------------------------------------------------------------------------
SHR