ocarina/trunk/src/plistView.py

358 lines
9.2 KiB
Python

import random
import gtk
import thread
import re
from menuItem import MenuItem
from song import Song
from list import List
CONTINUE = 0
PAFTER = 1
# This is both the playlist and the queue
class PlistView(gtk.Notebook):
def __init__(self,data,info):
gtk.Notebook.__init__(self)
self.connect("switch-page",self.changedTab)
self.set_scrollable(True)
self.data = data
self.info = info
self.controls = None
self.status = CONTINUE
self.ptime = 0
self.qtime = 0
self.search = ""
self.label = gtk.Label("")
self.label.show()
self.ptree = None
self.pwin = gtk.ScrolledWindow()
self.pwin.set_policy(gtk.POLICY_AUTOMATIC,gtk.POLICY_AUTOMATIC)
self.pwin.show()
self.qtree = None
self.makePList()
self.makeQList()
self.makeSearch()
self.qwin.show()
self.loadSong(True)
#gobject.timeout_add(1000,self.checkUpdate)
self.append_page(self.pwin,gtk.Label(""))
self.append_page(self.qwin,gtk.Label(""))
self.setTabText("plist")
self.setTabText("queue")
self.show()
def setStatus(self,status):
if status == "pafter":
self.status = PAFTER
def setTabText(self,tab):
if tab == "plist":
self.set_tab_label_text(self.pwin,"Playlist ("+str(len(self.data.curList))+")")
else:
self.set_tab_label_text(self.qwin,"Queue ("+str(len(self.data.curQ))+")")
# Check if the playlist has been updated
def checkUpdate(self):
if self.data.updateList == True:
self.clearList(self.plist)
self.data.updateList = False
self.ptime = self.popList(self.data.curList,self.plist)
self.setTabText("plist")
return True
def makePList(self):
self.plist = gtk.ListStore(int,str,str,str,str,int)
if self.ptree:
self.pwin.remove(self.ptree)
self.ptree,self.ptreesel = self.list2Tree(self.plist)
self.pwin.add(self.ptree)
self.prcmenu = gtk.Menu()
queue = MenuItem("Queue Song",self.enqueue,None,None,None,)
self.prcmenu.append(queue)
self.plist.set_sort_column_id(self.data.sortedCol,gtk.SORT_ASCENDING)
self.ptree.connect("button_release_event",self.clicked)
self.ptime = self.popList(self.data.curList,self.plist)
self.pfilter = self.plist.filter_new()
self.pfilter.set_visible_func(self.hideRows)
self.psort = gtk.TreeModelSort(self.pfilter)
self.ptree.set_model(self.psort)
#self.pfilter.set_child(self.ptreesel)
# Populate a list
def popList(self,src,dst):
time = self.generateList(src,dst)
return time
def makeQList(self):
self.qwin = gtk.ScrolledWindow()
self.qwin.set_policy(gtk.POLICY_AUTOMATIC,gtk.POLICY_AUTOMATIC)
self.qlist = gtk.ListStore(int,str,str,str,str,int)
self.qtree,self.qtreesel = self.list2Tree(self.qlist)
self.qwin.add(self.qtree)
self.qtime = self.generateList(self.data.curQ,self.qlist)
def generateList(self,src,dst):
time = 0
i = len(dst)
for index in src:
track = self.data.library.files[index]
dst.insert(i,[track.id,track.title,track.length,track.artist,track.album,track.count])
time+=track.duration
i+=1
return time
# Called by libview to add rows to list
def addToList(self,src,dest):
self.ptime+=self.generateList(src,dest)
self.updatePTime()
self.setTabText("plist")
# Make the playlist and show it
def list2Tree(self,list):
tree = gtk.TreeView(list)
cell = gtk.CellRendererText()
cols = ["Id","Title","Length","Artist","Album","#"]
lenSaved = len(self.data.colSizes)
for i in range(len(cols)):
col = gtk.TreeViewColumn(cols[i],cell)
col.add_attribute(cell,'text',i)
col.set_resizable(True)
col.set_sort_column_id(i)
col.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
col.set_min_width(2)
col.set_max_width(700)
col.set_sort_indicator(False)
if cols[i] != "Id":
tree.append_column(col)
tree.set_rules_hint(True)
tree.set_enable_search(True)
tree.connect("row-activated",self.selectSong,"clicked",list)
treesel = tree.get_selection()
tree.show()
self.resizeCols(tree)
return tree,treesel
# Use to save column widths
def saveCols(self):
cols = self.ptree.get_columns()
self.data.colSizes = []
for col in cols:
self.data.colSizes +=[col.get_width()]
# Uses saved column settings
def resizeCols(self,tree):
cols = tree.get_columns()
for i in range(len(self.data.colSizes)):
cols[i].set_fixed_width(self.data.colSizes[i])
# Erase the entire list
def clearList(self,list,time):
max = len(list)
if max == 0:
return
if max > 0:
iter = list.get_iter(0)
for i in range(0,max):
list.remove(iter)
self.ptime = 0
self.setTabText("plist")
self.updatePTime()
# Update the playlist time label
def updatePTime(self):
page = self.get_current_page()
if page==0:
self.label.set_text(self.makeTimeLabel(self.ptime))
# Shows total running time of the playlist
def makeTimeLabel(self,sec):
day = 0
hour = 0
min = 0
day = sec/86500
sec = sec-(day*86500)
hour = sec/3600
sec = sec-(hour*3600)
min = sec/60
sec = sec-(min*60)
string = ""
string = self.toStr(day,"day")+self.toStr(hour,"hour")
string += self.toStr(min,"minute")+self.toStr(sec,"second")
return string
# Make a string for the amount of time
def toStr(self,time,label):
if time > 0:
string=str(time) + " "+label
if time > 1:
string+="s"
string += " "
return string
return ""
# User selected a song with mouse click
def selectSong(self,widgit,iter,path,data,list):
self.data.curSong = self.pfilter[iter][0]
self.loadSong(False)
self.controls.plause(None,None)
self.data.scrobbler.nowPlaying(self.data.library.files[self.data.curSong])
# Go to the next song in the list
def next(self,widgit,data):
self.data.playingQ = False
#print self.pfilter[0][1]
#print self.pfilter[1][1]
#print float(self.data.song.position)/float(self.data.song.info.duration)
if (float(self.data.song.position)/float(self.data.song.info.duration)) >= 0.75:
for row in self.plist:
if row[0]==self.data.curSong:
row[5]+=1
break
self.data.library.files[self.data.curSong].count+=1
#if self.plist[self.data.curSong][0]==self.data.curSong:
# self.plist[self.data.curSong][5]+=1
if len(self.data.curQ) > 0:
self.data.curSong = self.qlist[0][0]
self.data.curQ.pop(self.data.curQ.index(self.data.curSong))
self.qtime -= self.data.library.files[self.data.curSong].duration
self.changedTab(None,None,1)
self.qlist.remove(self.qlist.get_iter(0))
self.data.playingQ = True
self.setTabText("queue")
elif self.data.random == True:
self.data.curSong = self.pfilter[random.randint(0,len(self.pfilter)-1)][0]
else:
next = self.pfilter[0][0]
for i in range(len(self.pfilter)-1):
if self.pfilter[i][0]==self.data.curSong:
next = self.pfilter[i+1][0]
break
self.data.curSong = next
#if self.data.curSong >= len(self.data.curList):
# self.data.curSong = 0
self.loadSong(True)
pause = (self.status == PAFTER)
if pause == False:
self.controls.plause(None,None)
self.data.scrobbler.nowPlaying(self.data.library.files[self.data.curSong])
self.controls.changeImg()
self.status = CONTINUE
# Load a song and begin playback
def loadSong(self,scroll):
if len(self.data.curList) == 0:
return
if self.data.song:
self.data.scrobbler.submit(self.data.song.timestamp)
self.data.song.close()
self.data.song = Song(self.data.library.files[self.data.curSong],self.next)
self.info.changeLabels()
if scroll == True:
self.gotoCurSong()
# Scroll window and select row with current song
def gotoCurSong(self):
if len(self.pfilter) == 0:
return
for i in range(len(self.pfilter)):
if self.pfilter[i][0] == self.data.song.info.id:
if i > 10:
self.ptree.scroll_to_cell(i-10,None,True,0,0)
else:
self.ptree.scroll_to_cell(0,None,True,0,0)
self.ptree.set_cursor_on_cell(i,None,None,False)
# A callback to show the right click menu
def clicked(self,widget,data):
if data.button == 3:
self.prcmenu.popup(None,None,None,data.button,data.time)
# Called when songs are queued
def enqueue(self,widgit,func,data):
(model,pathlist) = self.ptreesel.get_selected_rows()
for path in pathlist:
q = self.pfilter[path]
self.data.curQ+=[q[0]]
self.qlist.append([q[0],q[1],q[2],q[3],q[4],q[5]])
self.qtime+=self.data.library.files[q[0]].duration
self.setTabText("queue")
# Update the total time label when a tab is changed
def changedTab(self,widgit,page,pagenum):
if pagenum == 0:
self.label.set_text(self.makeTimeLabel(self.ptime))
else:
self.label.set_text(self.makeTimeLabel(self.qtime))
def makeSearch(self):
self.searchBar = gtk.Entry()
self.searchBar.connect("changed",self.textTyped)
self.searchBar.show()
def textTyped(self,entry):
self.search = entry.get_text().lower()
self.pfilter.refilter()
self.gotoCurSong()
def hideRows(self,list,iter):
if self.search == "":
return True
elif len(self.search) == 1:
try:
self.data.library.files[list[iter][0]].single[self.search]
return True
except:
return False
elif len(self.search) == 2:
try:
self.data.library.files[list[iter][0]].double[self.search]
return True
except:
return False
file = self.data.library.files[list[iter][0]]
if re.search(self.search,file.titlel):
return True
elif re.search(self.search,file.artistl):
return True
elif re.search(self.search,file.albuml):
return True
return False