1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
4 * RBSongDisplayBox is a hack of GtkHBox
5 * arch-tag: RBSongDisplayBox - display album/artist information
8 /* GTK - The GIMP Toolkit
9 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
11 * This library is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU Lesser General Public
13 * License as published by the Free Software Foundation; either
14 * version 2 of the License, or (at your option) any later version.
16 * This library is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * Lesser General Public License for more details.
21 * You should have received a copy of the GNU Lesser General Public
22 * License along with this library; if not, write to the
23 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
24 * Boston, MA 02110-1301 USA.
28 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
29 * file for a list of people on the GTK+ Team. See the ChangeLog
30 * files for a list of changes. These files are distributed with
31 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
36 #include <glib/gi18n.h>
38 #include <libgnomeui/libgnomeui.h> /* for GnomeUrl */
39 #include <libgnomevfs/gnome-vfs-utils.h>
41 #include "rb-song-display-box.h"
45 struct RBSongDisplayBoxPrivate
52 GtkTooltips
*artist_tips
, *album_tips
;
55 #define RB_SONG_DISPLAY_BOX_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), RB_TYPE_SONG_DISPLAY_BOX, RBSongDisplayBoxPrivate))
57 static void rb_song_display_box_class_init (RBSongDisplayBoxClass
*klass
);
58 static void rb_song_display_box_init (RBSongDisplayBox
*box
);
59 static void rb_song_display_box_finalize (GObject
*object
);
60 static void rb_song_display_box_size_request (GtkWidget
*widget
,
61 GtkRequisition
*requisition
);
62 static void rb_song_display_box_size_allocate (GtkWidget
*widget
,
63 GtkAllocation
*allocation
);
65 /* size_allocate helper functions */
66 static int displaybox_get_childwidth (GtkWidget
*widget
);
67 static void do_allocation (GtkWidget
*widget
,
69 GtkAllocation
*allocation
);
71 G_DEFINE_TYPE (RBSongDisplayBox
, rb_song_display_box
, GTK_TYPE_BOX
);
75 rb_song_display_box_class_init (RBSongDisplayBoxClass
*class)
77 GtkWidgetClass
*widget_class
;
79 widget_class
= (GtkWidgetClass
*) class;
81 G_OBJECT_CLASS (class)->finalize
= rb_song_display_box_finalize
;
83 widget_class
->size_request
= rb_song_display_box_size_request
;
84 widget_class
->size_allocate
= rb_song_display_box_size_allocate
;
86 g_type_class_add_private (class, sizeof (RBSongDisplayBoxPrivate
));
90 rb_song_display_box_init (RBSongDisplayBox
*displaybox
)
94 displaybox
->priv
= RB_SONG_DISPLAY_BOX_GET_PRIVATE (displaybox
);
97 box
= GTK_BOX (displaybox
);
99 box
->homogeneous
= FALSE
;
101 displaybox
->priv
->from
= gtk_label_new (_("from"));
102 displaybox
->priv
->album
= gnome_href_new ("", "");
103 displaybox
->priv
->by
= gtk_label_new (_("by"));
104 displaybox
->priv
->artist
= gnome_href_new ("", "");
107 gtk_box_pack_start (box
, displaybox
->priv
->from
,
109 gtk_box_pack_start (box
, displaybox
->priv
->album
,
111 gtk_box_pack_start (box
, displaybox
->priv
->by
,
113 gtk_box_pack_start (box
, displaybox
->priv
->artist
,
116 gtk_widget_set_no_show_all (displaybox
->priv
->from
, TRUE
);
117 gtk_widget_set_no_show_all (displaybox
->priv
->album
, TRUE
);
118 gtk_widget_set_no_show_all (displaybox
->priv
->by
, TRUE
);
119 gtk_widget_set_no_show_all (displaybox
->priv
->artist
, TRUE
);
121 displaybox
->priv
->artist_tips
= gtk_tooltips_new ();
122 displaybox
->priv
->album_tips
= gtk_tooltips_new ();
126 rb_song_display_box_new (void)
128 RBSongDisplayBox
*displaybox
;
130 displaybox
= g_object_new (RB_TYPE_SONG_DISPLAY_BOX
, NULL
, NULL
);
132 return GTK_WIDGET (displaybox
);
136 rb_song_display_box_finalize (GObject
*object
)
138 RBSongDisplayBox
*box
;
140 box
= RB_SONG_DISPLAY_BOX (object
);
142 G_OBJECT_CLASS (rb_song_display_box_parent_class
)->finalize (object
);
146 rb_song_display_box_size_request (GtkWidget
*widget
, GtkRequisition
*requisition
)
148 RBSongDisplayBox
*displaybox
;
152 GtkRequisition child_requisition
;
154 box
= GTK_BOX (widget
);
155 displaybox
= RB_SONG_DISPLAY_BOX (widget
);
157 requisition
->height
= 0;
159 for (children
= box
->children
; children
; children
= children
->next
)
161 child
= children
->data
;
163 if (GTK_WIDGET_VISIBLE (child
->widget
))
165 gtk_widget_size_request (child
->widget
,
167 requisition
->height
= MAX (requisition
->height
,
168 child_requisition
.height
);
172 gtk_widget_size_request (displaybox
->priv
->by
, &child_requisition
);
173 requisition
->width
= child_requisition
.width
;
177 rb_song_display_box_size_allocate (GtkWidget
*widget
, GtkAllocation
*allocation
)
179 RBSongDisplayBox
*displaybox
;
180 GtkAllocation remain
;
183 displaybox
= RB_SONG_DISPLAY_BOX (widget
);
184 widget
->allocation
= *allocation
;
186 /* calculate how much room we have for the 'album' link */
187 width
= allocation
->width
;
188 width
-= displaybox_get_childwidth (displaybox
->priv
->from
);
189 width
-= displaybox_get_childwidth (displaybox
->priv
->by
);
190 width
-= displaybox_get_childwidth (displaybox
->priv
->artist
);
192 /* if we can't fit the entire thing and we have less than 30 pixels
193 then just don't bother.
196 width
< displaybox_get_childwidth (displaybox
->priv
->album
))
204 remain
= widget
->allocation
;
205 if (gtk_widget_get_default_direction () == GTK_TEXT_DIR_RTL
) {
206 remain
.x
+= remain
.width
;
208 do_allocation (displaybox
->priv
->from
, shown
, &remain
);
209 do_allocation (displaybox
->priv
->album
, width
, &remain
);
210 do_allocation (displaybox
->priv
->by
, -1, &remain
);
211 do_allocation (displaybox
->priv
->artist
,-1, &remain
);
215 displaybox_get_childwidth (GtkWidget
*widget
)
217 GtkRequisition requisition
;
219 gtk_widget_get_child_requisition (widget
, &requisition
);
220 return requisition
.width
;
224 do_allocation (GtkWidget
*widget
, int size
, GtkAllocation
*allocation
)
226 GtkAllocation child_allocation
;
229 width
= displaybox_get_childwidth (widget
);
231 width
= MIN (width
, size
);
233 child_allocation
.width
= MIN (width
, allocation
->width
);
234 allocation
->width
-= child_allocation
.width
;
235 if (gtk_widget_get_default_direction () == GTK_TEXT_DIR_RTL
) {
236 allocation
->x
-= child_allocation
.width
;
237 child_allocation
.x
= allocation
->x
;
239 child_allocation
.x
= allocation
->x
;
240 allocation
->x
+= child_allocation
.width
;
243 child_allocation
.height
= allocation
->height
;
244 child_allocation
.y
= allocation
->y
;
246 gtk_widget_size_allocate( widget
, &child_allocation
);
250 sanitize_string (const char *data
)
255 * netlabels often put URLs (or domain names) in the 'album' field
256 * of their releases; since there are no artist names in AMG that
257 * start with 'http://' or 'www.' (there is a 'www', from the 70s,
258 * strangely enough), we can safely assume anything that looks
259 * like a URL or domain name is one.
261 * There's sometimes some trailing junk, usually after a space,
262 * so it's probably sensible to strip that off.
264 if (g_str_has_prefix (data
, "http://")) {
265 char *end
= strchr (data
, ' ');
267 ret
= g_strndup (data
, end
- data
);
269 ret
= g_strdup (data
);
270 } else if (g_str_has_prefix (data
, "www.")) {
271 char *end
= strchr (data
, ' ');
273 ret
= g_strdup_printf ("http://%*s",
274 (int) (end
-data
), data
);
276 ret
= g_strdup_printf ("http://%s", data
);
278 ret
= g_strdup (data
);
280 return g_strstrip (ret
);
284 info_url (const char *artist
, const char *album
)
286 char *escaped_artist
;
287 char *sanitized_artist
;
290 sanitized_artist
= sanitize_string (artist
);
291 escaped_artist
= gnome_vfs_escape_string (sanitized_artist
);
292 g_free (sanitized_artist
);
294 char *sanitized_album
;
296 sanitized_album
= sanitize_string (album
);
297 escaped_album
= gnome_vfs_escape_string (sanitized_album
);
298 g_free (sanitized_album
);
299 ret
= g_strdup_printf ("http://www.last.fm/music/%s/%s",
300 escaped_artist
, escaped_album
);
301 g_free (escaped_album
);
303 ret
= g_strdup_printf ("http://www.last.fm/music/%s", escaped_artist
);
305 g_free (escaped_artist
);
311 rb_song_display_box_sync (RBSongDisplayBox
*displaybox
, RhythmDBEntry
*entry
)
313 const char *album
, *artist
;
317 gtk_widget_hide (displaybox
->priv
->from
);
318 gtk_widget_hide (displaybox
->priv
->album
);
319 gtk_widget_hide (displaybox
->priv
->by
);
320 gtk_widget_hide (displaybox
->priv
->artist
);
324 gtk_widget_show (displaybox
->priv
->from
);
325 gtk_widget_show (displaybox
->priv
->album
);
326 gtk_widget_show (displaybox
->priv
->by
);
327 gtk_widget_show (displaybox
->priv
->artist
);
329 album
= rhythmdb_entry_get_string (entry
, RHYTHMDB_PROP_ALBUM
);
330 artist
= rhythmdb_entry_get_string (entry
, RHYTHMDB_PROP_ARTIST
);
332 tmp
= info_url (artist
, album
);
333 gnome_href_set_url (GNOME_HREF (displaybox
->priv
->album
), tmp
);
335 tmp
= g_markup_escape_text (album
, -1);
336 gnome_href_set_text (GNOME_HREF (displaybox
->priv
->album
), tmp
);
339 gtk_tooltips_set_tip (displaybox
->priv
->album_tips
,
340 displaybox
->priv
->album
,
341 _("Get information on this album from the web"),
344 tmp
= info_url (artist
, NULL
);
345 gnome_href_set_url (GNOME_HREF (displaybox
->priv
->artist
), tmp
);
347 tmp
= g_markup_escape_text (artist
, -1);
348 gnome_href_set_text (GNOME_HREF (displaybox
->priv
->artist
), tmp
);
351 gtk_tooltips_set_tip (displaybox
->priv
->artist_tips
,
352 displaybox
->priv
->artist
,
353 _("Get information on this artist from the web"),