1 #!/usr/bin/env python2.5
4 from mutagen_backend import MutagenBackend
5 from player_backend import MediaPlayer
7 from album_art import MussorgskyAlbumArt
10 # Fields in the tuple!
17 class MussorgskyEditPanel (hildon.StackableWindow):
19 def __init__ (self, songs_list=None, albums_list=None, artists_list=None):
20 hildon.StackableWindow.__init__ (self)
21 self.set_title ("Edit")
22 self.set_border_width (12)
24 self.album_callback_id = -1
25 self.album_change_handler = -1
26 self.writer = MutagenBackend ()
27 self.player = MediaPlayer ()
28 self.album_art_retriever = MussorgskyAlbumArt ()
29 self.albums_list = [a [0] for a in albums_list]
30 self.artists_list = [a [0] for a in artists_list]
31 self.add (self.__create_view ())
33 self.set_songs_list (songs_list)
37 def set_songs_list (self, songs_list):
38 if (songs_list and len (songs_list) > 0):
39 self.songs_list = songs_list
40 self.set_data_in_view (songs_list [0])
43 def press_back_cb (self, widget):
44 if (self.player.is_playing ()):
47 if (self.banner and self.banner.get_property("visible")):
48 self.banner.destroy ()
50 if (self.album_callback_id != -1):
51 gobject.source_remove (self.album_callback_id)
52 self.album_callback_id = -1
54 if self.__is_view_dirty ():
55 print "Modified data. Save!"
58 if (self.song_counter > 0):
59 self.song_counter -= 1
60 self.set_data_in_view (self.songs_list [self.song_counter])
62 def press_next_cb (self, widget):
63 if (self.player.is_playing ()):
66 if (self.banner and self.banner.get_property("visible")):
67 self.banner.destroy ()
69 if (self.album_callback_id != -1):
70 gobject.source_remove (self.album_callback_id)
71 self.album_callback_id = -1
73 if self.__is_view_dirty ():
74 print "Modified data. Save!"
77 if (self.song_counter < len (self.songs_list) -1):
78 self.song_counter += 1
79 self.set_data_in_view (self.songs_list [self.song_counter])
83 def save_metadata (self):
84 # Save the data in the online model to show the appropiate data
85 # in the UI while tracker process the update.
86 song = self.songs_list [self.song_counter]
88 new_song = (song[FILE_URI], song[1],
89 self.artist_button.get_value (),
90 self.title_entry.get_text (),
91 self.album_button.get_value (),
93 self.songs_list [self.song_counter] = new_song
95 self.writer.save_metadata_on_file (new_song[FILE_URI],
97 self.artist_button.get_value (),
98 self.title_entry.get_text (),
99 self.album_button.get_value ())
101 # This error in case of tracker returning unexistent files.
102 # Uhm.... for instance after removing a memory card we are editing!
103 dialog = gtk.MessageDialog (self,
104 gtk.DIALOG_DESTROY_WITH_PARENT,
112 def __is_view_dirty (self):
114 True if the data has been modified in the widgets
116 song = self.songs_list [self.song_counter]
118 return not (self.filename_data.get_text() == song[FILE_URI] and
119 self.artist_button.get_value () == song[ARTIST_KEY] and
120 self.title_entry.get_text () == song[TITLE_KEY] and
121 self.album_button.get_value () == song[ALBUM_KEY] )
124 def __create_view (self):
125 view_vbox = gtk.VBox (homogeneous=False, spacing = 12)
127 filename_row = gtk.HBox ()
128 filename_label = gtk.Label ("Filename:")
129 filename_row.pack_start (filename_label, expand=False, padding=12);
130 self.filename_data = gtk.Label ("")
131 filename_row.pack_start (self.filename_data, expand=True)
133 play_button = hildon.Button (hildon.BUTTON_STYLE_NORMAL, hildon.BUTTON_ARRANGEMENT_HORIZONTAL)
134 img = gtk.image_new_from_stock (gtk.STOCK_MEDIA_PLAY, gtk.ICON_SIZE_BUTTON)
135 play_button.set_image (img)
136 play_button.connect ("clicked", self.clicked_play)
137 filename_row.pack_start (play_button, expand=False, fill=False)
138 view_vbox.pack_start (filename_row, expand=False);
140 central_panel = gtk.HBox (spacing=12)
142 table = gtk.Table (3, 2, False)
143 table.set_col_spacings (12)
144 table.set_row_spacings (12)
146 central_panel.pack_start (table, fill=True)
147 view_vbox.pack_start (central_panel, expand=True, fill=True)
150 label_title = gtk.Label ("Title:")
151 table.attach (label_title, 0, 1, 0, 1, 0)
152 self.title_entry = gtk.Entry()
153 table.attach (self.title_entry, 1, 2, 0, 1)
156 artist_selector = hildon.hildon_touch_selector_entry_new_text ()
157 for a in self.artists_list:
158 artist_selector.append_text (a)
159 self.artist_button = hildon.PickerButton (hildon.BUTTON_STYLE_NORMAL,
160 hildon.BUTTON_ARRANGEMENT_HORIZONTAL)
161 self.artist_button.set_title ("Artist: ")
162 self.artist_button.set_selector (artist_selector)
163 table.attach (self.artist_button, 0, 2, 1, 2)
167 album_selector = hildon.hildon_touch_selector_entry_new_text ()
168 for a in self.albums_list:
169 album_selector.append_text (a)
170 self.album_button = hildon.PickerButton (hildon.BUTTON_STYLE_NORMAL,
171 hildon.BUTTON_ARRANGEMENT_HORIZONTAL)
172 self.album_button.set_title ("Album: ")
173 self.album_button.set_selector (album_selector)
174 table.attach (self.album_button, 0, 2, 2, 3)
178 album_art_button = gtk.Button ()
179 self.album_art = gtk.Image ()
180 self.album_art.set_size_request (124, 124)
181 album_art_button.add (self.album_art)
182 album_art_button.connect ("clicked", self.clicked_album_art)
183 central_panel.pack_start (album_art_button, expand=False, fill=False)
186 button_box = gtk.HButtonBox ()
187 button_box.set_layout (gtk.BUTTONBOX_END)
189 back_button = hildon.Button (hildon.BUTTON_STYLE_NORMAL, hildon.BUTTON_ARRANGEMENT_HORIZONTAL)
190 img = gtk.image_new_from_stock (gtk.STOCK_GO_BACK, gtk.ICON_SIZE_BUTTON)
191 back_button.set_image (img)
192 back_button.connect ("clicked", self.press_back_cb)
193 button_box.pack_start (back_button, expand=True, fill=True, padding=6)
195 next_button = hildon.Button (hildon.BUTTON_STYLE_NORMAL, hildon.BUTTON_ARRANGEMENT_HORIZONTAL)
196 img = gtk.image_new_from_stock (gtk.STOCK_GO_FORWARD, gtk.ICON_SIZE_BUTTON)
197 next_button.set_image (img)
198 next_button.connect ("clicked", self.press_next_cb)
199 button_box.pack_start (next_button, expand=True, fill=True, padding=6)
201 view_vbox.pack_start (button_box, expand=False, fill=True, padding=6)
206 def set_data_in_view (self, song):
208 Place in the screen the song information.
209 Song is a tuple like (filename, 'Music', title, artist, album, mime)
211 assert len (song) == 6
213 self.filename_data.set_text (song[FILE_URI])
214 self.title_entry.set_text (song[TITLE_KEY])
217 self.artist_button.set_active (self.artists_list.index(song[ARTIST_KEY]))
219 print "'%s' not in artist list!?" % (song[ARTIST_KEY])
221 # Disconnect the value-change signal to avoid extra album art retrievals
222 if (self.album_change_handler != -1):
223 self.album_button.disconnect (self.album_change_handler)
224 self.album_change_handle = -1
227 self.album_button.set_active (self.albums_list.index (song[ALBUM_KEY]))
229 print "'%s' is not in the album list!?" % (song[ALBUM_KEY])
231 # Reconnect the signal!
232 self.album_change_handler = self.album_button.connect ("value-changed",
233 self.album_selection_cb)
235 # Set the album art given the current data
237 if (song[ALBUM_KEY]):
238 thumb = album_art_spec.getCoverArtThumbFileName (song[ALBUM_KEY])
239 print "%s -> %s" % (song[ALBUM_KEY], thumb)
240 if (os.path.exists (thumb)):
241 self.album_art.set_from_file (thumb)
244 self.album_callback_id = gobject.idle_add (self.retrieve_album_art,
245 song[ARTIST_KEY], song[ALBUM_KEY])
248 self.album_art.set_from_stock (gtk.STOCK_CDROM, gtk.ICON_SIZE_DIALOG)
250 if (not song[MIME_KEY] in self.writer.get_supported_mimes ()):
251 print "show notification"
252 self.banner = hildon.Banner ()
253 self.banner.set_text ("Unsupported format (%s)" % song[MIME_KEY])
254 self.banner.show_all ()
256 def retrieve_album_art (self, artist, album):
257 print "trying to get the album art"
258 (img, thumb) = self.album_art_retriever.get_album_art (artist, album)
260 self.album_art.set_from_file (thumb)
262 print "Unable to retrieve album art"
266 def clicked_play (self, widget):
267 if (self.player.is_playing ()):
270 song = self.songs_list [self.song_counter]
271 self.player.play ("file://" + song[FILE_URI])
273 def clicked_album_art (self, widget):
274 print "implement me, please"
276 def album_selection_cb (self, widget):
277 song = self.songs_list [self.song_counter]
278 self.retrieve_album_art (song[ARTIST_KEY], widget.get_value ())
281 if __name__ == "__main__":
283 TEST_DATA = [("/a/b/c/d.mp3", "Music", "", "title", "Album 9", "audio/mpeg"),
284 ("/home/user/mufix/a.mp3", "Music", "", "title", "Album 2", "a/b"),
285 ("/media/mmc1/Attachments/b.m4a", "Music", "", "b", "Album 9", "audio/mpeg"),
286 ("/home/user/mufix/3.mp2", "Music", "", "titlex", "Album 3", "audio/mpeg")]
288 ALBUMS = [["Album %d" % i] for i in range (0, 10)]
289 ARTISTS = [["Artist %d" % i] for i in range (0, 10)]
290 window = MussorgskyEditPanel (TEST_DATA, ALBUMS, ARTISTS)
291 window.connect ("destroy", gtk.main_quit)