1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
3 * arch-tag: Implementation of internet radio station properties dialog
5 * Copyright (C) 2002 Colin Walters <walters@gnu.org>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
28 #include <glib/gi18n.h>
30 #include <glade/glade.h>
31 #include <libgnomevfs/gnome-vfs.h>
33 #include "rb-station-properties-dialog.h"
34 #include "rb-file-helpers.h"
35 #include "rb-glade-helpers.h"
36 #include "rb-dialog.h"
37 #include "rb-rating.h"
39 static void rb_station_properties_dialog_class_init (RBStationPropertiesDialogClass
*klass
);
40 static void rb_station_properties_dialog_init (RBStationPropertiesDialog
*dialog
);
41 static void rb_station_properties_dialog_finalize (GObject
*object
);
42 static void rb_station_properties_dialog_set_property (GObject
*object
,
46 static void rb_station_properties_dialog_get_property (GObject
*object
,
50 static gboolean
rb_station_properties_dialog_get_current_entry (RBStationPropertiesDialog
*dialog
);
51 static void rb_station_properties_dialog_update_title (RBStationPropertiesDialog
*dialog
);
52 static void rb_station_properties_dialog_update_location (RBStationPropertiesDialog
*dialog
);
53 static void rb_station_properties_dialog_response_cb (GtkDialog
*gtkdialog
,
55 RBStationPropertiesDialog
*dialog
);
57 static void rb_station_properties_dialog_update (RBStationPropertiesDialog
*dialog
);
58 static void rb_station_properties_dialog_update_title_entry (RBStationPropertiesDialog
*dialog
);
59 static void rb_station_properties_dialog_update_genre (RBStationPropertiesDialog
*dialog
);
60 static void rb_station_properties_dialog_update_play_count (RBStationPropertiesDialog
*dialog
);
61 static void rb_station_properties_dialog_update_bitrate (RBStationPropertiesDialog
*dialog
);
62 static void rb_station_properties_dialog_update_last_played (RBStationPropertiesDialog
*dialog
);
63 static void rb_station_properties_dialog_update_rating (RBStationPropertiesDialog
*dialog
);
64 static void rb_station_properties_dialog_update_playback_error (RBStationPropertiesDialog
*dialog
);
65 static void rb_station_properties_dialog_rated_cb (RBRating
*rating
,
67 RBStationPropertiesDialog
*dialog
);
68 static void rb_station_properties_dialog_sync_entries (RBStationPropertiesDialog
*dialog
);
69 static void rb_station_properties_dialog_show (GtkWidget
*widget
);
70 static void rb_station_properties_dialog_location_changed_cb (GtkEntry
*entry
,
71 RBStationPropertiesDialog
*dialog
);
73 struct RBStationPropertiesDialogPrivate
75 RBEntryView
*entry_view
;
77 RhythmDBEntry
*current_entry
;
82 GtkWidget
*lastplayed
;
86 GtkWidget
*playback_error
;
87 GtkWidget
*playback_error_box
;
88 GtkWidget
*close_button
;
92 #define RB_STATION_PROPERTIES_DIALOG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), RB_TYPE_STATION_PROPERTIES_DIALOG, RBStationPropertiesDialogPrivate))
100 G_DEFINE_TYPE (RBStationPropertiesDialog
,
101 rb_station_properties_dialog
,
105 rb_station_properties_dialog_class_init (RBStationPropertiesDialogClass
*klass
)
107 GObjectClass
*object_class
= G_OBJECT_CLASS (klass
);
108 GtkWidgetClass
*widget_class
= GTK_WIDGET_CLASS (klass
);
110 object_class
->set_property
= rb_station_properties_dialog_set_property
;
111 object_class
->get_property
= rb_station_properties_dialog_get_property
;
113 widget_class
->show
= rb_station_properties_dialog_show
;
115 g_object_class_install_property (object_class
,
117 g_param_spec_object ("entry-view",
119 "RBEntryView object",
121 G_PARAM_READWRITE
| G_PARAM_CONSTRUCT_ONLY
));
123 object_class
->finalize
= rb_station_properties_dialog_finalize
;
125 g_type_class_add_private (klass
, sizeof (RBStationPropertiesDialogPrivate
));
129 rb_station_properties_dialog_init (RBStationPropertiesDialog
*dialog
)
133 dialog
->priv
= RB_STATION_PROPERTIES_DIALOG_GET_PRIVATE (dialog
);
135 g_signal_connect_object (G_OBJECT (dialog
),
137 G_CALLBACK (rb_station_properties_dialog_response_cb
),
140 gtk_dialog_set_has_separator (GTK_DIALOG (dialog
), FALSE
);
141 gtk_container_set_border_width (GTK_CONTAINER (dialog
), 5);
142 gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog
)->vbox
), 2);
144 xml
= rb_glade_xml_new ("station-properties.glade",
147 glade_xml_signal_autoconnect (xml
);
149 gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog
)->vbox
),
150 glade_xml_get_widget (xml
, "stationproperties"));
152 dialog
->priv
->close_button
= gtk_dialog_add_button (GTK_DIALOG (dialog
),
155 gtk_dialog_set_default_response (GTK_DIALOG (dialog
), GTK_RESPONSE_CLOSE
);
157 /* get the widgets from the XML */
158 dialog
->priv
->title
= glade_xml_get_widget (xml
, "titleEntry");
159 dialog
->priv
->genre
= glade_xml_get_widget (xml
, "genreEntry");
160 dialog
->priv
->location
= glade_xml_get_widget (xml
, "locationEntry");
162 dialog
->priv
->lastplayed
= glade_xml_get_widget (xml
, "lastplayedLabel");
163 dialog
->priv
->playcount
= glade_xml_get_widget (xml
, "playcountLabel");
164 dialog
->priv
->bitrate
= glade_xml_get_widget (xml
, "bitrateLabel");
165 dialog
->priv
->playback_error
= glade_xml_get_widget (xml
, "errorLabel");
166 dialog
->priv
->playback_error_box
= glade_xml_get_widget (xml
, "errorBox");
168 rb_glade_boldify_label (xml
, "titleLabel");
169 rb_glade_boldify_label (xml
, "genreLabel");
170 rb_glade_boldify_label (xml
, "locationLabel");
171 rb_glade_boldify_label (xml
, "ratingLabel");
172 rb_glade_boldify_label (xml
, "lastplayedDescLabel");
173 rb_glade_boldify_label (xml
, "playcountDescLabel");
174 rb_glade_boldify_label (xml
, "bitrateDescLabel");
176 g_signal_connect_object (G_OBJECT (dialog
->priv
->location
),
178 G_CALLBACK (rb_station_properties_dialog_location_changed_cb
),
181 dialog
->priv
->rating
= GTK_WIDGET (rb_rating_new ());
182 g_signal_connect_object (dialog
->priv
->rating
,
184 G_CALLBACK (rb_station_properties_dialog_rated_cb
),
185 G_OBJECT (dialog
), 0);
186 gtk_container_add (GTK_CONTAINER (glade_xml_get_widget (xml
, "ratingVBox")),
187 dialog
->priv
->rating
);
188 g_object_unref (G_OBJECT (xml
));
192 rb_station_properties_dialog_finalize (GObject
*object
)
194 RBStationPropertiesDialog
*dialog
;
196 g_return_if_fail (object
!= NULL
);
197 g_return_if_fail (RB_IS_STATION_PROPERTIES_DIALOG (object
));
199 dialog
= RB_STATION_PROPERTIES_DIALOG (object
);
201 g_return_if_fail (dialog
->priv
!= NULL
);
203 if (dialog
->priv
->db
!= NULL
) {
204 g_object_unref (dialog
->priv
->db
);
207 G_OBJECT_CLASS (rb_station_properties_dialog_parent_class
)->finalize (object
);
211 rb_station_properties_dialog_set_property (GObject
*object
,
216 RBStationPropertiesDialog
*dialog
= RB_STATION_PROPERTIES_DIALOG (object
);
219 case PROP_ENTRY_VIEW
:
220 if (dialog
->priv
->db
!= NULL
) {
221 g_object_unref (dialog
->priv
->db
);
224 dialog
->priv
->entry_view
= g_value_get_object (value
);
226 g_object_get (G_OBJECT (dialog
->priv
->entry_view
),
227 "db", &dialog
->priv
->db
, NULL
);
230 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
236 rb_station_properties_dialog_get_property (GObject
*object
,
241 RBStationPropertiesDialog
*dialog
= RB_STATION_PROPERTIES_DIALOG (object
);
244 case PROP_ENTRY_VIEW
:
245 g_value_set_object (value
, dialog
->priv
->entry_view
);
248 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
254 rb_station_properties_dialog_new (RBEntryView
*entry_view
)
256 RBStationPropertiesDialog
*dialog
;
258 g_return_val_if_fail (RB_IS_ENTRY_VIEW (entry_view
), NULL
);
260 dialog
= g_object_new (RB_TYPE_STATION_PROPERTIES_DIALOG
,
261 "entry-view", entry_view
,
264 if (!rb_station_properties_dialog_get_current_entry (dialog
)) {
265 g_object_unref (G_OBJECT (dialog
));
269 rb_station_properties_dialog_update (dialog
);
271 return GTK_WIDGET (dialog
);
275 rb_station_properties_dialog_response_cb (GtkDialog
*gtkdialog
,
277 RBStationPropertiesDialog
*dialog
)
279 if (dialog
->priv
->current_entry
)
280 rb_station_properties_dialog_sync_entries (dialog
);
282 gtk_widget_destroy (GTK_WIDGET (dialog
));
286 rb_station_properties_dialog_get_current_entry (RBStationPropertiesDialog
*dialog
)
288 GList
*selected_entries
;
291 selected_entries
= rb_entry_view_get_selected_entries (dialog
->priv
->entry_view
);
293 if ((selected_entries
== NULL
) ||
294 (selected_entries
->data
== NULL
)) {
295 dialog
->priv
->current_entry
= NULL
;
299 if (dialog
->priv
->current_entry
!= NULL
) {
300 rhythmdb_entry_unref (dialog
->priv
->current_entry
);
303 dialog
->priv
->current_entry
= rhythmdb_entry_ref (selected_entries
->data
);
305 g_list_foreach (selected_entries
, (GFunc
)rhythmdb_entry_unref
, NULL
);
306 g_list_free (selected_entries
);
312 rb_station_properties_dialog_update (RBStationPropertiesDialog
*dialog
)
314 rb_station_properties_dialog_update_title (dialog
);
316 if (dialog
->priv
->current_entry
) {
317 rb_station_properties_dialog_update_location (dialog
);
318 rb_station_properties_dialog_update_title_entry (dialog
);
319 rb_station_properties_dialog_update_genre (dialog
);
322 rb_station_properties_dialog_update_play_count (dialog
);
323 rb_station_properties_dialog_update_bitrate (dialog
);
324 rb_station_properties_dialog_update_last_played (dialog
);
325 rb_station_properties_dialog_update_rating (dialog
);
326 rb_station_properties_dialog_location_changed_cb (GTK_ENTRY (dialog
->priv
->location
), dialog
);
330 rb_station_properties_dialog_update_title (RBStationPropertiesDialog
*dialog
)
335 if (dialog
->priv
->current_entry
) {
336 name
= rhythmdb_entry_get_string (dialog
->priv
->current_entry
, RHYTHMDB_PROP_TITLE
);
337 tmp
= g_strdup_printf (_("%s Properties"), name
);
338 gtk_window_set_title (GTK_WINDOW (dialog
), tmp
);
341 gtk_window_set_title (GTK_WINDOW (dialog
), _("New Internet Radio Station"));
346 rb_station_properties_dialog_update_title_entry (RBStationPropertiesDialog
*dialog
)
350 title
= rhythmdb_entry_get_string (dialog
->priv
->current_entry
, RHYTHMDB_PROP_TITLE
);
351 gtk_entry_set_text (GTK_ENTRY (dialog
->priv
->title
),title
);
355 rb_station_properties_dialog_update_genre (RBStationPropertiesDialog
*dialog
)
359 genre
= rhythmdb_entry_get_string (dialog
->priv
->current_entry
, RHYTHMDB_PROP_GENRE
);
360 gtk_entry_set_text (GTK_ENTRY (dialog
->priv
->genre
), genre
);
364 rb_station_properties_dialog_update_location (RBStationPropertiesDialog
*dialog
)
366 const char *location
;
369 location
= rhythmdb_entry_get_string (dialog
->priv
->current_entry
, RHYTHMDB_PROP_LOCATION
);
370 unescaped
= gnome_vfs_unescape_string_for_display (location
);
371 gtk_entry_set_text (GTK_ENTRY (dialog
->priv
->location
), unescaped
);
376 rb_station_properties_dialog_rated_cb (RBRating
*rating
,
378 RBStationPropertiesDialog
*dialog
)
380 GValue value
= {0, };
382 g_return_if_fail (RB_IS_RATING (rating
));
383 g_return_if_fail (RB_IS_STATION_PROPERTIES_DIALOG (dialog
));
384 g_return_if_fail (score
>= 0 && score
<= 5 );
386 if (!dialog
->priv
->current_entry
)
389 g_value_init (&value
, G_TYPE_DOUBLE
);
390 g_value_set_double (&value
, score
);
392 /* set the new value for the song */
393 rhythmdb_entry_set (dialog
->priv
->db
,
394 dialog
->priv
->current_entry
,
395 RHYTHMDB_PROP_RATING
,
397 g_value_unset (&value
);
398 rhythmdb_commit (dialog
->priv
->db
);
400 g_object_set (G_OBJECT (dialog
->priv
->rating
), "rating", score
, NULL
);
404 rb_station_properties_dialog_update_play_count (RBStationPropertiesDialog
*dialog
)
409 if (dialog
->priv
->current_entry
)
410 count
= rhythmdb_entry_get_ulong (dialog
->priv
->current_entry
, RHYTHMDB_PROP_PLAY_COUNT
);
412 text
= g_strdup_printf ("%ld", count
);
413 gtk_label_set_text (GTK_LABEL (dialog
->priv
->playcount
), text
);
418 rb_station_properties_dialog_update_bitrate (RBStationPropertiesDialog
*dialog
)
423 if (dialog
->priv
->current_entry
)
424 val
= rhythmdb_entry_get_ulong (dialog
->priv
->current_entry
, RHYTHMDB_PROP_BITRATE
);
427 text
= g_strdup (_("Unknown"));
429 text
= g_strdup_printf (_("%lu kbps"), val
);
431 gtk_label_set_text (GTK_LABEL (dialog
->priv
->bitrate
), text
);
436 rb_station_properties_dialog_update_last_played (RBStationPropertiesDialog
*dialog
)
438 const char *last_played
= _("Never");
440 if (dialog
->priv
->current_entry
)
441 last_played
= rhythmdb_entry_get_string (dialog
->priv
->current_entry
, RHYTHMDB_PROP_LAST_PLAYED_STR
);
442 gtk_label_set (GTK_LABEL (dialog
->priv
->lastplayed
), last_played
);
446 rb_station_properties_dialog_update_rating (RBStationPropertiesDialog
*dialog
)
448 gdouble rating
= 0.0;
449 g_return_if_fail (RB_IS_STATION_PROPERTIES_DIALOG (dialog
));
451 if (dialog
->priv
->current_entry
)
452 rating
= rhythmdb_entry_get_double (dialog
->priv
->current_entry
, RHYTHMDB_PROP_RATING
);
454 g_object_set (G_OBJECT (dialog
->priv
->rating
), "rating", rating
, NULL
);
458 rb_station_properties_dialog_update_playback_error (RBStationPropertiesDialog
*dialog
)
462 g_return_if_fail (RB_IS_STATION_PROPERTIES_DIALOG (dialog
));
464 error
= rhythmdb_entry_get_string (dialog
->priv
->current_entry
, RHYTHMDB_PROP_PLAYBACK_ERROR
);
465 if (dialog
->priv
->current_entry
&& error
) {
466 gtk_label_set_text (GTK_LABEL (dialog
->priv
->playback_error
), error
);
467 gtk_widget_show (dialog
->priv
->playback_error_box
);
469 gtk_label_set_text (GTK_LABEL (dialog
->priv
->playback_error
), "");
470 gtk_widget_hide (dialog
->priv
->playback_error_box
);
475 rb_station_properties_dialog_sync_entries (RBStationPropertiesDialog
*dialog
)
479 const char *location
;
482 gboolean changed
= FALSE
;
483 RhythmDBEntry
*entry
= dialog
->priv
->current_entry
;
485 title
= gtk_entry_get_text (GTK_ENTRY (dialog
->priv
->title
));
486 genre
= gtk_entry_get_text (GTK_ENTRY (dialog
->priv
->genre
));
487 location
= gtk_entry_get_text (GTK_ENTRY (dialog
->priv
->location
));
489 string
= rhythmdb_entry_get_string (entry
, RHYTHMDB_PROP_TITLE
);
490 if (strcmp (title
, string
)) {
491 g_value_init (&val
, G_TYPE_STRING
);
492 g_value_set_string (&val
, title
);
493 rhythmdb_entry_set (dialog
->priv
->db
, entry
,
496 g_value_unset (&val
);
500 string
= rhythmdb_entry_get_string (entry
, RHYTHMDB_PROP_GENRE
);
501 if (strcmp (genre
, string
)) {
502 g_value_init (&val
, G_TYPE_STRING
);
503 g_value_set_string (&val
, genre
);
504 rhythmdb_entry_set (dialog
->priv
->db
, entry
,
505 RHYTHMDB_PROP_GENRE
, &val
);
506 g_value_unset (&val
);
510 string
= rhythmdb_entry_get_string (entry
, RHYTHMDB_PROP_LOCATION
);
511 if (strcmp (location
, string
)) {
512 g_value_init (&val
, G_TYPE_STRING
);
513 g_value_set_string (&val
, location
);
514 rhythmdb_entry_set (dialog
->priv
->db
, entry
,
515 RHYTHMDB_PROP_LOCATION
, &val
);
516 g_value_unset (&val
);
521 rhythmdb_commit (dialog
->priv
->db
);
525 rb_station_properties_dialog_show (GtkWidget
*widget
)
527 if (GTK_WIDGET_CLASS (rb_station_properties_dialog_parent_class
)->show
)
528 GTK_WIDGET_CLASS (rb_station_properties_dialog_parent_class
)->show (widget
);
530 rb_station_properties_dialog_update_playback_error (
531 RB_STATION_PROPERTIES_DIALOG (widget
));
535 rb_station_properties_dialog_location_changed_cb (GtkEntry
*entry
,
536 RBStationPropertiesDialog
*dialog
)