def dropEvent(self, e): print "DROP EVENT" data = e.mimeData() print data.formats() if data.hasFormat('bullseye/library.items'): dic = eval(str(data.data('bullseye/library.items'))) bdd = BDD() tracks = bdd.getTracks(dic) self.model.insert(tracks, self.rowAt(e.pos().y())) elif(data.hasFormat('bullseye/queue.items')): indexes = self.selectedIndexes() print indexes movedTracks = [] if len(indexes) > 0: targetedTrack = self.getTrackAt(self.rowAt(e.pos().y())) print targetedTrack first = indexes[0] last = indexes[-1] row = -1 for index in indexes: if(index.row() != row): track = self.getTrackAt(index) if(targetedTrack == track): return movedTracks.append(track) self.model.removeTrack(track) row = index.row() self.model.insertAfter(movedTracks, targetedTrack) QtGui.QTableView.dropEvent(self, e) elif data.hasUrls(): tracks = [] for url in data.urls(): path = url.toLocalFile() track = Track.fromPath(path) if track is not None: tracks.append(track) self.model.insert(tracks, self.rowAt(e.pos().y()))
class QueueManager(gtk.VBox): """ Cet objet correspond au manager de pistes à jouer, graphiquement c'est un NoteBook (onglets, etc...) TODO ponts (A -> B, B-> C), filtres TODO bouton stop = set stop track """ def __init__(self, playerWidget): #gtk.rc_parse_string("style \"ephy-tab-close-button-style\"\n" #"{\n" #"GtkWidget::focus-padding = 0\n" #"GtkWidget::focus-line-width = 0\n" #"xthickness = 0\n" #"ythickness = 0\n" #"}\n" #"widget \"*.ephy-tab-close-button\" style \"ephy-tab-close-button-style\"") gtk.VBox.__init__(self) self.NoteBook = gtk.Notebook() self.playerWidget = playerWidget self.playerWidget.queueManager = self #DEPRECATED Abonnement à certains types de messages auprès du messager #messager.inscrire(self.charger_playlist, 'playlist') messager.inscrire(self.ajouter_selection, 'desPistes') messager.inscrire(self.charger_playlist, 'playlistData') self.IM = icons.IconManager() self.queue_jouee = None self.playing_iter = None self.dest_row = None # On ajoute une liste pour commencer self.loadState() self.initialisation_raccourcis() glib.timeout_add_seconds(300, self.save_state) actionBox = gtk.HBox() scrollToCurrentButton = gtk.ToolButton(gtk.STOCK_JUMP_TO) scrollToCurrentButton.connect('clicked', self.scrollToCurrent) searchEntry = gtk.Entry() searchEntry.connect('activate', self.filter) actionBox.pack_start(scrollToCurrentButton, False) actionBox.pack_start(searchEntry) self.pack_start(self.NoteBook) self.pack_start(actionBox, False) self.NoteBook.connect('expose-event', self.redrawAddTabButton) self.NoteBook.connect('button-release-event', self.onButtonRelease) def addSelection(self, tracks): self.visibleQueue.addTracks(tracks) def getAddTabButtonPos(self): try: last_tab_label = self.NoteBook.get_tab_label(self.NoteBook.get_nth_page(self.NoteBook.get_n_pages() -1)) alloc = last_tab_label.get_allocation() except: print 'TODO' return (alloc.x + alloc.width + 10, alloc.y + 4) def onButtonRelease(self, widget, event): if(event.button == 1): x, y = self.getAddTabButtonPos() x_root, y_root = self.window.get_root_origin() x = x + x_root - 5 y = y + y_root + 16 if(event.x_root > x and event.x_root < x + 32 and event.y_root > y and event.y_root < y + 32): self.addQueue() def redrawAddTabButton(self, w, e): icon = gtk.Image().render_icon(gtk.STOCK_ADD, gtk.ICON_SIZE_MENU) #icon = gtk.gdk.pixbuf_new_from_file('icons/track.png') alloc = self.getAddTabButtonPos() self.window.draw_pixbuf(None, icon, 0, 0, alloc[0], alloc[1]) @property def visibleQueue(self): try: queue = self.NoteBook.get_nth_page(self.NoteBook.get_current_page()) except: queue = None return queue def ajouter_selection(self, selection): ''' Ajoute la séléction envoyée par le Panel à la queue visible @param selection : t de list content les informations des pistes à ajouter rappel de l'ordre: police, icon_playing, icon_stopping, ID, path, titre, album, artiste, length, count, pixbuf_note, note, bridge_src key ''' liste = self.visibleQueue try: iter_pos = liste.get_iter(self.dest_row[0]) pos_type = self.dest_row[1] except: iter_pos = None pos_type = None if liste != None: for track in selection: length = self.format_length(track[5]) rating= self.IM.rating_pixbufs[track[7]] if(pos_type == gtk.TREE_VIEW_DROP_BEFORE or pos_type == gtk.TREE_VIEW_DROP_INTO_OR_BEFORE): liste.insert_before(iter_pos, [None, None, None, track[0], track[1], track[2], track[3], track[4], length, track[6], rating, track[7], None] ) elif(pos_type == gtk.TREE_VIEW_DROP_AFTER or pos_type == gtk.TREE_VIEW_DROP_INTO_OR_AFTER): liste.insert_after(iter_pos, [None, None, None, track[0], track[1], track[2], track[3], track[4], length, track[6], rating, track[7], None] ) else: liste.append([None, None, None, track[0], track[1], track[2], track[3], track[4], length, track[6], rating, track[7], None] ) self.dest_row = None def addQueue(self, button=None, label=None): nb_pages = self.NoteBook.get_n_pages() if(label != None): #Cela veut dire qu'on a reçu une playlist du messager nouvelleQueue = Playlist(self, label) else: label = _("List ") + str(nb_pages) nouvelleQueue = Queue(self, label) self.NoteBook.set_current_page(nb_pages) return nouvelleQueue def avance_ou_arrete(self, motif): ''' Méthode primordiale permettant au MusicPlayer d'avoir sa piste sur demande (démarrage ou enchaînement) ''' # Tout d'abord on incrémente si fin de piste atteinte et on vire le marquage de l'ancienne piste courante if(motif == "eos"): #ID_courant = self.queue_jouee.get_value(self.playing_iter, 3) self.incrementPlayedTrack() self.demarquer_piste() try: if (self.queue_jouee.get_value(self.playing_iter, 2) is None): not_a_stop_track = True else: not_a_stop_track = False except: not_a_stop_track = True try: di = self.directList[0] self.directList.remove(di) if(di.row == None): di = None except IndexError: di = None if(not_a_stop_track): #On vérifie d'abord qu'on ne doit pas s'arrêter avant de mouliner #Quelle est la piste à jouer? 3 possibilités : if(di != None): # 1/ une piste prioritaire self.playing_track = Track(di.get_model()[di.get_path()][3]) if di.temp: self.temp_queue_jouee = di.get_model() self.temp_playing_iter = self.temp_queue_jouee.get_iter(di.get_path()) else: self.queue_jouee = di.get_model() self.playing_iter = self.queue_jouee.get_iter(di.get_path()) messager.diffuser('musique_a_lire', self, self.playing_track) self.marquer_piste() else: if(self.playing_iter): # 2/ la piste qui suit la dernière piste lue bridge_key = self.queue_jouee.get_value(self.playing_iter, 12) if(bridge_key != None): try: ref = self.bridges_dest[bridge_key] queue = ref.get_model() next_iter = queue.get_iter(ref.get_path()) self.queue_jouee = queue except: next_iter = self.queue_jouee.iter_next(self.playing_iter) else: next_iter = self.queue_jouee.iter_next(self.playing_iter) else: # 3/ la première piste de la queue visible self.queue_jouee = self.visibleQueue next_iter = self.queue_jouee.get_iter_first() if(next_iter): # Après recherche, on a obtenu une piste self.playing_iter = next_iter self.playing_track = Track(self.queue_jouee.get_value(self.playing_iter, 3)) messager.diffuser('musique_a_lire', self, self.playing_track) self.marquer_piste() else: # Il n'y a pas de suivant self.queue_jouee.set_value(self.playing_iter, 2, None) messager.diffuser('arret_musique', self, True) print("Liste de lecture terminée ou stoppée") else: # On s'arrête simplement self.queue_jouee.set_value(self.playing_iter, 2, None) messager.diffuser('arret_musique', self, True) print("Liste de lecture terminée ou stoppée") def charger_playlist(self, data): #data[0] = tracks ID, data[1] = playlist name queue = self.addQueue(data[1]) messager.diffuser('ID_playlist', self, [data[0], queue], False) def cleanDirectList(self): """ Remove all DirectIter that is no longer present """ for di in self.directList: if(di.queue.get_path(di.ligne) == None): self.directList.remove(di) def closeQueue(self, bouton=None, onglet=None): if(bouton == None): #La demande provient d'un raccourci clavier numero_page = self.NoteBook.get_current_page() else: numero_page = self.NoteBook.page_num(onglet) if(self.NoteBook.get_nth_page(numero_page).modified == True): dialog = gtk.Dialog(title=_("Closing non-saved playlist"), buttons=(gtk.STOCK_NO, gtk.RESPONSE_REJECT, gtk.STOCK_YES, gtk.RESPONSE_ACCEPT)) box = dialog.get_content_area() box.pack_start(gtk.Label(_("Save changes?")), False, 5, 5) box.show_all() reponse = dialog.run() dialog.destroy() if(reponse == -3): #Valider self.get_nth_page(numero_page).save() self.NoteBook.remove_page(numero_page) #Il n'y a plus d'onglet, on en crée un if(self.NoteBook.get_n_pages() == 0): self.addQueue() def filter(self, entry): def match(model, iter, word): value = model.get_value(iter, 5) print value return value.lower().find(word) != -1 entry.get_text() filterModel = self.visibleQueue.model.filter_new() filterModel.set_visible_func(match, entry.get_text()) self.visibleQueue.TreeView.set_model(filterModel) def getDefaultTrack(self): return self.visibleQueue.getTrackAt(0) def incrementPlayedTrack(self): self.playing_track.incrementPlayCount() try: compteur = self.temp_queue_jouee.get_value(self.temp_playing_iter, 9) self.temp_queue_jouee.set_value(self.temp_playing_iter, 9, compteur) except: compteur = self.queue_jouee.get_value(self.playing_iter, 9) + 1 self.queue_jouee.set_value(self.playing_iter, 9, compteur) def initialisation_raccourcis(self): raccourcis = ( ('<Control>W', lambda *e: self.closeQueue()), ('<Control>T', lambda *e: self.addQueue()), ) accel_group = gtk.AccelGroup() for key, function in raccourcis: key, mod = gtk.accelerator_parse(key) accel_group.connect_group(key, mod, gtk.ACCEL_VISIBLE, function) messager.diffuser('desRaccourcis', self, accel_group) @util.threaded def loadState(self): """ TODO Use one sql query by queue (using parametized IN clause) and thread this self.memcursor.execute('''SELECT id, matbefore, matafter, name, date FROM main WHERE name IN (%s)''' % ','.join('?'*len(offset)), (offset,)) """ bdd = BDD() queues = settings.get_option('session/queues', None) if(queues is not None): for key in queues.iterkeys(): if type(key).__name__=='int': self.addQueue() self.addSelection(bdd.getTracksFromIDs(queues[key])) else: playlist = self.addQueue(key) for track_id in queues[key]: self.addSelection(bdd.getTracks({'track_ID':track_id})) playlist.Liste.connect("row-changed", playlist.setModified) else: self.addQueue() #def marquer_piste(self):#Ajoute un marqueur (pour la piste courante de la liste jouée) #icon = gtk.gdk.pixbuf_new_from_file('icons/track.png') #try: #self.temp_queue_jouee.set_value(self.temp_playing_iter, 1, icon) #self.temp_queue_jouee.set_value(self.temp_playing_iter, 0, 'bold') #except: #self.queue_jouee.set_value(self.playing_iter, 1, icon) #self.queue_jouee.set_value(self.playing_iter, 0, 'bold') def recule(self, data): if self.numero > 0: self.demarquer_piste() self.numero -= 1 self.playing_iter = self.queue_jouee.get_iter(self.numero) chemin = self.queue_jouee[self.numero][4] messager.diffuser('musique_a_lire', self, chemin) self.marquer_piste() def save_state(self): i = 0 queues = {} while( i < self.NoteBook.get_n_pages()): t = [] queue = self.NoteBook.get_nth_page(i) model = queue.model iter = model.get_iter_first() while(iter is not None): t.append(model.get_value(iter, 3)) iter = model.iter_next(iter) if(type(queue).__name__=='Playlist'): queues[self.NoteBook.get_nth_page(i).tab_label.get_text()] = t else: queues[i] = t i += 1 settings.set_option('session/queues', queues) def scrollToCurrent(self, button=None): currentQueue, currentTrack = self.playerWidget.getCurrents() index = currentQueue.tracks.index(currentTrack) self.NoteBook.set_current_page(self.NoteBook.page_num(currentQueue)) currentQueue.TreeView.scroll_to_cell(index)
def avance_ou_arrete(self, motif): ''' Méthode primordiale permettant au MusicPlayer d'avoir sa piste sur demande (démarrage ou enchaînement) ''' # Tout d'abord on incrémente si fin de piste atteinte et on vire le marquage de l'ancienne piste courante if(motif == "eos"): #ID_courant = self.queue_jouee.get_value(self.playing_iter, 3) self.incrementPlayedTrack() self.demarquer_piste() try: if (self.queue_jouee.get_value(self.playing_iter, 2) is None): not_a_stop_track = True else: not_a_stop_track = False except: not_a_stop_track = True try: di = self.directList[0] self.directList.remove(di) if(di.row == None): di = None except IndexError: di = None if(not_a_stop_track): #On vérifie d'abord qu'on ne doit pas s'arrêter avant de mouliner #Quelle est la piste à jouer? 3 possibilités : if(di != None): # 1/ une piste prioritaire self.playing_track = Track(di.get_model()[di.get_path()][3]) if di.temp: self.temp_queue_jouee = di.get_model() self.temp_playing_iter = self.temp_queue_jouee.get_iter(di.get_path()) else: self.queue_jouee = di.get_model() self.playing_iter = self.queue_jouee.get_iter(di.get_path()) messager.diffuser('musique_a_lire', self, self.playing_track) self.marquer_piste() else: if(self.playing_iter): # 2/ la piste qui suit la dernière piste lue bridge_key = self.queue_jouee.get_value(self.playing_iter, 12) if(bridge_key != None): try: ref = self.bridges_dest[bridge_key] queue = ref.get_model() next_iter = queue.get_iter(ref.get_path()) self.queue_jouee = queue except: next_iter = self.queue_jouee.iter_next(self.playing_iter) else: next_iter = self.queue_jouee.iter_next(self.playing_iter) else: # 3/ la première piste de la queue visible self.queue_jouee = self.visibleQueue next_iter = self.queue_jouee.get_iter_first() if(next_iter): # Après recherche, on a obtenu une piste self.playing_iter = next_iter self.playing_track = Track(self.queue_jouee.get_value(self.playing_iter, 3)) messager.diffuser('musique_a_lire', self, self.playing_track) self.marquer_piste() else: # Il n'y a pas de suivant self.queue_jouee.set_value(self.playing_iter, 2, None) messager.diffuser('arret_musique', self, True) print("Liste de lecture terminée ou stoppée") else: # On s'arrête simplement self.queue_jouee.set_value(self.playing_iter, 2, None) messager.diffuser('arret_musique', self, True) print("Liste de lecture terminée ou stoppée")