import gtk import re from menuItem import MenuItem from song import Song class List(gtk.ScrolledWindow): def __init__(self, data, text, funcs):#(nextFunc,labelFunc,plauseFunc,albumArtFunc) ): gtk.ScrolledWindow.__init__(self) self.show() self.set_policy(gtk.POLICY_AUTOMATIC,gtk.POLICY_AUTOMATIC) self.text = text self.data = data # Function pointers...whoo... #self.next = nextFunc #self.labels = labelFunc #self.plause = plauseFunc #self.setAlbumArt = albumArtFunc self.next = funcs[0] self.labels = funcs[1] self.plause = funcs[2] self.setAlbumArt = funcs[3] self.count = 0 self.seconds = 0 self.populated = False self.makeList() self.label = gtk.Label() self.makeLabel() self.align = gtk.Alignment(1,0,0,0) self.timeLabel = gtk.Label("") self.timeLabel.show() self.align.add(self.timeLabel) self.timeText() self.string = "" self.search = [] self.filter = self.list.filter_new() self.filter.set_visible_func(self.hideRows,"") self.sort = gtk.TreeModelSort(self.filter) self.tree.set_model(self.sort) def makeList(self): self.list = gtk.ListStore(int,str,str,str,str,int) self.tree = gtk.TreeView(self.list) self.tree.set_reorderable(True) cell = gtk.CellRendererText() cols = ["Id","Title","Length","Artist","Album","#"] 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": self.tree.append_column(col) self.tree.set_rules_hint(True) self.tree.connect("row-activated",self.selectSong,"clicked",list) self.tree.connect("button_release_event",self.clicked) self.sel = self.tree.get_selection() self.sel.set_mode(gtk.SELECTION_MULTIPLE) self.list.set_sort_column_id(self.data.sortedCol,gtk.SORT_ASCENDING) self.cols = self.tree.get_columns() self.loadCols() #self.tree.show() self.add(self.tree) # Select a song by double clicking on its row def selectSong(self,widgit,iter,path,data,list): self.loadSong(self.data.library.files[self.sort[iter][0]]) #self.gotoCurSong() self.plause(None,None) self.data.scrobbler.nowPlaying(self.data.song.info) # Opens a menu on a right click def clicked(self,widgit,data): if data.button == 3: end = self.tree.get_path_at_pos(int(data.x),int(data.y)) # end will be None if no rows are selected. if end != None: end = end[0][0] begin = self.sel.get_selected_rows()[1][0][0] self.sel.select_range(int(begin),int(end)) self.rcmenu.popup(None,None,None,data.button,data.time) # Add a row to the list def insert(self,file): self.list.insert(self.count,[file.id,file.title,file.length,file.artist,file.album,file.count]) self.count+=1 self.seconds+=file.duration def makeLabel(self): #print self.count, self.text self.label.set_text(self.text+" ("+str(self.count)+")") def timeText(self): day = 0 hour = 0 min = 0 sec = self.seconds 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") self.timeLabel.set_text(string) def toStr(self,time,label): if time > 0: string = str(time) + " " + label if time > 1: string+="s" string+=" " return string return "" def drop(self): if len(self.list) == 0: return iter = self.list.get_iter(0) while iter: if self.remove(iter) == False: self.makeLabel() self.timeText() return def remove(self,iter): self.count -= 1 self.seconds -= self.data.library.files[self.list[iter][0]].duration return self.list.remove(iter) def filterRows(self,string): self.string = string self.formatSearch(self.string) self.seconds = 0 self.count = 0 self.filter.refilter() self.count = len(self.filter) for i in range(self.count): self.seconds+=self.data.library.files[self.filter[i][0]].duration self.gotoCurSong() self.makeLabel() self.timeText() def filterQuick(self,list,string): self.count = 0 self.seconds = 0 self.string = string self.formatSearch(self.string) for file in list: if self.hideRows(None,file,string) == True: self.count+=1 self.seconds+=file.duration self.makeLabel() def formatSearch(self,string): self.search = [] split = string.split(",") for line in split: line = line.strip() if len(line) > 0: self.search+=[line.split()] # Returns true if the row is visible # False otherwise def hideRows(self,list,iter,string): #return True if list: file = self.data.library.files[list[iter][0]] else: file = iter #if self.string == "": # return True if len(self.search) == 0: return True #print self.search for terms in self.search: foundAll = True for substr in terms: foundSS = False if re.search(substr,file.titlel): foundSS = True elif re.search(substr,file.artistl): foundSS = True elif re.search(substr,file.albuml): foundSS = True if foundSS == False: foundAll = False if foundAll == True: return True #if re.search(term,file.titlel): # return True #elif re.search(term,file.artistl): # return True #elif re.search(term,file.albuml): # return True return False def makeRCMenu(self): self.rcmenu = gtk.Menu() rm = MenuItem("Remove from "+self.text.lower(),self.rm,None,None,None) self.rcmenu.append(rm) def rm(self,widgit,func,data): #print widgit,data,selection print "remove" def selection(self,func): (model,pathlist) = self.sel.get_selected_rows() for path in pathlist: func(self.data.library.files[model[path[0]][0]]) self.sel.unselect_path(path) # Prepare the next song for playing def loadSong(self,file): if self.data.song: self.data.scrobbler.submit(self.data.song.timestamp) self.data.song.close() self.data.song = Song(file,self.next) self.data.curSong = file.id self.gotoCurSong() self.setAlbumArt(file.filename) self.labels() #self.gotoCurSong() # Scroll the window and select the row def gotoCurSong(self): if len(self.filter) == 0: return # self.sort will be filtered, and it will have rows in the correct order for i in range(len(self.sort)): if self.sort[i][0] == self.data.curSong: if i > 10: self.tree.scroll_to_cell(i-10,None,True,0,0) else: self.tree.scroll_to_cell(0,None,True,0,0) self.tree.set_cursor_on_cell(i,None,None,False) return def visible(self,func): if func=="show": self.loadCols() self.align.show() self.tree.show() self.gotoCurSong() else: self.storeCols() self.align.hide() self.tree.hide() # Store the columns into an array in self.data def storeCols(self): for i in range(len(self.cols)): self.data.colSizes[i] = self.cols[i].get_width() # Load columns from self.data def loadCols(self): for i in range(len(self.cols)): width = self.data.colSizes[i] # Column widths are too small, set an initial width here if width <= 0: if i==0: width = 200 else: width = 110 self.cols[i].set_fixed_width(width) # Called after populating the list def populate(self): self.populated = True self.makeLabel() self.timeText()