Fix rating menu.
[gmpc.git] / src / Widgets / gmpc-song-list.vala
blob9e93e64ef2e5014a00a414c33bc667cbaa079b6b
1 /* Gnome Music Player Client (GMPC)
2 * Copyright (C) 2004-2012 Qball Cow <qball@gmpclient.org>
3 * Project homepage: http://gmpclient.org/
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 using Config;
21 using Gtk;
22 using Gmpc;
23 using MPD;
25 private const bool use_transition_gsl = Gmpc.use_transition;
26 private const string some_unique_name_gsl = Config.VERSION;
28 public class Gmpc.Widgets.Songlist : Gmpc.Widgets.Qtable
30 private const int MAX_RESULTS = 125;
31 /* Constructor function */
32 public Songlist()
34 this.spacing = 6;
35 this.max_columns = 3;
38 /**
39 * Add a artist entry
41 private void add_artist_entry(MPD.Song song, int level=0)
43 /* Event box */
44 var event = new Gtk.EventBox();
45 event.set_visible_window(false);
47 var box = new Gtk.HBox(false, 6);
48 /* Disc image */
49 /* add padding */
50 var ali = new Gtk.Alignment(0.0f, 0.5f,0f,0f);
51 ali.set_padding(0,0,level*32,0);
52 box.pack_start(ali, false, false, 0);
54 var image = new Gmpc.MetaData.Image(Gmpc.MetaData.Type.ARTIST_ART, 32);
55 image.set_no_cover_icon("no-artist");
56 image.set_loading_cover_icon("fetching-artist");
57 image.set_squared(false);
58 image.update_from_song(song);
59 /* add the image */
60 ali.add(image);
62 /* Create lLabel */
63 string label = null;
64 if(song.albumartist != null && song.albumartist.length > 0 )
66 label = "%s: %s".printf(_("Artist"), song.albumartist);
68 else
70 label = "%s: %s".printf(_("Artist"), song.artist);
72 var wlabel = new Clicklabel(label);
73 wlabel.set_do_bold(true);
74 wlabel.set_can_focus(true);
76 MPD.Song song_file = song.copy();
77 wlabel.clicked.connect((source, event) =>
79 artist_song_clicked(song_file);
80 });
82 /* add the label */
83 box.pack_start(wlabel, false, false, 0);
85 /* Add the entry */
86 event.add(box);
87 //this.pack_start(event, false, false, 0);
88 this.add_header(event);
91 /**
92 * Add a album entry
94 private void add_album_entry(MPD.Song song, int level=0)
96 /* Event box */
97 var event = new Gtk.EventBox();
98 event.set_visible_window(false);
100 var box = new Gtk.HBox(false, 6);
101 /* Disc image */
102 /* add padding */
103 var ali = new Gtk.Alignment(0.0f, 0.5f,0f,0f);
104 ali.set_padding(0,0,level*32,0);
105 box.pack_start(ali, false, false, 0);
108 //var image = new Gtk.Image.from_icon_name("media-album", Gtk.IconSize.BUTTON);
109 var image = new Gmpc.MetaData.Image(Gmpc.MetaData.Type.ALBUM_ART, 32);
110 image.set_squared(false);
111 image.update_from_song(song);
112 /* add the image */
113 ali.add(image);
115 /* Create lLabel */
116 string label = "%s: %s".printf(_("Album"), song.album);
117 var wlabel = new Clicklabel(label);
118 wlabel.set_do_bold(true);
119 wlabel.set_can_focus(true);
121 MPD.Song song_file = song.copy();
122 wlabel.clicked.connect((source) =>
124 album_song_clicked(song_file);
126 /* add the label */
127 box.pack_start(wlabel, false, false, 0);
129 /* Add the entry */
130 event.add(box);
131 // this.pack_start(event, false, false, 0);
132 this.add_header(event);
135 * Add a disc entry
137 private void add_disc_entry(string entry, int level=0)
139 GLib.debug("Disc entry add: %s", entry);
141 /* */
142 var box = new Gtk.HBox(false, 6);
144 /* add padding */
145 var ali = new Gtk.Alignment(0.0f, 0.5f,0f,0f);
146 ali.set_padding(0,0,level*32,0);
147 box.pack_start(ali, false, false, 0);
149 /* Disc image */
150 var image = new Gtk.Image.from_icon_name("media-album", Gtk.IconSize.BUTTON);
151 /* add the image */
152 ali.add(image);
154 /* Create lLabel */
155 string label = "<b>%s: %s</b>".printf(_("Disc"), entry);
156 var wlabel = new Gtk.Label("");
157 wlabel.set_markup(label);
159 /* add the label */
160 box.pack_start(wlabel, false, false, 0);
162 /* Add the entry */
163 //this.pack_start(box, false, false, 0);
164 this.add_header(box);
169 * Add a song entry
172 private void add_song_entry(MPD.Song song, int level=0)
174 var event = new Gtk.EventBox();
175 event.set_visible_window(false);
176 GLib.debug("Song entry add: %s", song.file);
178 var box = new Gtk.HBox(false, 6);
180 /* add padding */
181 var ali = new Gtk.Alignment(0.0f, 0.5f,0f,0f);
182 ali.set_padding(0,0,level*32,0);
183 box.pack_start(ali, false, false, 0);
185 /* Title image */
186 var image = new Gtk.Image.from_icon_name("media-audiofile", Gtk.IconSize.MENU);
188 event.enter_notify_event.connect((source, event) =>
190 image.set_from_stock("gtk-media-play", Gtk.IconSize.MENU);
191 return false;
195 event.leave_notify_event.connect((source, event) =>
197 image.set_from_icon_name("media-audiofile",Gtk.IconSize.MENU);
198 return false;
201 /* add the image */
202 event.add(image);
203 ali.add(event);
206 MPD.Song song_file = song.copy();
207 event.button_release_event.connect((source, event) =>
209 if(event.button == 1)
211 play_song_clicked(song_file);
212 return true;
214 else if (event.button == 3)
216 song_context_menu(song_file);
217 return true;
219 return false;
222 /* add title label */
223 string label = null;
224 if(song.track != null && song.title != null)
226 label = "%02s. %s".printf(song.track, song.title);
228 else if (song.title != null)
230 label = song.title;
232 else
234 label = GLib.Path.get_basename(song.file);
236 var wlabel = new Gmpc.Clicklabel(label);
237 wlabel.set_can_focus(true);
239 /* add the label */
240 box.pack_start(wlabel, false, false, 0);
241 wlabel.context_menu.connect((source) =>
243 stdout.printf("song list context menu\n");
244 song_context_menu(song_file);
247 wlabel.clicked.connect((source, alt) =>
249 if(alt)
250 play_song_clicked(song_file);
251 else
252 song_clicked(song_file);
255 /* Add the entry */
256 //this.pack_start(box, false, false, 0);
257 this.add(box);
260 /* User click on the title */
261 public signal void song_clicked (MPD.Song song);
262 public signal void song_context_menu (MPD.Song song);
263 /* user clicked on the play */
264 public signal void play_song_clicked (MPD.Song song);
265 /* user clicked on the album */
266 public signal void album_song_clicked (MPD.Song song);
267 /* user clicked on the artist */
268 public signal void artist_song_clicked(MPD.Song song);
271 * Fill the widget from a song list
273 public void set_from_data(owned MPD.Data.Item? list, bool show_album=false, bool show_artist=false)
275 int results = 0;
276 /* Removing everything it contains */
277 foreach(var child in this.get_children())
279 child.destroy();
282 if(list == null) return;
284 /* Sort the list so we can display it correctly */
285 list.sort_album_disc_track();
286 weak MPD.Data.Item iter = list;
287 /* itterating items */
288 string disc = null;
289 string album = null;
290 string artist = null;
291 /* Itterate over the songs */
292 int level = -1;
293 for(; iter != null; iter.next(false))
295 /* if it is no MPD.Song, skip */
296 if(iter.song == null) continue;
297 if(results > this.MAX_RESULTS)
299 var bar = new Gtk.InfoBar();
300 var label = new Gtk.Label(_("Only the first %i results are shown. Please refine your search.".printf(MAX_RESULTS)));
301 label.set_alignment(0.0f,0.5f);
302 bar.set_message_type(Gtk.MessageType.WARNING);
303 (bar.get_content_area() as Gtk.Container).add(label);
305 // this.pack_start(bar, false, false);
306 this.add_header(bar);
307 break;
309 results++;
311 if(show_artist)
313 if(iter.song.albumartist != null &&
314 iter.song.albumartist.length > 0)
316 if(artist == null || artist != iter.song.albumartist)
318 this.add_artist_entry(iter.song,0);
319 artist = iter.song.albumartist;
320 disc = null;
321 album = null;
324 else if(iter.song.artist != null && (artist == null || artist != iter.song.artist))
326 this.add_artist_entry(iter.song,0);
327 artist = iter.song.artist;
328 disc = null;
329 album = null;
332 if(show_album)
334 if(iter.song.album != null && (album == null || album != iter.song.album))
336 this.add_album_entry(iter.song,(artist != null)?1:0);
337 album = iter.song.album;
338 disc = null;
341 /* Check for a new disc */
342 if(iter.song.disc != null && (disc == null || disc != iter.song.disc))
344 this.add_disc_entry(iter.song.disc,((artist != null)?1:0)+((album!=null)?1:0));
345 /* Add a new disc button */
346 disc = iter.song.disc;
348 /* add song row */
349 level = 0;
350 if(disc != null) level++;
351 if(artist != null) level++;
352 if(album != null) level++;
353 this.add_song_entry(iter.song,level);
356 /* show everything */
357 this.show_all();