Add button and image to choose album art
[mussorgsky] / src / edit_panel.py
1 #!/usr/bin/env python2.5
2 import hildon
3 import gtk
4 from mutagen_backend import MutagenBackend
5 from player_backend import MediaPlayer
6
7 # Fields in the tuple!
8 FILE_URI = 0
9 ARTIST_KEY = 2
10 TITLE_KEY = 3
11 ALBUM_KEY = 4
12 MIME_KEY = 5
13
14 class MussorgskyEditPanel (hildon.StackableWindow):
15
16     def __init__ (self, songs_list=None, albums_list=None, artists_list=None):
17         hildon.StackableWindow.__init__ (self)
18         self.set_title ("Edit")
19         self.writer = MutagenBackend ()
20         self.player = MediaPlayer ()
21         self.albums_list = albums_list
22         self.artists_list = artists_list
23         self.add (self.__create_view ())
24         if (songs_list):
25             self.set_songs_list (songs_list)
26         self.banner = None
27
28         self.artists_selector = None
29         self.artists_dialog = None
30
31         self.albums_selector = None
32         self.albums_dialog = None
33         
34     def set_songs_list (self, songs_list):
35             self.songs_list = songs_list
36             self.set_data_in_view (songs_list [0])
37             self.song_counter = 0
38
39     def press_back_cb (self, widget):
40         if (self.player.is_playing ()):
41             self.player.stop ()
42
43         if (self.banner and self.banner.get_property("visible")):
44             self.banner.destroy ()
45
46         if self.__is_view_dirty ():
47             print "Modified data. Save!"
48             self.save_metadata ()
49             
50         if (self.song_counter > 0):
51             self.song_counter -= 1
52             self.set_data_in_view (self.songs_list [self.song_counter])
53
54     def press_next_cb (self, widget):
55         if (self.player.is_playing ()):
56             self.player.stop ()
57
58         if (self.banner and self.banner.get_property("visible")):
59             self.banner.destroy ()
60
61         if self.__is_view_dirty ():
62             print "Modified data. Save!"
63             self.save_metadata ()
64
65         if (self.song_counter < len (self.songs_list) -1):
66             self.song_counter += 1
67             self.set_data_in_view (self.songs_list [self.song_counter])
68         else:
69             self.destroy ()
70
71     def save_metadata (self):
72         # Save the data in the online model to show the appropiate data
73         # in the UI while tracker process the update.
74         song = self.songs_list [self.song_counter]
75
76         new_song = (song[FILE_URI], song[1],
77                     self.artist_entry.get_text (),
78                     self.title_entry.get_text (),
79                     self.album_entry.get_text (),
80                     song[MIME_KEY])
81         self.songs_list [self.song_counter] = new_song
82         try:
83             self.writer.save_metadata_on_file (new_song[FILE_URI],
84                                                new_song[MIME_KEY],
85                                                self.artist_entry.get_text (),
86                                                self.title_entry.get_text (),
87                                                self.album_entry.get_text ())
88         except IOError, e:
89             # This error in case of tracker returning unexistent files.
90             # Uhm.... for instance after removing a memory card we are editing!
91             dialog = gtk.MessageDialog (self,
92                                         gtk.DIALOG_DESTROY_WITH_PARENT,
93                                         gtk.MESSAGE_ERROR,
94                                         gtk.BUTTONS_CLOSE,
95                                         "%s" % str(e));
96             dialog.run ()
97
98         
99
100     def __is_view_dirty (self):
101         """
102         True if the data has been modified in the widgets
103         """
104         song = self.songs_list [self.song_counter]
105
106         return not (self.filename_data.get_text() == song[FILE_URI] and
107                     self.artist_entry.get_text () == song[ARTIST_KEY] and
108                     self.title_entry.get_text () == song[TITLE_KEY] and
109                     self.album_entry.get_text () == song[ALBUM_KEY] )
110         
111
112     def __create_view (self):
113         view_vbox = gtk.VBox (homogeneous=False, spacing = 24)
114
115         filename_row = gtk.HBox ()
116         filename_label = gtk.Label ("Filename:")
117         filename_row.pack_start (filename_label, expand=False, padding=12);
118         self.filename_data = gtk.Label ("")
119         filename_row.pack_start (self.filename_data, expand=True)
120
121         play_button = gtk.Button (stock=gtk.STOCK_MEDIA_PLAY)
122         play_button.connect ("clicked", self.clicked_play)
123         filename_row.pack_start (play_button, expand=False, fill=False, padding=12)
124         view_vbox.pack_start (filename_row, expand=True);
125
126         central_panel = gtk.HBox ()
127
128         table = gtk.Table (3, 2, False)
129         table.set_col_spacings (12)
130         table.set_row_spacings (12)
131
132         central_panel.pack_start (table)
133         view_vbox.pack_start (central_panel, expand=True, fill=True)
134
135         # Artist row
136         button_artist = gtk.Button ("Artist:")
137         if (not self.artists_list):
138             button_artist.set_sensitive (False)
139         button_artist.connect ("clicked", self.artist_selection_cb)
140         table.attach (button_artist, 0, 1, 0, 1, 0, gtk.FILL|gtk.EXPAND)
141         self.artist_entry = gtk.Entry()
142         table.attach (self.artist_entry, 1, 2, 0, 1)
143
144         # Title row
145         label_title = gtk.Label ("Title:")
146         table.attach (label_title, 0, 1, 1, 2, 0)
147         self.title_entry = gtk.Entry()
148         table.attach (self.title_entry, 1, 2, 1, 2)
149
150         # Album row
151         button_album = gtk.Button ("Album:")
152         if (not self.albums_list):
153             button_album.set_sensitive (False)
154         button_album.connect ("clicked", self.album_selection_cb)
155         table.attach (button_album, 0, 1, 2, 3, 0)
156         self.album_entry = gtk.Entry()
157         table.attach (self.album_entry, 1, 2, 2, 3)
158
159         # Album art space
160         album_button = gtk.Button ()
161         self.album_art = gtk.Image ()
162         self.album_art.set_size_request (124, 124)
163         album_button.add (self.album_art)
164         album_button.connect ("clicked", self.clicked_album_art)
165         central_panel.pack_start (album_button, expand=False, fill=False, padding=24)
166         
167         # Buttons row
168         button_box = gtk.HButtonBox ()
169         button_box.set_layout (gtk.BUTTONBOX_END)
170
171         back_button = gtk.Button (stock=gtk.STOCK_GO_BACK)
172         back_button.connect ("clicked", self.press_back_cb)
173         button_box.pack_start (back_button, expand=True, fill=True, padding=6)
174         
175         next_button = gtk.Button (stock=gtk.STOCK_GO_FORWARD)
176         next_button.connect ("clicked", self.press_next_cb)
177         button_box.pack_start (next_button, expand=True, fill=True, padding=6)
178         
179         view_vbox.pack_start (button_box, expand=False, fill=True, padding=12)
180         
181         return view_vbox
182
183
184     def set_data_in_view (self, song):
185         """
186         Place in the screen the song information.
187         Song is a tuple like (filename, 'Music', title, artist, album, mime)
188         """
189         assert len (song) == 6
190         self.filename_data.set_text (song[FILE_URI])
191         self.artist_entry.set_text (song[ARTIST_KEY])
192         self.title_entry.set_text (song[TITLE_KEY])
193         self.album_entry.set_text (song[ALBUM_KEY])
194
195         self.album_art.set_from_file ("/home/ivan/cover-sample.jpeg")
196
197         if (not song[MIME_KEY] in self.writer.get_supported_mimes ()):
198             print "show notification"
199             self.banner = hildon.Banner ()
200             self.banner.set_text ("Unsupported format (%s)" % song[MIME_KEY])
201             self.banner.show_all ()
202
203     def clicked_play (self, widget):
204         if (self.player.is_playing ()):
205             self.player.stop ()
206         else:
207             song = self.songs_list [self.song_counter]
208             self.player.play ("file://" + song[FILE_URI])
209
210     def clicked_album_art (self, widget):
211         print "implement me, please"
212
213     def album_selection_cb (self, widget):
214         if (not self.albums_selector):
215             self.albums_selector = hildon.hildon_touch_selector_new_text ()
216             for album in self.albums_list :
217                 self.albums_selector.append_text (album[0])
218
219         if (not self.albums_dialog):
220             self.albums_dialog = hildon.PickerDialog (self)
221             self.albums_dialog.set_title ("Choose album...")
222             self.albums_dialog.set_selector (self.albums_selector)
223
224         response = self.albums_dialog.run ()
225         if (response == gtk.RESPONSE_OK):
226             print "Ok (%s)" % (self.albums_selector.get_current_text ())
227             self.album_entry.set_text (self.albums_selector.get_current_text ())
228         self.albums_dialog.hide ()
229
230     def artist_selection_cb (self, widget):
231         if (not self.artists_selector):
232             self.artists_selector = hildon.hildon_touch_selector_new_text ()
233             for artist in self.artists_list :
234                 self.artists_selector.append_text (artist[0])
235                 
236         if (not self.artists_dialog):
237             self.artists_dialog = hildon.PickerDialog (self)
238             self.artists_dialog.set_title ("Choose artist...")
239             self.artists_dialog.set_selector (self.artists_selector)
240
241         response = self.artists_dialog.run ()
242
243         if (response == gtk.RESPONSE_OK):
244             print "Ok (%s)" % (self.artists_selector.get_current_text ())
245             self.artist_entry.set_text (str(self.artists_selector.get_current_text ()))
246         self.artists_dialog.hide ()
247
248 # Testing porpuses
249 if __name__ == "__main__":
250
251     TEST_DATA = [("/a/b/c/d.mp3", "Music", "", "title", "album", "audio/mpeg"),
252                  ("/home/user/mufix/dejame.mp3", "Music", "", "title", "album 2", "a/b"),
253                  ("/home/user/mufix/3.mp2", "Music", "", "titlex", "album 3", "audio/mpeg")]
254     ALBUMS = [["Album %d" % i] for i in range (0, 10)]
255     ARTISTS = [["Artist %d" % i] for i in range (0, 10)]
256     window = MussorgskyEditPanel (TEST_DATA, ALBUMS, ARTISTS)
257     window.connect ("destroy", gtk.main_quit)
258     window.show_all ()
259     gtk.main ()