dbaa8ffda9b85142b46987a25760de182abb7c0d
[jamaendo] / jamaui / albumlist.py
1 import os
2 import gtk
3 import gobject
4 try:
5     import hildon
6 except:
7     import helldon as hildon
8 import jamaendo
9 import util
10 from settings import settings
11 from postoffice import postoffice
12 import logging
13
14 log = logging.getLogger(__name__)
15
16 class _BaseList(gtk.TreeView):
17     """
18     TODO: unify the different lists into one
19     """
20     ICON_SIZE = 50
21
22     def __init__(self):
23         gtk.TreeView.__init__(self)
24         self.__store = None
25         self.default_pixbuf = util.find_resource('album.png')
26         self.connect('destroy', self.on_destroy)
27
28     def get_pixbuf(self, img):
29         try:
30             return gtk.gdk.pixbuf_new_from_file_at_size(img,
31                                                         self.ICON_SIZE,
32                                                         self.ICON_SIZE)
33         except gobject.GError:
34             log.error("Broken image in cache: %s", img)
35             try:
36                 os.unlink(img)
37             except OSError, e:
38                 log.warning("Failed to unlink broken image.")
39             if img != self.default_pixbuf:
40                 return self.get_default_pixbuf()
41             else:
42                 return None
43
44     def get_default_pixbuf(self):
45         if self.default_pixbuf:
46             return self.get_pixbuf(self.default_pixbuf)
47
48     def on_destroy(self, wnd):
49         pass
50
51 class MusicList(_BaseList):
52     def __init__(self):
53         _BaseList.__init__(self)
54         (self.COL_ICON, self.COL_NAME, self.COL_ID, self.COL_IMAGE) = range(4)
55         self.__store = gtk.ListStore(gtk.gdk.Pixbuf, str, int, str)
56
57         self.set_model(self.__store)
58
59         icon = gtk.TreeViewColumn('Icon')
60         self.append_column(icon)
61         cell = gtk.CellRendererPixbuf()
62         icon.pack_start(cell, True)
63         icon.add_attribute(cell, 'pixbuf', self.COL_ICON)
64
65         col = gtk.TreeViewColumn('Name')
66         self.append_column(col)
67         cell = gtk.CellRendererText()
68         col.pack_start(cell, True)
69         col.add_attribute(cell, 'text', self.COL_NAME)
70         self.set_search_column(self.COL_NAME)
71         col.set_sort_column_id(self.COL_NAME)
72
73         postoffice.connect('images', self, self.on_images)
74
75     def get_item_id(self, path):
76         return self.__store.get(self.__store.get_iter(path), self.COL_ID)[0]
77
78     def on_destroy(self, wnd):
79         postoffice.disconnect('images', self)
80
81     def on_images(self, images):
82         for url, image in images:
83             for row in self.__store:
84                 if row[self.COL_IMAGE] == url:
85                     pb = self.get_pixbuf(image)
86                     if pb:
87                         row[self.COL_ICON] = pb
88
89     def add_items(self, items):
90         images = [x for x in (self.get_item_image(item) for item in items) if x]
91         for item in items:
92             txt = self.get_item_text(item)
93             self.__store.append([self.get_default_pixbuf(), txt, item.ID, self.get_item_image(item)])
94         if images:
95             postoffice.notify('request-images', images)
96
97     def get_item_text(self, item):
98         if isinstance(item, jamaendo.Album):
99             return "%s - %s" % (item.artist_name, item.name)
100         elif isinstance(item, jamaendo.Track):
101             return "%s - %s" % (item.artist_name, item.name)
102         else:
103             return item.name
104
105     def get_item_image(self, item):
106         ret = None
107         if isinstance(item, jamaendo.Track):
108             ret = item.album_image
109         elif hasattr(item, 'image'):
110             ret = item.image
111         if ret:
112             ret = ret.replace('1.100.jpg', '1.%d.jpg'%(self.ICON_SIZE))
113         return ret
114
115 class AlbumList(_BaseList):
116     def __init__(self):
117         _BaseList.__init__(self)
118         (self.COL_ICON, self.COL_NAME, self.COL_ID) = range(3)
119         self.__store = gtk.ListStore(gtk.gdk.Pixbuf, str, int)
120         self.__show_artist = True
121
122         self.set_model(self.__store)
123
124         icon = gtk.TreeViewColumn('Icon')
125         self.append_column(icon)
126         cell = gtk.CellRendererPixbuf()
127         icon.pack_start(cell, True)
128         icon.add_attribute(cell, 'pixbuf', self.COL_ICON)
129
130         col = gtk.TreeViewColumn('Name')
131         self.append_column(col)
132         cell = gtk.CellRendererText()
133         col.pack_start(cell, True)
134         col.add_attribute(cell, 'text', self.COL_NAME)
135         self.set_search_column(self.COL_NAME)
136         col.set_sort_column_id(self.COL_NAME)
137
138         postoffice.connect('album-cover', self, self.on_album_cover)
139
140     def on_destroy(self, wnd):
141         _BaseList.on_destroy(self, wnd)
142         postoffice.disconnect('album-cover', self)
143
144     def on_album_cover(self, albumid, size, cover):
145         if size == self.ICON_SIZE:
146             for row in self.__store:
147                 if row[self.COL_ID] == albumid:
148                     row[self.COL_ICON] = self.get_pixbuf(cover)
149
150     def add_album(self, album):
151         if self.__show_artist:
152             txt = "%s - %s" % (album.artist_name, album.name)
153         else:
154             txt = album.name
155         self.__store.append([self.get_default_pixbuf(), txt, album.ID])
156         postoffice.notify('request-album-cover', album.ID, self.ICON_SIZE)
157
158     def get_album_id(self, path):
159         return self.__store.get(self.__store.get_iter(path), self.COL_ID)[0]
160
161     def show_artist(self, show):
162         self.__show_artist = show
163
164 class TrackList(_BaseList):
165     def __init__(self, numbers = True):
166         _BaseList.__init__(self)
167         self.track_numbers = numbers
168         self.__store = gtk.ListStore(int, str, int)
169         self.set_model(self.__store)
170
171         if numbers:
172             col0 = gtk.TreeViewColumn('Num')
173             self.append_column(col0)
174             cell0 = gtk.CellRendererText()
175             col0.pack_start(cell0, True)
176             col0.add_attribute(cell0, 'text', 0)
177
178         col = gtk.TreeViewColumn('Name')
179         self.append_column(col)
180         cell = gtk.CellRendererText()
181         col.pack_start(cell, True)
182         col.add_attribute(cell, 'text', 1)
183
184         self.set_search_column(1 if numbers else 0)
185         col.set_sort_column_id(0)
186
187     def add_track(self, track):
188         self.__store.append([track.numalbum, track.name, track.ID])
189
190     def get_track_id(self, path):
191         treeiter = self.__store.get_iter(path)
192         _, _, _id = self.__store.get(treeiter, 0, 1, 2)
193         return _id
194
195 class RadioList(_BaseList):
196     def __init__(self):
197         _BaseList.__init__(self)
198         (self.COL_ICON, self.COL_NAME, self.COL_ID, self.COL_IMAGE) = range(4)
199         self.__store = gtk.ListStore(gtk.gdk.Pixbuf, str, int, str)
200         self.set_model(self.__store)
201
202         icon = gtk.TreeViewColumn('Icon')
203         self.append_column(icon)
204         cell = gtk.CellRendererPixbuf()
205         icon.pack_start(cell, True)
206         icon.add_attribute(cell, 'pixbuf', self.COL_ICON)
207
208         col = gtk.TreeViewColumn('Name')
209         self.append_column(col)
210         cell = gtk.CellRendererText()
211         col.pack_start(cell, True)
212         col.add_attribute(cell, 'text', self.COL_NAME)
213         self.set_search_column(self.COL_NAME)
214         col.set_sort_column_id(self.COL_NAME)
215
216         postoffice.connect('images', self, self.on_images)
217
218     def on_destroy(self, wnd):
219         postoffice.disconnect('images', self)
220
221     def add_radios(self, radios):
222         for radio in radios:
223             self.__store.append([self.get_default_pixbuf(), self.radio_name(radio), radio.ID, radio.image])
224         postoffice.notify('request-images', [radio.image for radio in radios])
225
226
227     def get_radio_id(self, path):
228         treeiter = self.__store.get_iter(path)
229         name, _id = self.__store.get(treeiter, self.COL_NAME, self.COL_ID)
230         return name, _id
231
232     def on_images(self, images):
233         for url, image in images:
234             for row in self.__store:
235                 if row[self.COL_IMAGE] == url:
236                     pb = self.get_pixbuf(image)
237                     if pb:
238                         row[self.COL_ICON] = pb
239
240     def radio_name(self, radio):
241         if radio.idstr:
242             return radio.idstr.capitalize()
243         elif radio.name:
244             return radio.name
245         else:
246             return "Radio #%s" % (radio.ID)