1 #!/usr/bin/env python2.5
4 from mutagen_backend import MutagenBackend
5 from player_backend import MediaPlayer
16 class MussorgskyEditPanel (hildon.StackableWindow):
18 def __init__ (self, songs_list=None, albums_list=None, artists_list=None):
19 hildon.StackableWindow.__init__ (self)
20 self.set_border_width (12)
22 self.album_callback_id = -1
23 self.album_change_handler = -1
24 self.artist_change_handler = -1
25 self.writer = MutagenBackend ()
26 self.player = MediaPlayer ()
27 self.albums_list = [a [0] for a in albums_list]
28 self.artists_list = [a [0] for a in artists_list]
31 self.set_songs_list (songs_list)
36 def update_title (self):
37 self.set_title ("Edit (%d/%d)" % (self.song_counter+1, len (self.songs_list)))
40 def set_songs_list (self, songs_list):
41 if (songs_list and len (songs_list) > 0):
42 self.songs_list = songs_list
43 self.set_data_in_view (songs_list [0])
46 def press_back_cb (self, widget):
47 if (self.player.is_playing ()):
50 if (self.banner and self.banner.get_property("visible")):
51 self.banner.destroy ()
53 if (self.album_callback_id != -1):
54 gobject.source_remove (self.album_callback_id)
55 self.album_callback_id = -1
57 if self.__is_view_dirty ():
58 print "Modified data. Save!"
61 if (self.song_counter > 0):
62 self.song_counter -= 1
63 self.set_data_in_view (self.songs_list [self.song_counter])
68 def press_next_cb (self, widget):
69 if (self.player.is_playing ()):
72 if (self.banner and self.banner.get_property("visible")):
73 self.banner.destroy ()
75 if (self.album_callback_id != -1):
76 gobject.source_remove (self.album_callback_id)
77 self.album_callback_id = -1
79 if self.__is_view_dirty ():
80 print "Modified data. Save!"
83 if (self.song_counter < len (self.songs_list) -1):
84 self.song_counter += 1
85 self.set_data_in_view (self.songs_list [self.song_counter])
90 def save_metadata (self):
91 # Save the data in the online model to show the appropiate data
92 # in the UI while tracker process the update.
93 song = self.songs_list [self.song_counter]
95 new_song = (song[FILE_URI], song[1],
96 self.artist_button.get_value (),
97 self.title_entry.get_text (),
98 self.album_button.get_value (),
100 self.songs_list [self.song_counter] = new_song
102 self.writer.save_metadata_on_file (new_song[FILE_URI],
104 self.artist_button.get_value (),
105 self.title_entry.get_text (),
106 self.album_button.get_value ())
108 # This error in case of tracker returning unexistent files.
109 # Uhm.... for instance after removing a memory card we are editing!
110 dialog = gtk.MessageDialog (self,
111 gtk.DIALOG_DESTROY_WITH_PARENT,
119 def __is_view_dirty (self):
121 True if the data has been modified in the widgets
123 song = self.songs_list [self.song_counter]
125 return not (self.filename_data.get_text() == song[FILE_URI] and
126 self.artist_button.get_value () == song[ARTIST_KEY] and
127 self.title_entry.get_text () == song[TITLE_KEY] and
128 self.album_button.get_value () == song[ALBUM_KEY] )
131 def __create_view (self):
132 view_vbox = gtk.VBox (homogeneous=False, spacing = 12)
134 filename_row = gtk.HBox ()
135 filename_label = gtk.Label ("Filename:")
136 filename_row.pack_start (filename_label, expand=False, padding=12);
137 self.filename_data = gtk.Label ("")
138 filename_row.pack_start (self.filename_data, expand=True)
140 play_button = hildon.Button (hildon.BUTTON_STYLE_NORMAL, hildon.BUTTON_ARRANGEMENT_HORIZONTAL)
141 img = gtk.image_new_from_stock (gtk.STOCK_MEDIA_PLAY, gtk.ICON_SIZE_BUTTON)
142 play_button.set_image (img)
143 play_button.connect ("clicked", self.clicked_play)
144 filename_row.pack_start (play_button, expand=False, fill=False)
145 view_vbox.pack_start (filename_row, expand=False);
147 central_panel = gtk.HBox (spacing=12)
149 table = gtk.Table (3, 2, False)
150 table.set_col_spacings (12)
151 table.set_row_spacings (12)
153 central_panel.pack_start (table, fill=True)
154 view_vbox.pack_start (central_panel, expand=True, fill=True)
157 label_title = gtk.Label ("Title:")
158 table.attach (label_title, 0, 1, 0, 1, 0)
159 self.title_entry = gtk.Entry()
160 table.attach (self.title_entry, 1, 2, 0, 1)
163 artist_selector = hildon.TouchSelectorEntry (text=True)
164 for a in self.artists_list:
165 artist_selector.append_text (a)
166 self.artist_button = hildon.PickerButton (hildon.BUTTON_STYLE_NORMAL,
167 hildon.BUTTON_ARRANGEMENT_HORIZONTAL)
168 self.artist_button.set_title ("Artist: ")
169 self.artist_button.set_selector (artist_selector)
170 table.attach (self.artist_button, 0, 2, 1, 2)
174 album_selector = hildon.TouchSelectorEntry (text=True)
175 for a in self.albums_list:
176 album_selector.append_text (a)
177 self.album_button = hildon.PickerButton (hildon.BUTTON_STYLE_NORMAL,
178 hildon.BUTTON_ARRANGEMENT_HORIZONTAL)
179 self.album_button.set_title ("Album: ")
180 self.album_button.set_selector (album_selector)
181 table.attach (self.album_button, 0, 2, 2, 3)
185 album_art_button = gtk.Button ()
186 self.album_art = gtk.Image ()
187 self.album_art.set_size_request (124, 124)
188 album_art_button.add (self.album_art)
189 album_art_button.connect ("clicked", self.clicked_album_art)
190 central_panel.pack_start (album_art_button, expand=False, fill=False)
193 button_box = gtk.HButtonBox ()
194 button_box.set_layout (gtk.BUTTONBOX_END)
196 back_button = hildon.Button (hildon.BUTTON_STYLE_NORMAL, hildon.BUTTON_ARRANGEMENT_HORIZONTAL)
197 img = gtk.image_new_from_stock (gtk.STOCK_GO_BACK, gtk.ICON_SIZE_BUTTON)
198 back_button.set_image (img)
199 back_button.connect ("clicked", self.press_back_cb)
200 button_box.pack_start (back_button, expand=True, fill=True, padding=6)
202 next_button = hildon.Button (hildon.BUTTON_STYLE_NORMAL, hildon.BUTTON_ARRANGEMENT_HORIZONTAL)
203 img = gtk.image_new_from_stock (gtk.STOCK_GO_FORWARD, gtk.ICON_SIZE_BUTTON)
204 next_button.set_image (img)
205 next_button.connect ("clicked", self.press_next_cb)
206 button_box.pack_start (next_button, expand=True, fill=True, padding=6)
208 view_vbox.pack_start (button_box, expand=False, fill=True, padding=6)
212 #menu = hildon.AppMenu ()
213 #go_to = hildon.Button (hildon.BUTTON_STYLE_NORMAL,
214 # hildon.BUTTON_ARRANGEMENT_HORIZONTAL)
215 #go_to.set_title ("Go to")
216 #go_to.connect ("clicked", self.go_to_cb)
219 #self.set_app_menu (menu)
222 def go_to_cb (self, widget):
225 def set_data_in_view (self, song):
227 Place in the screen the song information.
228 Song is a tuple like (filename, 'Music', title, artist, album, mime)
230 assert len (song) == 6
232 self.filename_data.set_text (song[FILE_URI])
233 self.title_entry.set_text (song[TITLE_KEY])
236 # Disconnect the value-change signal to avoid extra album art retrievals
237 if (self.album_button.handler_is_connected (self.album_change_handler)):
238 self.album_button.disconnect (self.album_change_handler)
240 if (self.artist_button.handler_is_connected (self.artist_change_handler)):
241 self.artist_button.disconnect (self.artist_change_handler)
243 # Set values in the picker buttons
245 self.artist_button.set_active (self.artists_list.index(song[ARTIST_KEY]))
247 print "'%s' not in artist list!?" % (song[ARTIST_KEY])
248 self.artist_button.set_value ("")
251 self.album_button.set_active (self.albums_list.index (song[ALBUM_KEY]))
253 print "'%s' is not in the album list!?" % (song[ALBUM_KEY])
254 self.album_button.set_value ("")
256 # Reconnect the signals!
257 self.album_change_handler = self.album_button.connect ("value-changed",
258 self.album_selection_cb)
260 self.artist_change_handler = self.artist_button.connect ("value-changed",
261 self.artist_selection_cb)
263 # Set the album art given the current data
265 if (song[ALBUM_KEY]):
266 thumb = album_art_spec.getCoverArtThumbFileName (song[ALBUM_KEY])
267 print "%s -> %s" % (song[ALBUM_KEY], thumb)
268 if (os.path.exists (thumb)):
269 self.album_art.set_from_file (thumb)
272 self.album_callback_id = gobject.idle_add (self.retrieve_album_art,
273 song[ARTIST_KEY], song[ALBUM_KEY])
276 self.album_art.set_from_stock (gtk.STOCK_CDROM, gtk.ICON_SIZE_DIALOG)
278 if (not song[MIME_KEY] in self.writer.get_supported_mimes ()):
279 print "show notification"
280 self.banner = hildon.Banner ()
281 self.banner.set_text ("Unsupported format (%s)" % song[MIME_KEY])
282 self.banner.show_all ()
284 def retrieve_album_art (self, artist, album):
285 print "trying to get the album art"
286 (img, thumb) = self.album_art_retriever.get_album_art (artist, album)
288 self.album_art.set_from_file (thumb)
290 print "Unable to retrieve album art"
294 def clicked_play (self, widget):
295 if (self.player.is_playing ()):
298 song = self.songs_list [self.song_counter]
299 self.player.play ("file://" + song[FILE_URI])
301 def clicked_album_art (self, widget):
302 print "implement me, please"
304 def album_selection_cb (self, widget):
306 On album change, add the album the local list of albums and the selector
307 if it doesn't exist already. So we show the new entry in the selector next time.
309 song = self.songs_list [self.song_counter]
310 if (not widget.get_value () in self.albums_list):
311 print "Inserting ", widget.get_value ()
312 widget.get_selector ().prepend_text (widget.get_value ())
313 self.albums_list.insert (0, widget.get_value ())
314 self.retrieve_album_art (song[ARTIST_KEY], widget.get_value ())
316 def artist_selection_cb (self, widget):
318 On artist change, add the artist the local list of artists and the selector
319 if it doesn't exist already. So we show the new entry in the selector next time
321 song = self.songs_list [self.song_counter]
322 if (not widget.get_value () in self.artists_list):
323 print "Inserting artist", widget.get_value ()
324 widget.get_selector ().prepend_text (widget.get_value ())
325 self.artists_list.insert (0, widget.get_value ())
328 if __name__ == "__main__":
330 TEST_DATA = [("/home/user/Music/dylan.mp3", "Music", "Bob Dylan", "Subterranean homesick blues", "Bring it all back home", "audio/mpeg"),
331 ("/home/user/mufix/a.mp3", "Music", "", "title", "Album 2", "a/b"),
332 ("/media/mmc1/Attachments/b.m4a", "Music", "", "b", "Album 9", "audio/mpeg"),
333 ("/home/user/mufix/3.mp2", "Music", "", "titlex", "Album 3", "audio/mpeg")]
335 ALBUMS = [["Album %d" % i] for i in range (0, 10)] + [["Bring it all back home"]]
336 ARTISTS = [["Artist %d" % i] for i in range (0, 10)] + [["Bob Dylan"]]
337 window = MussorgskyEditPanel (TEST_DATA, ALBUMS, ARTISTS)
338 window.connect ("destroy", gtk.main_quit)