Cue Reader 5.6 - Updated 20/07/2014

Download and get help for different MediaMonkey Addons.

Moderators: Peke, Gurus

Cue Reader 5.6 - Updated 20/07/2014

Postby trixmoto » Fri Dec 09, 2005 11:17 am

Here is the long awaited Cue Reader script, as discussed here: http://www.mediamonkey.com/forum/viewtopic.php?t=6773. It will load the corresponding cue sheet when an mp3 is played, and if it has mulitple valid tracks, it will display a form allowing you to skip straight to them.

When my web hoster sorts itself out there will be an installer for this script on my website: http://trixmoto.net

ADDITION: I think I'm having problems with length in this box because I keep getting 403 Forbidden errors. Going to try posting the code separately! :)

EDIT: 8) Installer now available! 8)
Last edited by trixmoto on Sun May 25, 2008 3:31 pm, edited 13 times in total.
Download my scripts at trixmoto.net.
All the code for my website and scripts is safely backed up immediately and for free using Dropbox.
Send me BTC: 34VQPVsf9mCeR4nfhFvvBYZqQ7LkqNZ8Mn
Send me LTC: 3P1mzrfbyscdhbxRpXLgKz7tufGAU3SrEG
Send me DOGE: 9xPpYSqgF7P5yQiqvE1VqWb4UjxVCCLFJ6
Check out these great cryptocurrency faucets... BTC / LTC / DOGE
trixmoto
 
Posts: 10024
Joined: Fri Aug 26, 2005 3:28 am
Location: Barton, UK

The code

Postby trixmoto » Fri Dec 09, 2005 11:23 am

Code: Select all
'
' MediaMonkey Script
'
' NAME: CueReader 5.3
'
' AUTHOR: trixmoto (http://trixmoto.net)
' DATE : 30/10/2009
'
' Thanks to Bex for his missing cue sheet code
'
' INSTALL: Copy to Scripts\Auto directory
'
' FIXES: Fixed blank strings leave table cells blank
'        Added support for unicode characters in cue sheets
'        Added option to show/hide panel header section
'        Added option to show/hide panel borders
'        Added option to read cue sheets from a field
'

Option Explicit
Public styleOn

Sub OnStartUp
  'save defaults to ini file
  Dim ini : Set ini = SDB.IniFile
  If ini.StringValue("CueReader","ShowStartTime") = "" Then
    ini.BoolValue("CueReader","ShowStartTime") = True
  End If
  If ini.StringValue("CueReader","ShowHeaders") = "" Then
    ini.BoolValue("CueReader","ShowHeaders") = True
  End If
  If ini.StringValue("CueReader","FileMatching") = "" Then
    ini.BoolValue("CueReader","FileMatching") = True
  End If
  If ini.StringValue("CueReader","ShowPanelHeader") = "" Then
    ini.BoolValue("CueReader","ShowPanelHeader") = True
  End If 
  If ini.StringValue("CueReader","OddColour") = "" Then
    ini.StringValue("CueReader","OddColour") = "#FFFFFF"
  End If 
  If ini.StringValue("CueReader","EvenColour") = "" Then
    ini.StringValue("CueReader","EvenColour") = "#EFEFEF"
  End If
  If ini.StringValue("CueReader","TextColour") = "" Then
    ini.StringValue("CueReader","TextColour") = "#000000"
  End If
  If ini.StringValue("CueReader","HighlightColour") = "" Then
    ini.StringValue("CueReader","HighlightColour") = "#FFFF77"
  End If 
  If ini.StringValue("CueReader","EnableReader") = "" Then
    ini.BoolValue("CueReader","EnableReader") = True
  End If
  If ini.StringValue("CueReader","RefreshRate") = "" Then
    ini.IntValue("CueReader","RefreshRate") = 1000
  End If 
  If ini.StringValue("CueReader","SubNode1") = "" Then
    ini.StringValue("CueReader","SubNode1") = "Cuesheet correct"
  End If   
  If ini.StringValue("CueReader","SubNode2") = "" Then
    ini.StringValue("CueReader","SubNode2") = "Cuesheet faulty"
  End If
  If ini.StringValue("CueReader","SubNode3") = "" Then
    ini.StringValue("CueReader","SubNode3") = "Cuesheet missing"
  End If   
  If ini.StringValue("CueReader","Millis") = "" Then
    ini.StringValue("CueReader","Millis") = 1800000
  End If 
  If ini.StringValue("CueReader","External") = "" Then
    ini.BoolValue("CueReader","External") = False
  End If
  If ini.StringValue("CueReader","ShowPanelSection") = "" Then
    ini.BoolValue("CueReader","ShowPanelSection") = True
  End If     
  If ini.StringValue("CueReader","ShowPanelBorder") = "" Then
    ini.BoolValue("CueReader","ShowPanelBorder") = True
  End If   
  If ini.StringValue("CueReader","EmbedField") = "" Then
    ini.IntValue("CueReader","EmbedField") = 0  '1-5=Custom# 6=Mood 7=Occasion 8=Quality 9=Tempo 10=Comment
  End If   
 
  'create temporary tables
  Dim DB : Set DB = SDB.Database
  DB.ExecSQL("CREATE TEMP TABLE IF NOT EXISTS tmpMissingCueSheet (tmpId INTEGER PRIMARY KEY, tmpCuesheet TEXT COLLATE IUNICODE, tmpFolder TEXT COLLATE IUNICODE, tmpGroup INTEGER)")
  DB.ExecSQL("CREATE TEMP TABLE IF NOT EXISTS tmpMissingCueSheet2 (tmp2CueSheet TEXT COLLATE IUNICODE, tmp2Folder TEXT COLLATE IUNICODE, CONSTRAINT Index1 PRIMARY KEY(tmp2CueSheet, tmp2Folder))")
  DB.ExecSQL("CREATE TEMP TABLE If NOT EXISTS TmpMedias (tmpIDMedia INTEGER PRIMARY KEY, tmpDriveLetter TEXT COLLATE IUNICODE)")
 
  'create tree node
  Dim tree : Set tree = SDB.MainTree
  Dim node : Set node = tree.CreateNode
  node.Caption = "CueReader"
  node.UseScript = Script.ScriptPath
  Call Script.RegisterEvent(node,"OnFillChildren","FillCue")
  Call Script.RegisterEvent(node,"OnCanEditNode","EditCan")   
  Call Script.RegisterEvent(node,"OnNodeEditText","EditGet")   
  Call Script.RegisterEvent(node,"OnNodeEdited","EditSet")   
  node.IconIndex = 23
  Call tree.AddNode(tree.Node_FilesToEdit,node,3)
  node.HasChildren = True
 
  'add option sheet
  Call SDB.UI.AddOptionSheet("CueReader Settings",Script.ScriptPath,"InitSheet","SaveSheet",-2)
 
  'register events
  Call Script.RegisterEvent(SDB,"OnPlay","CueReader")
  Call Script.RegisterEvent(SDB,"OnBeforeTracksMove","MoveCue")
 
  'run on startup
  If SDB.Player.isPlaying Then
    Call CueReader()
  End If
End Sub

Sub CueReader
  'check reader is enabled
  Set SDB.Objects("CueReaderData") = Nothing
  Dim ini : Set ini = SDB.IniFile
  If Not (ini.BoolValue("CueReader","EnableReader")) Then
    Exit Sub
  End If
 
  'check current song
  Dim song : Set song = SDB.Player.CurrentSong
  If song Is Nothing Then
    Exit Sub
  End If
 
  'get path of cue
  Dim mp3f : mp3f = song.Path
  Dim mode : mode = InStrRev(mp3f,".") 
  Dim cuef : cuef = Left(mp3f,mode)&"cue"
  Dim filesys : Set filesys = CreateObject("Scripting.FileSystemObject")
  Dim ecue : ecue = ""
  Dim cue : Set cue = Nothing
  Dim fld : fld = ini.IntValue("CueReader","EmbedField")
  Dim boo : boo = False
  If fld > 0 Then
    Select Case fld
      Case 1
        ecue = song.Custom1
      Case 2
        ecue = song.Custom2
      Case 3
        ecue = song.Custom3
      Case 4
        ecue = song.Custom4
      Case 5
        ecue = song.Custom5
      Case 6
        ecue = song.Mood
      Case 7
        ecue = song.Occasion
      Case 8
        ecue = song.Quality
      Case 9
        ecue = song.Tempo
      Case 10
        ecue = song.Comment                                                                                                                                   
    End Select 
    If ecue = "" Then
      Exit Sub
    End If
  Else
    If filesys.FileExists(cuef) Then
      Set cue = filesys.OpenTextFile(cuef,1,False)
      boo = cue.AtEndOfStream
    Else
      Exit Sub
    End If 
  End If

  'setup form
  Dim Form : Set Form = SDB.Objects("CueReaderForm")
  If Form Is Nothing Then
    Set Form = SDB.UI.NewDockablePersistentPanel("CueReaderPanel")
    If Form.IsNew Then
      Form.DockedTo = 2
      Form.Common.Width = 250
    End If

    Dim WB : Set WB = SDB.UI.NewActiveX(Form, "Shell.Explorer")
    If ini.BoolValue("CueReader","ShowPanelBorder") Then
      WB.Common.Align = 5
    Else
      WB.Common.ClientWidth = Form.Common.ClientWidth
      WB.Common.ClientHeight = Form.Common.ClientHeight
      WB.Common.Anchors = 15 
    End If
    WB.Common.ControlName = "WB"
    SDB.Objects("CueReaderInterf") = WB.Interf
    SDB.Objects("CueReaderDocument") = WB.Interf.Document
  End If
 
  'setup variables
  Dim line : line = ""
  Dim str : str = ""
  Dim res : res = 0
  Dim data : Set data = CreateObject("Scripting.Dictionary")
  Dim trax : trax = 0
  Dim trak : trak = 1
  mode = 0   '0>file>title>performer, 1>track>title>performer, 2>index>title>performer, 3=success, 4=error
 
  'read cue file
  Do While Not boo
    If fld > 0 Then
      res = InStr(ecue,VbCrLf)     
      If res > 1 Then
        line = Trim(Left(ecue,res-1))
        ecue = Mid(ecue,res+2)
      Else   
        line = Trim(ecue)
        ecue = ""
        boo = True       
      End If         
    Else
      line = Trim(cue.ReadLine)
      boo = cue.AtEndOfStream
    End If
    Select Case Mid(line,1,4)
      Case "CATA"
        'ignore
      Case "CDTE"
        'ignore
      Case "FILE"
        Select Case mode
          Case 0
            If ini.BoolValue("CueReader","FileMatching") Then
              If filematches(mp3f,line) Then mode = 1
            Else
              mode = 1
            End If
          Case 1
            If trax > 1 Then
              mode = 3
            Else
              res = SDB.MessageBox("CueReader: Multiple tracks not found in file", mtError, Array(mbOk))
              mode = 4
            End If   
          Case 2
            res = SDB.MessageBox("CueReader: Invalid tracks found in file", mtError, Array(mbOk))
            mode = 4
        End Select
      Case "FLAG"
        'ignore
      Case "INDE"
        If mode = 2 Then
          If Mid(line,1,8) = "INDEX 01" Then
            data.Add "indx"&trax, mid(line,10)
            mode = 1
          End If
        End If
      Case "ISRC"
        'ignore
      Case "PERF"
        Select Case mode
          Case 0
            data.Item("artist") = Replace(Mid(line,11),chr(34),"")
          Case 1
            data.Item("artist") = Replace(Mid(line,11),chr(34),"")
          Case 2
            data.Add "perf"&trax, Replace(Mid(line,11),chr(34),"")
        End Select
      Case "POST"
        'ignore
      Case "PREG"
        'ignore
      Case "REM "
        'ignore
      Case "SONG"
        'ignore
      Case "TITL"
        Select Case mode
          Case 0
            data.Item("title") = Replace(Mid(line,7),chr(34),"")
          Case 1
            data.Item("title") = Replace(Mid(line,7),chr(34),"")
          Case 2
            data.Add "titl"&trax, Replace(Mid(line,7),chr(34),"")
        End Select
      Case "TRAC"
        If mode = 1 Then
          If line = gettrack(trax+1) Then
            trax = trax + 1
            mode = 2
          Else
            If (trax = 0) And (Left(line,6) = "TRACK ") AND (Right(line,6) = " AUDIO") Then
              Dim num : num = Trim(Mid(line,7,2))
              If IsNumeric(num) Then
                trax = Int(num)
                trak = trax
                mode = 2
              End If
            End If
          End If
        End If
      Case Else
        mode = InStr(line," ")
        If mode > 0 Then
          str = Left(line,mode-1)
        Else
          str = line
        End If
        res = SDB.MessageBox("CueReader: Unknown command in cue sheet: '"&str&"'", mtError, Array(mbOk))
        mode = 4
    End Select
  Loop
  If fld = 0 Then
    Call cue.Close()
  End If
     
  'display any error messages
  Select Case mode
    Case 0
      Call SDB.MessageBox("CueReader: File not found in cue sheet", mtError, Array(mbOk))
    Case 1
      If trax > 1 Then
        mode = 3
      Else
        Call SDB.MessageBox("CueReader: Multiple tracks not found in file", mtError, Array(mbOk))
      End If
    Case 2
      Call SDB.MessageBox("CueReader: Invalid tracks found in file", mtError, Array(mbOk))
    Case 3
      'success
    Case 4
      'other error
    Case Else
      Call SDB.MessageBox("CueReader: Unknown error occurred", mtError, Array(mbOk))
  End Select
 
  'display form
  If mode = 3 Then
    str = ""
    If ini.BoolValue("CueReader","ShowPanelHeader") Then
      If data.Item("artist") <> "" Then
        str = ": "&data.Item("artist")
      End If
      If data.Item("title") <> "" Then
        If str = "" Then
          str = ": "&data.Item("title")
        Else
          str = str&" - "&data.Item("title")
        End If
      End If
    End If
    Form.Caption = "Cue Reader"&str
    Form.ShowCaption = ini.BoolValue("CueReader","ShowPanelSection")
    SDB.Objects("CueReaderForm") = Form
    SDB.Objects("CueReaderData") = data

    Call writedocument(trak,trax)
    Form.Common.Visible = True

    Dim ms : ms = ini.IntValue("CueReader","RefreshRate")
    Dim Tmr : Set Tmr = SDB.CreateTimer(ms)
    Script.RegisterEvent Tmr, "OnTimer", "UpdateDocument"
  End If
End Sub

Sub UpdateDocument(Timer)
  Dim error,form,data,doc,row,curr
  If Not SDB.Player.isPlaying Then
    error = error&"player stopped. " 
  End If
  Set data = SDB.Objects("CueReaderData")
  If data Is Nothing Then
    error = error&"no data. " 
    curr = 0
  Else
    If Not (data.Item("reset") = "") Then
      'restart cue reader
      SDB.Objects("CueReaderDocument") = Nothing
      SDB.Objects("CueReaderForm") = Nothing
      Call CueReader()
      Exit Sub
    End If
    If data.Item("current") = "" Then
      data.Item("current") = SDB.Player.CurrentSong.ID
    Else
      If Not (SDB.Player.CurrentSong.ID = CLng(data.Item("current"))) Then
        error = error&"song changed. "
      End If
    End If
    If data.Item("curr") = "" Then
      data.Item("curr") = 0
    End If
    curr = CLng(data.Item("curr"))
  End If
  Set form = SDB.Objects("CueReaderForm")
  If form Is Nothing Then
    error = error&"no form. "
  Else
    If Not form.Common.Visible Then
      error = error&"form closed. " 
    End If
  End If   
  Set doc = SDB.Objects("CueReaderDocument")
  If doc Is Nothing Then 
    error = error&"no document. " 
  Else   
    If curr > 0 Then
      Set row = doc.getElementById("row"&curr)
      If row Is Nothing Then
        error = error&"no row. "
      End If
    End If
  End If
 
  If error = "" Then
    Dim classname,newcurr,newrow
    classname = data.Item("classname")
    curr = CLng(data.Item("curr")) 
    newcurr = getcurr()
    If Not (newcurr = curr) Then
      If curr > 0 Then
        Set newrow = doc.getElementById("row"&curr)
        If Not (newrow Is Nothing) Then
          newrow.className = classname
        End If
      End If
      Set newrow = doc.getElementById("row"&newcurr)
      If Not (newrow Is Nothing) Then
        data.Item("classname") = newrow.className
        newrow.className = "highlight"
      End If
      data.Item("curr") = newcurr
    End If
    SDB.Objects("CueReaderData") = data
  Else
    Script.UnregisterEvents Timer   
    If Not (form Is Nothing) Then
      form.Common.Visible = False
      SDB.Objects("CueReaderForm") = Nothing
    End If
  End If 
End Sub

Function MapXML(original)
  Dim hold : hold = original
  hold = Replace(hold,"&","&amp;")
  hold = Replace(hold," ","&nbsp;")
  hold = Replace(hold,"<","&lt;")
  hold = Replace(hold,">","&gt;")
  Dim i : i = 1
  While (i <= Len(hold))
    If (AscW(Mid(hold,i,1)) > 127) Then
      hold = Mid(hold,1,i-1)+"&#"+CStr(AscW(Mid(hold,i,1)))+";"+Mid(hold,i+1)
    End If
    i = i + 1
  WEnd
  If hold = "" Then
    MapXML = "&nbsp;"
  Else
    MapXML = hold
  End If
End Function

Function Style()
  styleOn = Not styleOn
  If styleOn Then
    Style = ""
  Else
    Style = " class='dark'"
  End If
End Function

Function getcurr()
  getcurr = 1
  Dim data : Set data = SDB.Objects("CueReaderData")
  If data Is Nothing Then
    Exit Function
  End If
  Dim boo : boo = False
 
  Do While (getcurr < 100)
    Dim indx : indx = data.Item("indx"&(getcurr+1))
    If indx = "" Then
      If boo Then
        Exit Do
      Else
        getcurr = getcurr + 1
      End If
    Else
      boo = True
      If SDB.Player.PlaybackTime > gettime(indx) Then
        getcurr = getcurr + 1
      Else
        Exit Do
      End If
    End If
  Loop
End Function

Function filematches(par1,par2)
  filematches = False
  Dim mp3f : mp3f = UCase(par1)
  Dim line : line = UCase(par2)
  line = Mid(line,6,InStrRev(line," ")-6)
  line = Replace(line,chr(34),"")

  If line = mp3f Then
    filematches = True   'absolute
  ElseIf line = Mid(mp3f,InStrRev(mp3f,"\")+1) Then
    filematches = True   'relative
  End If
End Function

Function gettrack(num)
  If num < 10 Then
    gettrack = "TRACK 0"&num&" AUDIO"
  Else
    gettrack = "TRACK "&num&" AUDIO"
  End If
End Function

Function gettime(txt)
  Dim min : min = Clng(Mid(txt,1,Len(txt)-6))
  Dim sec : sec = Clng(Mid(txt,Len(txt)-4,2))
  Dim fra : fra = Clng(Mid(txt,Len(txt)-1,2))
  gettime = min*60000 + sec*1000 + fra*13
End Function

Function settime(lng)
  Dim tint : tint = lng\60000
  Dim min : min = lead2(tint)
  lng = lng - (tint*60000)
  Dim sec : sec = lead2(lng\1000)
  settime = min&":"&sec
End Function

Function lead2(i)
  If i < 10 Then
    lead2 = "0"&i
  Else
    lead2 = ""&i
  End If
End Function

Sub writedocument(trak,trax)
  'get web component
  Dim web : Set web = SDB.Objects("CueReaderInterf")
  If web Is Nothing Then
    Exit Sub
  End If

  'get data 
  Dim data : Set data = SDB.Objects("CueReaderData")
  If data Is Nothing Then
    Exit Sub 
  End If

  'setup variables 
  Dim txt,i,pos,dur
  Dim ini : Set ini = SDB.IniFile 
  Dim OddColour : OddColour = ini.StringValue("CueReader","OddColour")
  Dim EvenColour : EvenColour = ini.StringValue("CueReader","EvenColour")
  Dim TextColour : TextColour = ini.StringValue("CueReader","TextColour")
  Dim HighlightColour : HighlightColour = ini.StringValue("CueReader","HighlightColour") 
  Dim External : External = ini.BoolValue("CueReader","External")
 
  'get editor path
  Dim str : str = ini.StringValue("CueReader","CueEditor")
  str = Replace(str,chr(34),chr(34)&chr(34))
  Dim str2 : str2 = str
  If InStr(str,"<cue>") > 0 Then
    i = InStrRev(SDB.Player.CurrentSong.Path,".") 
    txt = Left(SDB.Player.CurrentSong.Path,i)&"cue" 
    str = Replace(str,"<cue>",txt)
  End If
  If External Then
    If InStr(str2,"<cue>") > 0 Then
      txt = Replace(Script.ScriptPath,".vbs",".css")
      str2 = Replace(str2,"<cue>",txt)
    End If
  Else
    str2 = ""
  End If 
 
  'create html file
  Dim fso : Set fso = CreateObject("Scripting.fileSystemObject")
  Dim out : Set out = fso.CreateTextFile(Script.ScriptPath&".htm",True,True)       
  out.WriteLine "<!DOCTYPE HTML PUBLIC ""-//W3C//DTD HTML 4.0 Transitional//EN"">"
  out.WriteLine "<html>"
  out.WriteLine "  <head>" 
  out.WriteLine "    <title>"&SDB.Localize("Cue Reader")&"</title>"
  If External Then
    out.WriteLine "    <link rel=""stylesheet"" href=""CueReader.css"" type=""text/css"" />"
    out.WriteLine "  </head>"
  Else
    out.WriteLine "  </head>"
    out.WriteLine "  <style type=""text/css"">"
    out.WriteLine "    body{font-family:'Verdana',sans-serif; background-color:"&OddColour&"; font-size:9pt; color:"&TextColour&";}"
    out.WriteLine "    H1{font-family:'Verdana',sans-serif; font-size:10pt; font-weight:bold; color:#AAAAAA; text-align:left}"
    out.WriteLine "    P{font-family:'Verdana',sans-serif; font-size:8pt; color:"&TextColour&";}"
    out.WriteLine "    TH{font-family:'Verdana',sans-serif; font-size:9pt; font-weight:bold; color:"&TextColour&"; border-color:"&TextColour&"; border-style: solid; border-left-width:0px; border-right-width:0px; border-top-width:0px; border-bottom-width:3px;}"
    out.WriteLine "    TD{font-family:'Verdana',sans-serif; font-size:7pt; color:"&TextColour&"; border-color:"&TextColour&"; border-style: solid; border-left-width:0px; border-right-width:0px; border-top-width:0px; border-bottom-width:1px;}" 
    out.WriteLine "    TR.aleft TH{text-align:left}"
    out.WriteLine "    TR.dark{background-color:"&EvenColour&"}"
    out.WriteLine "    TR.highlight{background-color:"&HighlightColour&"}"       
    out.WriteLine "  </style>"
  End If
  out.WriteLine "  <script Language=""VBScript"">"
  out.WriteLine "    Dim SDB : Set SDB = CreateObject(""SongsDB.SDBApplication"")"
  out.WriteLine "    Function gotopos (str)"
  out.WriteLine "      If Clng(str) < SDB.Player.CurrentSongLength Then"
  out.WriteLine "        SDB.Player.PlaybackTime = Clng(str)"
  out.WriteLine "      End If"
  out.WriteLine "    End Function"
  If Not (str = "") Then
    out.WriteLine "    Function editfile"
    out.WriteLine "      Dim wsh : Set wsh = CreateObject(""WScript.Shell"")"
    out.WriteLine "      Call wsh.Run("""&str&""",1,0)"
    out.WriteLine "    End Function"
  End If 
  out.WriteLine "    Function restart"
  out.WriteLine "      Set data = SDB.Objects(""CueReaderData"")"
  out.WriteLine "      If Not (data Is Nothing) Then"
  out.WriteLine "        data.Item(""reset"") = ""now"""
  out.WriteLine "      End If"
  out.WriteLine "    End Function"
  If Not (str2 = "") Then
    out.WriteLine "    Function editstyle"
    out.WriteLine "      Dim wsh : Set wsh = CreateObject(""WScript.Shell"")"
    out.WriteLine "      Call wsh.Run("""&str2&""",1,0)"
    out.WriteLine "    End Function"
  End If 
  out.WriteLine "  </script>"
  out.WriteLine "  <body id='bbody'>"
  out.WriteLine "    <table border=""0"" cellspacing=""0"" cellpadding=""4"" width=""100%"">" 
       
  If ini.BoolValue("CueReader","ShowHeaders") Then
    out.WriteLine "      <tr class=""aleft"">"
    out.WriteLine "        <th nowrap width=10>" & SDB.Localize("Track") & "</th>"
    If ini.BoolValue("CueReader","ShowStartTime") Then
      out.WriteLine "        <th nowrap width=10>" & SDB.Localize("Start") & "</th>"
    End If
    out.WriteLine "        <th nowrap width=10>" & SDB.Localize("Length") & "</th>"
    out.WriteLine "        <th nowrap width=40%>" & SDB.Localize("Artist") & "</th>" 
    out.WriteLine "        <th nowrap width=60%>" & SDB.Localize("Title") & "</th>"     
    out.WriteLine "      </tr>"
  End If

  For i = trak To trax
    out.WriteLine "      <tr id='row"&i&"'" & Style() & ">"
    txt = """vbscript:gotopos("&gettime(data.Item("indx"&i))&")"""
    out.WriteLine "        <td nowrap width=10>"
    out.WriteLIne "          <a href="&MapXML(txt)&">"&lead2(i)&"</a></td>"
         
    pos = gettime(data.Item("indx"&i))
    If ini.BoolValue("CueReader","ShowStartTime") Then
      If pos > SDB.Player.CurrentSongLength Then
       txt = "??:??"
      Else
        txt = data.Item("indx"&i)
        txt = Mid(txt,1,Len(txt)-3)
      End If
      out.WriteLine "        <td nowrap width=10>" & MapXML(txt) & "</td>"
    End If
         
    If pos > SDB.Player.CurrentSongLength Then
      txt = "??:??"
    Else
      If i<trax Then
        dur = gettime(data.Item("indx"&(i+1))) - gettime(data.Item("indx"&i))
      Else
        dur = SDB.Player.CurrentSonglength - gettime(data.Item("indx"&i))
      End If         
      txt = settime(dur)
    End If
    out.WriteLine "        <td nowrap width=10>" & MapXML(txt) & "</td>"
         
    out.WriteLine "        <td nowrap width=40%>" & MapXML(data.Item("perf"&i)) & "</td>"           
    out.WriteLine "        <td nowrap width=60%>" & MapXML(data.Item("titl"&i)) & "</td>"
    out.WriteLine "      </tr>"
  Next
  out.WriteLine "    </table>"
 
  out.WriteLine "  <script Language=""JavaScript1.2"">"
  out.WriteLine "    document.write(""<span id='spanreset' style='container:positioned; position:absolute;'><a href='vbscript:restart()'><img src='reset.gif' border=0></a></span>"");"
  If Not (str = "") Then
    out.WriteLine "    document.write(""<span id='spanedit' style='container:positioned; position:absolute;'><a href='vbscript:editfile()'><img src='edit.gif' border=0></a></span>"");"
  End If   
  If Not (str2 = "") Then
    out.WriteLine "    document.write(""<span id='spanstyle' style='container:positioned; position:absolute;'><a href='vbscript:editstyle()'><img src='style.gif' border=0></a></span>"");"
  End If   
  out.WriteLine "    setInterval(""repos()"",500);" 
  out.WriteLine "    function repos() {"
  out.WriteLine "      document.all(""spanreset"").style.top = bbody.scrollTop+5;"
  out.WriteLine "      document.all(""spanreset"").style.left = bbody.scrollWidth-17;"
  If Not (str = "") Then 
    out.WriteLine "      document.all(""spanedit"").style.top = bbody.scrollTop+20;"
    out.WriteLine "      document.all(""spanedit"").style.left = bbody.scrollWidth-17;" 
  End If
  If Not (str2 = "") Then 
    out.WriteLine "      document.all(""spanstyle"").style.top = bbody.scrollTop+37;"
    out.WriteLine "      document.all(""spanstyle"").style.left = bbody.scrollWidth-17;" 
  End If
  out.WriteLine "      return true;"
  out.WriteLine "    }"
  out.WriteLine "  </script>"   
 
  out.WriteLine "  </body>"
  out.WriteLine "</html>"
  out.Close
  Call web.Navigate(Script.ScriptPath&".htm")
End Sub

Sub InitSheet(Sheet)
  Dim ini : Set ini = SDB.IniFile
  Dim ui : Set ui = SDB.UI
  Dim edt : Set edt = ui.NewCheckBox(Sheet)
  edt.Common.SetRect 5, 5, 400, 20
  edt.Common.ControlName = "CueEnableReader"
  edt.Caption = "Enable Cue Reader"
  edt.Checked = ini.BoolValue("CueReader","EnableReader")
 
  Set edt = ui.NewCheckBox(Sheet)
  edt.Common.SetRect 5, 30, 400, 20
  edt.Common.ControlName = "CueShowPanelHeader"
  edt.Caption = "Show panel header"
  edt.Checked = ini.BoolValue("CueReader","ShowPanelHeader")
 
  Set edt = ui.NewCheckBox(Sheet)
  edt.Common.SetRect 5, 55, 400, 20
  edt.Common.ControlName = "CueShowHeaders"
  edt.Caption = "Show table headers"
  edt.Checked = ini.BoolValue("CueReader","ShowHeaders")
 
  Set edt = ui.NewCheckBox(Sheet)
  edt.Common.SetRect 205, 30, 400, 20
  edt.Common.ControlName = "CueShowPanelSection"
  edt.Caption = "Show panel header section"
  edt.Checked = ini.BoolValue("CueReader","ShowPanelSection")
 
  Set edt = ui.NewCheckBox(Sheet)
  edt.Common.SetRect 205, 55, 400, 20
  edt.Common.ControlName = "CueShowPanelBorder"
  edt.Caption = "Show panel borders"
  edt.Checked = ini.BoolValue("CueReader","ShowPanelBorder")
 
  Set edt = ui.NewCheckBox(Sheet)
  edt.Common.SetRect 5, 80, 200, 20
  edt.Common.ControlName = "CueShowStartTime"
  edt.Caption = "Show track start times"
  edt.Checked = ini.BoolValue("CueReader","ShowStartTime")
 
  Set edt = ui.NewLabel(Sheet)
  edt.Common.SetRect 205, 82, 45, 20
  edt.Caption = "Embedded in field:"
  edt.Autosize = False 
 
  Set edt = ui.NewDropdown(Sheet)
  edt.Common.Left = 300
  edt.Common.Top = 79
  edt.Common.ControlName = "CueEmbedField"
  edt.AddItem("(None)")
  edt.AddItem("Custom1")
  edt.AddItem("Custom2")
  edt.AddItem("Custom3")
  edt.AddItem("Custom4")
  edt.AddItem("Custom5")
  edt.AddItem("Mood")
  edt.AddItem("Occasion")
  edt.AddItem("Quality")
  edt.AddItem("Tempo")
  edt.AddItem("Comment")
  edt.ItemIndex = ini.IntValue("CueReader","EmbedField") 
  edt.Style = 2   
 
  Set edt = ui.NewCheckBox(Sheet)
  edt.Common.SetRect 5, 105, 400, 20
  edt.Common.ControlName = "CueFileMatching"
  edt.Caption = "Perform file matching (when disabled, first in cuesheet is used)"
  edt.Checked = ini.BoolValue("CueReader","FileMatching")
 
  Set edt = ui.NewLabel(Sheet)
  edt.Common.SetRect 5, 133, 45, 20
  edt.Caption = "Refresh rate (ms):"
  edt.Autosize = False
 
  Set edt = ui.NewSpinEdit(Sheet)
  edt.Common.SetRect 105, 130, 50, 20
  edt.Common.ControlName = "CueRefreshRate"
  edt.MinValue = 100
  edt.MaxValue = 9999
  edt.Value = ini.IntValue("CueReader","RefreshRate")
 
  Set edt = ui.NewLabel(Sheet)
  edt.Common.SetRect 5, 160, 45, 20
  edt.Caption = "External editor:"
  edt.Autosize = False 
 
  Set edt = ui.NewEdit(Sheet)
  edt.Common.SetRect 105, 157, 300, 20
  edt.Common.ControlName = "CueEditor" 
  edt.Common.Hint = "You can use <cue> to insert the filepath"
  edt.Text = ini.StringValue("CueReader","CueEditor")
 
  Set edt = ui.NewButton(Sheet)
  edt.Common.SetRect 410, 156, 20, 23
  edt.Caption = "..."
  edt.UseScript = Script.ScriptPath
  edt.OnClickFunc = "BrowseEditor"
   
  Set edt = ui.NewLabel(Sheet)
  edt.Common.SetRect 5, 185, 45, 20
  edt.Caption = "Minimum length (s):"
  edt.Autosize = False 
 
  Set edt = ui.NewSpinEdit(Sheet)
  edt.Common.SetRect 105, 182, 50, 20
  edt.Common.ControlName = "CueMillis"
  edt.MinValue = 60
  edt.MaxValue = 9999
  edt.Value = ini.IntValue("CueReader","Millis")\1000
 
  Set edt = ui.NewLabel(Sheet)
  edt.Common.SetRect 160, 185, 200, 20
  edt.Caption = "(used to determine tracks with cuesheets)"
  edt.Autosize = False

  Set edt = ui.NewLabel(Sheet)
  edt.Common.SetRect 5, 235, 45, 20
  edt.Caption = "COLOURS...."
  edt.Autosize = False
 
  Set edt = ui.NewLabel(Sheet)
  edt.Common.SetRect 15, 260, 45, 20
  edt.Caption = "Odd row:"
  edt.Autosize = False
 
  Set edt = ui.NewEdit(Sheet)
  edt.Common.SetRect 85, 257, 100, 20
  edt.Common.ControlName = "CueOddColour" 
  edt.Text = ini.StringValue("CueReader","OddColour")
  Dim boo : boo = Not ini.BoolValue("CueReader","External")
  edt.Common.Enabled = boo
 
  Set edt = ui.NewLabel(Sheet)
  edt.Common.SetRect 15, 285, 45, 20
  edt.Caption = "Even row:"
  edt.Autosize = False
 
  Set edt = ui.NewEdit(Sheet)
  edt.Common.SetRect 85, 282, 100, 20
  edt.Common.ControlName = "CueEvenColour"
  edt.Text = ini.StringValue("CueReader","EvenColour")   
  edt.Common.Enabled = boo
 
  Set edt = ui.NewLabel(Sheet)
  edt.Common.SetRect 15, 310, 45, 20
  edt.Caption = "Main text:"
  edt.Autosize = False
 
  Set edt = ui.NewEdit(Sheet)
  edt.Common.SetRect 85, 307, 100, 20
  edt.Common.ControlName = "CueTextColour"
  edt.Text = ini.StringValue("CueReader","TextColour")   
  edt.Common.Enabled = boo
 
  Set edt = ui.NewLabel(Sheet)
  edt.Common.SetRect 15, 335, 45, 20
  edt.Caption = "Highlight:"
  edt.Autosize = False 
 
  Set edt = ui.NewEdit(Sheet)
  edt.Common.SetRect 85, 332, 100, 20
  edt.Common.ControlName = "CueHighlightColour"
  edt.Text = ini.StringValue("CueReader","HighlightColour")   
  edt.Common.Enabled = boo
 
  Set edt = ui.NewCheckBox(Sheet)
  edt.Common.SetRect 5, 360, 400, 20
  edt.Common.ControlName = "CueExternal"
  edt.Caption = "Use external stylesheet ('CueReader.css') for colours"
  edt.Checked = ini.BoolValue("CueReader","External")
  Call Script.RegisterEvent(edt.Common,"OnClick","ExternalClick")
End Sub

Sub ExternalClick(chk)
  Dim par : Set par = chk.Common.TopParent.Common
  Dim boo : boo = Not chk.Checked
  par.ChildControl("CueOddColour").Common.Enabled = boo
  par.ChildControl("CueEvenColour").Common.Enabled = boo
  par.ChildControl("CueTextColour").Common.Enabled = boo
  par.ChildControl("CueHighlightColour").Common.Enabled = boo
End Sub

Sub SaveSheet(Sheet)
  Dim ini : Set ini = SDB.IniFile
  ini.BoolValue("CueReader","EnableReader") = Sheet.Common.ChildControl("CueEnableReader").Checked
  ini.BoolValue("CueReader","ShowHeaders") = Sheet.Common.ChildControl("CueShowHeaders").Checked
  ini.BoolValue("CueReader","ShowPanelHeader") = Sheet.Common.ChildControl("CueShowPanelHeader").Checked
  ini.BoolValue("CueReader","ShowStartTime") = Sheet.Common.ChildControl("CueShowStartTime").Checked
  ini.BoolValue("CueReader","FileMatching") = Sheet.Common.ChildControl("CueFileMatching").Checked
  ini.StringValue("CueReader","OddColour") = Sheet.Common.ChildControl("CueOddColour").Text
  ini.StringValue("CueReader","EvenColour") = Sheet.Common.ChildControl("CueEvenColour").Text
  ini.StringValue("CueReader","TextColour") = Sheet.Common.ChildControl("CueTextColour").Text
  ini.StringValue("CueReader","HighlightColour") = Sheet.Common.ChildControl("CueHighlightColour").Text
  ini.IntValue("CueReader","RefreshRate") = Sheet.Common.ChildControl("CueRefreshRate").Value
  ini.StringValue("CueReader","CueEditor") = Sheet.Common.ChildControl("CueEditor").Text
  ini.BoolValue("CueReader","External") = Sheet.Common.ChildControl("CueExternal").Checked
  ini.IntValue("CueReader","Millis") = Sheet.Common.ChildControl("CueMillis").Value*1000
  ini.BoolValue("CueReader","ShowPanelSection") = Sheet.Common.ChildControl("CueShowPanelSection").Checked
  ini.BoolValue("CueReader","ShowPanelBorder") = Sheet.Common.ChildControl("CueShowPanelBorder").Checked
  ini.IntValue("CueReader","EmbedField") = Sheet.Common.ChildControl("CueEmbedField").ItemIndex
 
  'restart cue reader 
  SDB.Objects("CueReaderDocument") = Nothing
  SDB.Objects("CueReaderForm") = Nothing
  Call CueReader()
End Sub

Sub BrowseEditor(ClickedBtn)
  Dim Sheet : Set Sheet = ClickedBtn.Common.Parent
  If Not (Sheet Is Nothing) Then
    Dim edt : Set edt = Sheet.Common.ChildControl("CueEditor")
    If Not (edt Is Nothing) Then
      Dim dlg : Set dlg = SDB.CommonDialog
      dlg.Title = "Select cuesheet editor..."
      dlg.DefaultExt = ".exe"
      dlg.Filter = "Executable (*.exe)|*.exe"
      dlg.Flags = cdlOFNOverwritePrompt + cdlOFNHideReadOnly + cdlOFNNoChangeDir
      dlg.InitDir = edt.Text
      dlg.ShowOpen
      If Not dlg.Ok Then Exit Sub
      If dlg.FileName = "" Then Exit Sub
      edt.Text = dlg.FileName
      If InStr(edt.Text," ") Then
        edt.Text = Chr(34)&edt.Text&Chr(34)
      End If
    End If
  End If
End Sub

Sub MoveCue(tracks,paths,move)
  Dim filesys,i,j,k,itm,mp3f,dest,sour,typ
  Set filesys = CreateObject("Scripting.FileSystemObject")
   
  For i = 0 To tracks.Count-1
    Set itm = tracks.Item(i)
    mp3f = ecue = song.Path
    j = InStrRev(mp3f,".") 
    sour = Left(mp3f,j)&"cue"
   
    If filesys.FileExists(sour) Then
      mp3f = paths.Item(i)
      j = InStrRev(mp3f,".")
      dest = Left(mp3f,j)&"cue"
      If sour = dest Then
        Exit Sub
      End If       
     
      typ = UCase(Mid(mp3f,j+1))
      mp3f = "FILE """&filesys.GetFileName(mp3f)&""" "
      Dim line : line = ""
      Dim changed : changed = False
      Dim match : match = False
      If SDB.IniFile.IntValue("CueReader","FileMatching") = 1 Then
        match = True
      End If

      Dim cue1 : Set cue1 = Nothing
      Dim temp : temp = ""
      If UCase(sour) = UCase(dest) Then 
        temp = sour&".tmp"
        While filesys.FileExists(temp)
          temp = temp&".tmp"
        WEnd
        Call filesys.CopyFile(sour,temp,True)     
        Call filesys.DeleteFile(sour)
        Set cue1 = filesys.OpenTextFile(temp,1,False)
      Else
        Set cue1 = filesys.OpenTextFile(sour,1,False)
      End If
     
      If Not (cue1 Is Nothing) Then
        Dim cue2 : Set cue2 = filesys.CreateTextFile(dest,True,True)
        If Not (cue2 Is Nothing) Then
          Do While Not cue1.AtEndOfStream
            line = cue1.ReadLine
            If Not changed Then
              line = Trim(line)
              If Mid(line,1,4) = "FILE" Then
                typ = Mid(line,InStrRev(line," ")+1)
                If match Then
                  If filematches(itm.Path,line) Then
                    line = mp3f&typ
                    changed = True
                  End If
                Else
                  line = mp3f&typ
                  changed = True
                End If
              End If
            End If
            Call cue2.WriteLine(line)
          Loop
          cue2.Close
        End If
        cue1.Close
      End If
     
      If move Then
        mp3f = "moved"
      Else
        mp3f = "copied"
      End If
      If filesys.FileExists(dest) Then
        If (move) And (temp = "") Then
          Call filesys.DeleteFile(sour)
        End If
        line = "Cue file "&mp3f&" to '"&dest&"' but FILE command could not be updated."
      Else
        changed = False
        If Not (temp = "") Then
          Call filesys.CopyFile(temp,sour,True)
        End If       
        line = "Cue file could not be "&mp3f&" to '"&dest&"'."     
      End If
      If Not (temp = "") Then
        Call filesys.DeleteFile(temp)
      End If     
      If Not changed Then     
        Call SDB.MessageBox(line,mtError,Array(mbOk))
      End If     
    End If
  Next
End Sub

Sub FillCue(node)
  node.HasChildren = False
  Dim fso,sql,iter,cue1,cue2,fold,fold1,dNode,fld,cue3,file,i,values,dl,tot,tot2
  Dim DB : Set DB = SDB.Database
  Dim Millis : Millis = SDB.IniFile.IntValue("CueReader","Millis")
 
  'create progress bar
  Dim prog : Set prog = SDB.Progress
  prog.Text = "CueReader: Initialising..."
  prog.Value = 0
  tot = DB.OpenSQL("SELECT COUNT(*) FROM Songs WHERE SongLength > "&Millis).ValueByIndex(0)
  prog.MaxValue = tot*2
 
  'populate TmpMedias. Can't be done in Onstartup since SDB.Media object doesn't get created until later
  If DB.OpenSQL("SELECT COUNT(*) FROM TmpMedias").ValueByIndex(0) = 0 Then
    Set iter = DB.QuerySongs("Songs.ID IN (SELECT MIN(Songs.ID) FROM Songs GROUP BY IDMedia)")
    Do While Not iter.EOF
      If iter.item.Media.DriveLetter = -1 Then
        dl = ""
      Else
        dl = Chr(iter.item.Media.DriveLetter+65)
      End If
      values = values&"UNION SELECT "&iter.item.Media.ID&",'"&dl&"' FROM (SELECT 1) "
      iter.Next
    Loop
    DB.ExecSQL("INSERT INTO TmpMedias (tmpIDMedia, tmpDriveLetter) "&Mid(values,7))
    Set iter = Nothing
  End If
  DB.ExecSQL("DELETE FROM tmpMissingCueSheet")
  DB.ExecSQL("DELETE FROM tmpMissingCueSheet2")
  values = ""
  i = 0
 
  'populate TmpMissingCueSheet
  Set fso = CreateObject("Scripting.fileSystemObject")
  sql = "SELECT tmpDriveLetter||SongPath, ID FROM Songs, TmpMedias WHERE IDmedia=TmpIDMedia AND Songs.SongLength > "&Millis
  Set iter = DB.OpenSQL(sql)
  Do While Not iter.EOF
    prog.Text = "CueReader: Checking track "&(prog.Value+1)&"/"&tot&"..."
    prog.Value = prog.Value+1
    cue1 = Left(Iter.StringByIndex(0),InStrRev(Iter.StringByIndex (0),"."))&"cue"
    cue2 = Replace(cue1,"'","''")
    fold = Left(Iter.StringByIndex(0),InStrRev(Iter.StringByIndex(0),"\"))
    fold = Replace(fold,"'","''")
    i = i+1
    If fso.FileExists(cue1) Then
      values = values&"UNION SELECT "&iter.ValueByIndex(1)&", '"&cue2&"', '"&fold&"', 1 FROM (SELECT 1) "
    Else
      values = values&"UNION SELECT "&iter.ValueByIndex(1)&" ,'X' ,'"&fold&"', 3 FROM (SELECT 1) "
    End If
    If i = 100 Then
      DB.ExecSQL("INSERT INTO tmpMissingCueSheet (tmpId, tmpCuesheet, tmpFolder, tmpGroup) "&Mid(values,7))
      i = 0
      values = ""
    End If
    iter.Next
  Loop
  Set iter = Nothing
  If Not values = "" Then
    DB.ExecSQL("INSERT INTO tmpMissingCueSheet (tmpId, tmpCuesheet, tmpFolder, tmpGroup) "&Mid(values,7))
  End If
  values = ""
  i = 0
  tot2 = DB.OpenSQL("SELECT COUNT(DISTINCT tmpFolder) FROM tmpMissingCueSheet WHERE tmpCuesheet='X'").ValueByIndex(0)
  prog.MaxValue = Int(tot)+Int(tot2)+2
 
  'populate TmpMissingCueSheet2
  sql = "SELECT DISTINCT tmpFolder FROM tmpMissingCueSheet WHERE tmpCuesheet='X'"
  Set iter = DB.OpenSQL(sql)
  Do While Not iter.EOF
    prog.Text = "CueReader: Checking folder "&(prog.Value+1-tot)&"/"&tot2&"..."
    prog.Value = prog.Value+1 
    fold = Iter.StringByIndex(0)
    fold = Replace(fold,"''","'")
    If fso.FolderExists(fold) Then
      Set fld = fso.getFolder(fold)
      For Each file In fld.files
        If UCase(Right(file.Name,4))=".CUE" Then
          i = i+1
          cue3 = file.Path
          cue3 = Replace(cue3,"'","''")
          fold1 = Replace(fold,"'","''")
          values = values&"UNION SELECT '"&fold1&"' ,'"&cue3&"' FROM (SELECT 1) "
          If i = 100 Then
            DB.ExecSQL("INSERT INTO tmpMissingCueSheet2 (tmp2Folder, tmp2CueSheet) "&Mid(values,7))
            i = 0
            values = ""
          End If
        End If
      Next
    End If
    iter.Next
  Loop
  Set iter = Nothing
  If Not values = "" Then
    DB.ExecSQL("INSERT INTO tmpMissingCueSheet2 (tmp2Folder, tmp2CueSheet) "&Mid(values,7))
  End If
  DB.ExecSQL("DELETE FROM tmpMissingCueSheet2 WHERE tmp2CueSheet IN (SELECT tmpcuesheet FROM tmpMissingCueSheet)")
  DB.ExecSQL("UPDATE tmpMissingCueSheet SET tmpGroup = 2 WHERE tmpCuesheet='X' AND tmpFolder IN (SELECT tmp2Folder FROM tmpMissingCueSheet2)")
 
  'add nodes
  prog.Value = prog.MaxValue
  prog.Text = "CueReader: Finialising..." 
  sql = "SELECT tmpGroup, COUNT(*) FROM tmpMissingCueSheet GROUP BY tmpGroup"
  Set iter = DB.OpenSQL(sql)
  Do While Not iter.EOF
    Set dNode = SDB.MainTree.CreateNode
    dNode.IconIndex = 23
    dNode.CustomData = Iter.StringByIndex(0)
    Call Script.RegisterEvent(dNode,"OnFillTracks","AddTracks")
    Call Script.RegisterEvent(dNode,"OnCanEditNode","SubnCan")   
    Call Script.RegisterEvent(dNode,"OnNodeEditText","SubnGet")   
    Call Script.RegisterEvent(dNode,"OnNodeEdited","SubnSet")   
    dNode.Caption = GetCaption(Iter.StringByIndex(0))&" ("&Iter.StringByIndex(1)&")"
    Call SDB.MainTree.AddNode(node,dNode,3)
    iter.Next
  Loop
  Set iter = Nothing
End Sub

Function GetCaption(nr)
  Select Case nr
    Case 1
      GetCaption = SDB.IniFile.StringValue("CueReader","SubNode1")
    Case 2
      GetCaption = SDB.IniFile.StringValue("CueReader","SubNode2")
    Case 3
      GetCaption = SDB.IniFile.StringValue("CueReader","SubNode3")
  End Select
End Function

Sub AddTracks(Node)
  SDB.MainTracksWindow.AddTracksFromQuery("WHERE Songs.ID IN (SELECT tmpId FROM tmpMissingCueSheet WHERE tmpGroup="&Node.CustomData&")")
End Sub

Function EditCan(Node)
  EditCan = True
End Function

Function EditGet(Node)
  EditGet = CStr(SDB.IniFile.IntValue("CueReader","Millis")/60000)
End Function

Sub EditSet(Node,NewMillis)
  If Not IsNumeric(NewMillis) Then
    Call SDB.MessageBox("CueReader: Number of minutes only, try again!",mtError,Array(mbOK))
    Exit Sub
  End If
  If NewMillis < 1 Then
    Call SDB.MessageBox("CueReader: Positive number of minutes only, try again!",mtError,Array(mbOK))
    Exit Sub
  End If 
  SDB.IniFile.IntValue("CueReader","Millis") = NewMillis*60000
End Sub

Function SubnCan(Node)
  SubnCan = True
End Function

Function SubnGet(Node)
  SubnGet = SDB.IniFile.StringValue("CueReader","SubNode"&Node.CustomData)
End Function

Sub SubnSet(Node,NewCaption)
  SDB.IniFile.StringValue("CueReader","SubNode"&Node.CustomData) = NewCaption
End Sub
Last edited by trixmoto on Tue Dec 13, 2005 3:26 pm, edited 1 time in total.
Download my scripts at trixmoto.net.
All the code for my website and scripts is safely backed up immediately and for free using Dropbox.
Send me BTC: 34VQPVsf9mCeR4nfhFvvBYZqQ7LkqNZ8Mn
Send me LTC: 3P1mzrfbyscdhbxRpXLgKz7tufGAU3SrEG
Send me DOGE: 9xPpYSqgF7P5yQiqvE1VqWb4UjxVCCLFJ6
Check out these great cryptocurrency faucets... BTC / LTC / DOGE
trixmoto
 
Posts: 10024
Joined: Fri Aug 26, 2005 3:28 am
Location: Barton, UK

Postby trixmoto » Fri Dec 09, 2005 11:44 am

Known issues:

1) If there is no limit on the size of the form, so more than 20(ish) tracks gives an unusable form - ideas for better form design appreciated.

2) FILE command in CUE sheet must be an absolute path - relative path will be possible in next version.

3) Only TITLE and PERFORMER commands are read for a track - is there a demand for any others to be read?

4) Only a single index per track is read (INDEX 01) - is there a demand for subindexes to be read?
Download my scripts at trixmoto.net.
All the code for my website and scripts is safely backed up immediately and for free using Dropbox.
Send me BTC: 34VQPVsf9mCeR4nfhFvvBYZqQ7LkqNZ8Mn
Send me LTC: 3P1mzrfbyscdhbxRpXLgKz7tufGAU3SrEG
Send me DOGE: 9xPpYSqgF7P5yQiqvE1VqWb4UjxVCCLFJ6
Check out these great cryptocurrency faucets... BTC / LTC / DOGE
trixmoto
 
Posts: 10024
Joined: Fri Aug 26, 2005 3:28 am
Location: Barton, UK

Postby trixmoto » Tue Dec 13, 2005 3:28 pm

New version (1.3) now available (new installer also on my website):

:o NEW CODE BELOW :o
Download my scripts at trixmoto.net.
All the code for my website and scripts is safely backed up immediately and for free using Dropbox.
Send me BTC: 34VQPVsf9mCeR4nfhFvvBYZqQ7LkqNZ8Mn
Send me LTC: 3P1mzrfbyscdhbxRpXLgKz7tufGAU3SrEG
Send me DOGE: 9xPpYSqgF7P5yQiqvE1VqWb4UjxVCCLFJ6
Check out these great cryptocurrency faucets... BTC / LTC / DOGE
trixmoto
 
Posts: 10024
Joined: Fri Aug 26, 2005 3:28 am
Location: Barton, UK

Postby trixmoto » Wed Dec 14, 2005 5:28 pm

New version (2.0) allows you to limit the number of tracks shown at once (default=10) and scroll through them to find later ones.

:o NEW CODE BELOW :o
Last edited by trixmoto on Fri Dec 16, 2005 11:26 am, edited 1 time in total.
Download my scripts at trixmoto.net.
All the code for my website and scripts is safely backed up immediately and for free using Dropbox.
Send me BTC: 34VQPVsf9mCeR4nfhFvvBYZqQ7LkqNZ8Mn
Send me LTC: 3P1mzrfbyscdhbxRpXLgKz7tufGAU3SrEG
Send me DOGE: 9xPpYSqgF7P5yQiqvE1VqWb4UjxVCCLFJ6
Check out these great cryptocurrency faucets... BTC / LTC / DOGE
trixmoto
 
Posts: 10024
Joined: Fri Aug 26, 2005 3:28 am
Location: Barton, UK

Postby judas » Thu Dec 15, 2005 4:56 pm

I dont have many files with cue sheets in them...but i have tried the script with the few ones i have and I love it...and I'm impressed as always with your scripts.

One addition i think that would be nice is to close the window when you change to another track on MM...now it stays open and have to close it manually. only a minor annoiance though...

see ya around again now that I have finished exams.
judas
 
Posts: 572
Joined: Thu Jun 02, 2005 11:26 pm
Location: Bogotá, Colombia

Postby trixmoto » Fri Dec 16, 2005 5:48 am

I was thinking about that, but it would mean having a second monitor script to watch the player. Yeah, I think I'll add this to the next version. :)
Download my scripts at trixmoto.net.
All the code for my website and scripts is safely backed up immediately and for free using Dropbox.
Send me BTC: 34VQPVsf9mCeR4nfhFvvBYZqQ7LkqNZ8Mn
Send me LTC: 3P1mzrfbyscdhbxRpXLgKz7tufGAU3SrEG
Send me DOGE: 9xPpYSqgF7P5yQiqvE1VqWb4UjxVCCLFJ6
Check out these great cryptocurrency faucets... BTC / LTC / DOGE
trixmoto
 
Posts: 10024
Joined: Fri Aug 26, 2005 3:28 am
Location: Barton, UK

Postby judas » Fri Dec 16, 2005 10:37 am

:P NICE :P
judas
 
Posts: 572
Joined: Thu Jun 02, 2005 11:26 pm
Location: Bogotá, Colombia

Postby trixmoto » Fri Dec 16, 2005 11:28 am

New version (2.1) - this has a monitor script which hides the form if the player is stopped or the track is changed. There is also a bug fixed, where if you play the same song over and over you get the same form many times on top of itself - now each new form closes the old one first.

:o NEW CODE BELOW :o
Last edited by trixmoto on Tue Jan 03, 2006 9:39 am, edited 1 time in total.
Download my scripts at trixmoto.net.
All the code for my website and scripts is safely backed up immediately and for free using Dropbox.
Send me BTC: 34VQPVsf9mCeR4nfhFvvBYZqQ7LkqNZ8Mn
Send me LTC: 3P1mzrfbyscdhbxRpXLgKz7tufGAU3SrEG
Send me DOGE: 9xPpYSqgF7P5yQiqvE1VqWb4UjxVCCLFJ6
Check out these great cryptocurrency faucets... BTC / LTC / DOGE
trixmoto
 
Posts: 10024
Joined: Fri Aug 26, 2005 3:28 am
Location: Barton, UK

Postby judas » Thu Dec 22, 2005 9:25 am

Hey trix..I've been playing around with the script and so far Im happy with it, 2 comments though:

BUG: After scrolling down on the list you can´t go back up because the ^ does not appear

addition: how about organizing the fields in columns? maybe that would make it easier to find a specific song? maybe add column headings and that way there would be no need to specify Artist: xxxx and Title: yyyy for every track?

besides that...i dunno how hard it would be...but is it possible to make a script that warns you when moving/renaming a file that has a cue sheet associated with it?

cheers...

judas
judas
 
Posts: 572
Joined: Thu Jun 02, 2005 11:26 pm
Location: Bogotá, Colombia

Postby trixmoto » Fri Dec 23, 2005 5:04 am

I'm rather confused about the "/\" button because it appears on mine. I'll have to check how the position is specified.

Columns could be a good idea. The trouble is that the screen is then as wide as the longest artist plus the longest title, which can be very wide (depending on your taste in music). I'll have a play though and maybe you'll see them in the next version! :)

Are there any other columns you'd like to see?

I think it would be impossible to write a MM script that did this because there is no event for moving/renaming. A script could be written I suppose that you'd run externally which could check all your cue sheets to see if the tracks can be found and warn if any are invalid, but it wouldn't be sensible to have this running as a monitor. I'll mull it over. :)
Download my scripts at trixmoto.net.
All the code for my website and scripts is safely backed up immediately and for free using Dropbox.
Send me BTC: 34VQPVsf9mCeR4nfhFvvBYZqQ7LkqNZ8Mn
Send me LTC: 3P1mzrfbyscdhbxRpXLgKz7tufGAU3SrEG
Send me DOGE: 9xPpYSqgF7P5yQiqvE1VqWb4UjxVCCLFJ6
Check out these great cryptocurrency faucets... BTC / LTC / DOGE
trixmoto
 
Posts: 10024
Joined: Fri Aug 26, 2005 3:28 am
Location: Barton, UK

Postby trixmoto » Tue Jan 03, 2006 9:44 am

New version (3.0) has an entirely new display which should be more user friendly.

:o NEW CODE BELOW :o

N.B. You will need the Internet Explorer security setting "Initialise and script ActiveX controls not marked as safe" set to at least prompt if not enable (otherwise you will get the error messge "ActiveX component can't create object: 'SongsDB.SDBApplication' ") - this is all the script is doing, connecting to MM.
Last edited by trixmoto on Sun Jan 08, 2006 8:23 am, edited 1 time in total.
Download my scripts at trixmoto.net.
All the code for my website and scripts is safely backed up immediately and for free using Dropbox.
Send me BTC: 34VQPVsf9mCeR4nfhFvvBYZqQ7LkqNZ8Mn
Send me LTC: 3P1mzrfbyscdhbxRpXLgKz7tufGAU3SrEG
Send me DOGE: 9xPpYSqgF7P5yQiqvE1VqWb4UjxVCCLFJ6
Check out these great cryptocurrency faucets... BTC / LTC / DOGE
trixmoto
 
Posts: 10024
Joined: Fri Aug 26, 2005 3:28 am
Location: Barton, UK

Postby Bex » Tue Jan 03, 2006 2:26 pm

Trixi!

This is a beautiful one. I've been using the mp3cue plugin made for winamp until now, but I probably going to change to this instead. It just looks so much better than mp3cue.

There are however some wishes I have that imo would enhance this beauty. I dont know if all are possible but anyway, here they are:

1) Support for more filetypes than mp3 (I've have alot flac's and ape's)
2) Change the layout so the songs are displayed like this:
Track#. mm:ss (mm:ss) Artists - Title (First time is timestamp, second is songlenght, If track# = 1-9, display 01-09)
Eg:
01. 00:00 (03.23) Juliet - Avalon
02. 03:24 (05.57) Jaf Presents Nicole Brown - Music It Is My Life (Jaf Vocal Mix)
03. 09:22 (04.14) DJ Jose - Hecitate (DJ Antoine vs Mad Mark Club Mix)
04. 13:37 (04.37) David Tort & Toni Bali - Beer & Skittles
3) Highlight the song currently playing and remove the clickable box so the rowhight is the same as in now playing. Finally, make the songs themself clickable.
4) If TRACK or PERFORMER commands exist before any TRACK commands in the cue file, they are Album Name and Album Artist. It would be nice to display them in the top of the Cue Reader window if they exist.

I hope you find my suggestions interesting!
I also must say that your contribution to this community is great and much appreciated, especially your scripts!

Thanks!
/Martin
Last edited by Bex on Tue Jan 03, 2006 7:29 pm, edited 1 time in total.
Bex
 
Posts: 6316
Joined: Fri May 21, 2004 5:44 am
Location: Sweden

Postby Bex » Tue Jan 03, 2006 4:00 pm

Playing around with this plugin I found a file which triggered an error "Unknown command in cue sheet". I opened the cue file and found a REM command which i've never seen before. Since i didnt know what it was and Peke's great "CueSheet editor help" file didnt say anything about it, I googled and found a good site:
http://digitalx.org/cuesheetsyntax.php
It says regarding REM:
REM

Description:

This command is used to put comments in your CUE SHEET file.
Syntax:

REM (comment)
Example:

REM This is a comment
Rules:

None.


Would be great if your script could handle this REM comand!

/Martin
Bex
 
Posts: 6316
Joined: Fri May 21, 2004 5:44 am
Location: Sweden

Postby Peke » Tue Jan 03, 2006 6:23 pm

REM Back in 2000 there was no Note about REM :( Althru my Editor ignores it you are right it should be supported.
Best regards,
Pavle
MM Core Developer and Admin of free MediaMonkey extensions Hosting
Image
Image
Peke
 
Posts: 10441
Joined: Tue Jun 10, 2003 7:21 pm
Location: Serbia

Next

Return to Need Help with Addons?

Who is online

Users browsing this forum: Majestic-12 [Bot], Yahoo [Bot] and 14 guests