Commits

Damián Nohales committed a97830c

Bug fixed while searching by song on a AbstractSongList with repeated songs (untested!!)

When I search a row by a Song object in an AbstractSongList, I made the search comparing the GrooveShark ID for the song (see Song.equals), I change this by assigning a unique local ID for all Song objects created, and when search for a song, the comparation is in the local ID.

Comments (0)

Files changed (5)

lib/AbstractSongList.py

     
     def range(self):
         return range(len(self.get_model()))
+    
+    def get_selected_rows(self):
+        self.get_view().get_selection().get_selected_rows()[1]
+        
         return gtk.ListStore(object, str, str, int, str, str)
     
     def __append_song_to_model(self, song):
+        # Change song local ID to fix the search by song
+        song = song.clone()
+        
         self.get_model().append([
             song,
             unicode(os.path.basename(song.get_filename()), errors = 'replace'),
     
 class PlayList (AbstractSongList):
     def __init__(self, view):
+        playing_song = None
         AbstractSongList.__init__(self, view)
     
     def create_model(self):
             return str
         
     def create_view(self):
+        self.get_view().set_selection_mode(gtk.SELECTION_MULTIPLE)
         self.get_view().set_reorderable(True)
         
         self.get_view().set_markup_column(1)
         self.get_view().set_tooltip_column(3)
         self.get_view().set_item_width(120);
         self.get_view().set_columns(999)
+        
+    def get_selected_rows(self):
+        return self.get_view().get_selected_items()
+    
+    def get_playing_song(self):
+        return self.playing_song
+    
+    def set_playing_song(self, song):
+        if song != None:
+            path = self.get_model().get_song_path(song)
+            self.get_view().scroll_to_path(path, False, 0, 0)
+            self.get_model()[2] = self.create_composited_image(self.get_model()[2])
+        else:
+            if self.playing_song != None:
+                self.get_song_row(self.playing_song)[2] = self.playing_song.get_cover_pixbuf() 
+        
+        self.playing_song = song
     
     def append_song(self, song):
+        # Change song local ID to fix the search by song
+        song = song.clone()
+        
         song_string = "<span>%s</span>\n<span fgcolor='#777777'>%s</span>" % (self.get_sliced_string(glib.markup_escape_text(song.get_title()), 25),
                                                                               self.get_sliced_string(glib.markup_escape_text(song.get_artist()), 20))
         #if len(song_string) > 14:
             song.download_cover()
             
     def on_song_cover_downloaded(self, song):
-        self.get_song_row(song)[2] = self.create_cornered_image(song.get_cover_pixbuf())
+        image = self.create_cornered_image(song.get_cover_pixbuf())
+        if song.equals(self.get_playing_song()) == True:
+            self.get_song_row(song)[2] = self.create_composited_image(image)
+        else:
+            self.get_song_row(song)[2] = image
         
     def create_loading_track_icon(self):
         default = gtk.gdk.pixbuf_new_from_file("%s/data/loading.png" % env().BASEPATH)
         corners.composite(pixbuf, 0, 0, pixbuf.props.width, pixbuf.props.height,
                           0, 0, 1.0, 1.0, gtk.gdk.INTERP_HYPER, 255)
         return pixbuf
+    
+    def create_composited_image(self, pixbuf):
+        play = gtk.gdk.pixbuf_new_from_file('%s/data/play.png' % env().BASEPATH)
+        play.composite(pixbuf, 0, 0, pixbuf.props.width, pixbuf.props.height,
+                          0, 0, 1.0, 1.0, gtk.gdk.INTERP_HYPER, 255)
 from DownloadList import DownloadList
 from Song import Song
 import guihelpers
-import urllib2
-import webbrowser
 import pickle
 import gtk
 import gst
         self.scrobbled = 0
         # Download dictionary in form Filename : Thread
         self.last_iter = None
+        self.windowstate = 1
+        self.current_song = None
         
         init_thread = InitThread(self)
         init_thread.start()
         builder.add_from_file('%s/data/main_window.ui' % env().BASEPATH)
         self.window = builder.get_object('mainwindow')
         self.window.connect('delete-event', self.on_window_close)
-        self.windowstate = 1
-        self.current_song = None
         self.play_button = builder.get_object('toolbutton_play')
         self.ff_button = builder.get_object('toolbutton_play_next')
         self.prev_button = builder.get_object('toolbutton_play_previous')
         
         self.window.set_sensitive(False)
         self.window.show_all()
+ 
         
     def on_init_thread_end(self):
         self.window.set_sensitive(True)
+        self.entry.set_text("metallica")
+        self.on_search_grooveshark(self.entry)
         if os.path.exists("%s/.gsharkdown/downqueue.pkl" % os.environ.get("HOME")):
             self.load_downqueue_list("%s/.gsharkdown/downqueue.pkl" % os.environ.get("HOME"))
 
-    def get_playing_iter(self):
-        iter = self.playlist.get_iter_first()
-        while iter != None:
-            if self.playlist[iter][5] > 400:
-                return iter
-            iter = self.playlist.iter_next(iter)
-
-        return None
 
     def get_iter_last(self, model):
         """
         """
         Removes an item from the playlist and the playitems list
         """
-        select = self.playlist.get_view().get_selected_items()
-        selectiter = self.playlist.get_model().get_iter(select[0])
-        if selectiter != None:
-            next = self.playlist.get_model().iter_next(selectiter)
-            self.playlist.get_model().remove(selectiter)
-            if selectiter == self.get_playing_iter():
-                self.stop_play()
-            if next != None:
-                self.playlist.get_view().select_path((select[0][0] + 1,))
+        selection = self.playlist.get_selected_rows()
+        if len(selection) > 0:
+            for i in selection:
+                self.playlist.get_model().remove( self.playlist.get_model().get_iter(i) )
+                
+            if len(self.playlist) > 0:
+                select_path = selection[len(selection) - 1]
+                if select_path[0] >= len(self.playlist):
+                    select_path = (select_path[0]-1,)
+                self.playlist.get_view().select_path(select_path)
+        
+        
+#        select = self.playlist.get_view().get_selected_items()
+#        if selectiter != None:
+#            next = self.playlist.get_model().iter_next(selectiter)
+#            self.playlist.get_model().remove(selectiter)
+#            if selectiter == self.get_playing_iter():
+#                self.stop_play()
+#            if next != None:
+#                self.playlist.get_view().select_path((select[0][0] + 1,))
 
     def on_clear_playlist(self, widget, data = None):
         """
         Removes all items from the playlist
         """
-        if self.last_iter != None:
+        if self.get_current_song() != None:
             self.stop_play()
         self.playlist.clear()
 
         On double click in the search treeview the item is added to 
         the playlist and starts playling.
         """
-        song = self.result_song(column[0])
-        self.add_song_to_playlist(song)
+        song = self.result.get_song(column[0])
+        self.playlist.append_song(song)
 
     def play_next(self, widget, data = None):
         """
         """
         Starts the play thread
         """
-        if self.get_playing_iter() == None:
-            if self.playlist.iter_n_children(None) > 0:
-                self.play_by_index(0)
+        if self.get_playing_song() == None:
+            if len(self.playlist):
+                self.set_playing_song(self.playlist.get_song(0))
         else:
-            self.stop_play()
-
-    def set_songinfos(self, song = None):
+            self.set_playing_song(None)
+            
+    def get_playing_iter(self):
+        return self.playlist.get_song_iter(self.get_playing_song())
+    
+    def get_playing_song(self):
+        return self.playlist.get_playing_song()
+        
+    def set_playing_song(self, song):
         """
         Updates some labels and icons when a song is playing
         """
+        self.playlist.set_playing_song(song)
+        
         if song != None:
-            if self.last_iter == None:
-                pass
-            else:
-                name = self.playlist.get_value(self.last_iter, 1)
-                self.playlist.set(self.last_iter, 1,
-                                  self.create_cornered_image(self.recover_icon(
-                                                    self.get_current_cover_url(name))))
-            playing = self.get_playing_iter()
-            if playing == None:
-                playing = self.playlist.get_iter_first()
-            path = self.playlist.get_path(playing)
-            self.play_view.scroll_to_path(path, False, 0, 0)
-            self.last_iter = playing
-            self.current_song = song
             self.staticon.change_status_playing()
-            image = gtk.Image()
-            image.set_from_stock(gtk.STOCK_MEDIA_STOP, gtk.ICON_SIZE_MENU)
-            self.staticon.change_playbutton(image)
+            
+            play_stop_image = gtk.Image()
+            play_stop_image.set_from_stock(gtk.STOCK_MEDIA_STOP, gtk.ICON_SIZE_MENU)
+            self.staticon.change_playbutton(play_stop_image)
 
-            image1 = self.playlist.get_value(playing, 1)
-            play = gtk.gdk.pixbuf_new_from_file('%s/data/play.png' % env().BASEPATH)
-            play.composite(image1, 0, 0, image1.props.width, image1.props.height,
-                              0, 0, 1.0, 1.0, gtk.gdk.INTERP_HYPER, 255)
-            self.playlist.set(playing, 1, image1)
             self.songinfo.set_markup(
-                _("<b>Playing:</b> {artist} - {title}").format(artist = glib.markup_escape_text(self.current_song['ArtistName']),
-                                         title = glib.markup_escape_text(self.current_song['SongName']))
+                _("<b>Playing:</b> {artist} - {title}").format(artist = glib.markup_escape_text(song.get_artist()),
+                                         title = glib.markup_escape_text(song.get_title()))
             )
             if int(config()['show_notification']) == 1:
                 n = pynotify.Notification(_("Now playing"),
-                    "%s - %s" % (glib.markup_escape_text(song['ArtistName']),
-                                 glib.markup_escape_text(song['SongName'])),
+                    "%s - %s" % (glib.markup_escape_text(song.get_artist()),
+                                 glib.markup_escape_text(song.get_title())),
                     "audio-x-generic")
                 n.set_timeout(50)
                 n.show()
         else:
             self.staticon.change_status_stopped()
-            image = gtk.Image()
-            name = self.playlist.get_value(self.last_iter, 1)
-            self.playlist.set(self.last_iter, 1,
-                              self.create_cornered_image(self.recover_icon(
-                                                    self.get_current_cover_url(name))))
-            image.set_from_stock(gtk.STOCK_MEDIA_PLAY, gtk.ICON_SIZE_MENU)
-            self.staticon.change_playbutton(image)
+            play_stop_image = gtk.Image()
+            play_stop_image.set_from_stock(gtk.STOCK_MEDIA_PLAY, gtk.ICON_SIZE_MENU)
+            self.staticon.change_playbutton(play_stop_image)
             self.songinfo.set_markup("")
 
     def get_overwritten_filename(self, filename):
         u'ArtistName': u'Viejas Locas'
     }
     """
+    last_song_local_id = 0
+    
     def __init__(self, data):
         self.__gobject_init__()
+        Song.last_song_local_id += 1
+        
+        self.local_id = Song.last_song_local_id
         self.data = data
         self.cover_pixbuf = None
         self.download_progress = None
     def __getitem__(self, key):
         return self.data[key]
     
+    def clone(self):
+        """
+        Clone the song but changes it local ID to avoid errors during the song searching
+        on AbstractSongList
+        """
+        newsong = Song(self.get_data())
+        newsong.set_cover_pixbuf(self.get_cover_pixbuf())
+        newsong.set_filename(self.get_filename())
+        
+        return newsong
+    
     def equals(self, othersong):
-        return self.get_id() == othersong.get_id();
+        return self.local_id == othersong.local_id
     
     def get_data(self):
         return self.data