No issues found
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
2 *
3 * Copyright (C) 2005 Renato Araujo Oliveira Filho <renato.filho@indt.org>
4 *
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.
9 *
10 * The Rhythmbox authors hereby grant permission for non-GPL compatible
11 * GStreamer plugins to be used and distributed together with GStreamer
12 * and Rhythmbox. This permission is above and beyond the permissions granted
13 * by the GPL license by which Rhythmbox is covered. If you modify this code
14 * you may extend this exception to your version of the code, but you are not
15 * obligated to do so. If you do not wish to do so, delete this exception
16 * statement from your version.
17 *
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
26 *
27 */
28
29 #include <config.h>
30
31 #include <string.h>
32 #include <time.h>
33
34 #include <glib/gi18n.h>
35 #include <gtk/gtk.h>
36 #include <glib.h>
37 /* GStreamer happens to have some language name functions */
38 #include <gst/gst.h>
39 #include <gst/tag/tag.h>
40
41 #include "rb-feed-podcast-properties-dialog.h"
42 #include "rb-file-helpers.h"
43 #include "rb-builder-helpers.h"
44 #include "rb-dialog.h"
45 #include "rb-cut-and-paste-code.h"
46 #include "rhythmdb.h"
47 #include "rb-debug.h"
48
49 static void rb_feed_podcast_properties_dialog_class_init (RBFeedPodcastPropertiesDialogClass *klass);
50 static void rb_feed_podcast_properties_dialog_init (RBFeedPodcastPropertiesDialog *dialog);
51 static void rb_feed_podcast_properties_dialog_finalize (GObject *object);
52 static void rb_feed_podcast_properties_dialog_update_title (RBFeedPodcastPropertiesDialog *dialog);
53 static void rb_feed_podcast_properties_dialog_update_title_label (RBFeedPodcastPropertiesDialog *dialog);
54 static void rb_feed_podcast_properties_dialog_update_location (RBFeedPodcastPropertiesDialog *dialog);
55 static void rb_feed_podcast_properties_dialog_response_cb (GtkDialog *gtkdialog,
56 int response_id,
57 RBFeedPodcastPropertiesDialog *dialog);
58
59 static void rb_feed_podcast_properties_dialog_update (RBFeedPodcastPropertiesDialog *dialog);
60 static void rb_feed_podcast_properties_dialog_update_author (RBFeedPodcastPropertiesDialog *dialog);
61 static void rb_feed_podcast_properties_dialog_update_language (RBFeedPodcastPropertiesDialog *dialog);
62 static void rb_feed_podcast_properties_dialog_update_last_update (RBFeedPodcastPropertiesDialog *dialog);
63 static void rb_feed_podcast_properties_dialog_update_last_episode (RBFeedPodcastPropertiesDialog *dialog);
64 static void rb_feed_podcast_properties_dialog_update_copyright (RBFeedPodcastPropertiesDialog *dialog);
65 static void rb_feed_podcast_properties_dialog_update_summary (RBFeedPodcastPropertiesDialog *dialog);
66 static gchar* rb_feed_podcast_properties_dialog_parse_time (gulong time);
67
68 struct RBFeedPodcastPropertiesDialogPrivate
69 {
70 RhythmDB *db;
71 RhythmDBEntry *current_entry;
72
73 GtkWidget *title;
74 GtkWidget *author;
75 GtkWidget *location;
76 GtkWidget *language;
77 GtkWidget *last_update;
78 GtkWidget *last_episode;
79 GtkWidget *copyright;
80 GtkWidget *summary;
81
82 GtkWidget *close_button;
83 };
84
85 #define RB_FEED_PODCAST_PROPERTIES_DIALOG_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), RB_TYPE_FEED_PODCAST_PROPERTIES_DIALOG, RBFeedPodcastPropertiesDialogPrivate))
86
87 enum
88 {
89 PROP_0,
90 PROP_BACKEND
91 };
92
93 G_DEFINE_TYPE (RBFeedPodcastPropertiesDialog, rb_feed_podcast_properties_dialog, GTK_TYPE_DIALOG)
94
95 static void
96 rb_feed_podcast_properties_dialog_class_init (RBFeedPodcastPropertiesDialogClass *klass)
97 {
98 GObjectClass *object_class = G_OBJECT_CLASS (klass);
99
100 object_class->finalize = rb_feed_podcast_properties_dialog_finalize;
101
102 g_type_class_add_private (klass, sizeof (RBFeedPodcastPropertiesDialogPrivate));
103 }
104
105 static void
106 rb_feed_podcast_properties_dialog_init (RBFeedPodcastPropertiesDialog *dialog)
107 {
108 GtkWidget *content_area;
109 GtkBuilder *builder;
110
111 dialog->priv = RB_FEED_PODCAST_PROPERTIES_DIALOG_GET_PRIVATE (dialog);
112
113 g_signal_connect_object (G_OBJECT (dialog),
114 "response",
115 G_CALLBACK (rb_feed_podcast_properties_dialog_response_cb),
116 dialog, 0);
117
118 gtk_window_set_default_size (GTK_WINDOW (dialog), 600, 400);
119 content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
120
121 gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
122 gtk_box_set_spacing (GTK_BOX (content_area), 2);
123
124 builder = rb_builder_load ("podcast-feed-properties.ui", dialog);
125
126 gtk_container_add (GTK_CONTAINER (content_area),
127 GTK_WIDGET (gtk_builder_get_object (builder, "podcastproperties")));
128
129 dialog->priv->close_button = gtk_dialog_add_button (GTK_DIALOG (dialog),
130 GTK_STOCK_CLOSE,
131 GTK_RESPONSE_CLOSE);
132 gtk_dialog_set_default_response (GTK_DIALOG (dialog),
133 GTK_RESPONSE_CLOSE);
134
135 /* get the widgets from the builder */
136 dialog->priv->title = GTK_WIDGET (gtk_builder_get_object (builder, "titleLabel"));
137 dialog->priv->author = GTK_WIDGET (gtk_builder_get_object (builder, "authorLabel"));
138 dialog->priv->location = GTK_WIDGET (gtk_builder_get_object (builder, "locationLabel"));
139 dialog->priv->language = GTK_WIDGET (gtk_builder_get_object (builder, "languageLabel"));
140 dialog->priv->last_update = GTK_WIDGET (gtk_builder_get_object (builder, "lastupdateLabel"));
141 dialog->priv->last_episode = GTK_WIDGET (gtk_builder_get_object (builder, "lastepisodeLabel"));
142 dialog->priv->copyright = GTK_WIDGET (gtk_builder_get_object (builder, "copyrightLabel"));
143 dialog->priv->summary = GTK_WIDGET (gtk_builder_get_object (builder, "summaryLabel"));
144
145 rb_builder_boldify_label (builder, "titleDescLabel");
146 rb_builder_boldify_label (builder, "authorDescLabel");
147 rb_builder_boldify_label (builder, "locationDescLabel");
148 rb_builder_boldify_label (builder, "languageDescLabel");
149 rb_builder_boldify_label (builder, "lastupdateDescLabel");
150 rb_builder_boldify_label (builder, "lastepisodeDescLabel");
151 rb_builder_boldify_label (builder, "copyrightDescLabel");
152 rb_builder_boldify_label (builder, "summaryDescLabel");
153
154 g_object_unref (builder);
155 }
156
157 static void
158 rb_feed_podcast_properties_dialog_finalize (GObject *object)
159 {
160 RBFeedPodcastPropertiesDialog *dialog;
161
162 g_return_if_fail (object != NULL);
163 g_return_if_fail (RB_IS_FEED_PODCAST_PROPERTIES_DIALOG (object));
164
165 dialog = RB_FEED_PODCAST_PROPERTIES_DIALOG (object);
166
167 g_return_if_fail (dialog->priv != NULL);
168
169 G_OBJECT_CLASS (rb_feed_podcast_properties_dialog_parent_class)->finalize (object);
170 }
171
172 GtkWidget *
173 rb_feed_podcast_properties_dialog_new (RhythmDBEntry *entry)
174 {
175 RBFeedPodcastPropertiesDialog *dialog;
176
177 dialog = g_object_new (RB_TYPE_FEED_PODCAST_PROPERTIES_DIALOG, NULL);
178 dialog->priv->current_entry = entry;
179
180 rb_feed_podcast_properties_dialog_update (dialog);
181
182 return GTK_WIDGET (dialog);
183 }
184
185 static void
186 rb_feed_podcast_properties_dialog_response_cb (GtkDialog *gtkdialog,
187 int response_id,
188 RBFeedPodcastPropertiesDialog *dialog)
189 {
190 gtk_widget_destroy (GTK_WIDGET (dialog));
191 }
192
193 static void
194 rb_feed_podcast_properties_dialog_update (RBFeedPodcastPropertiesDialog *dialog)
195 {
196 g_return_if_fail (dialog->priv->current_entry != NULL);
197
198 rb_feed_podcast_properties_dialog_update_location (dialog);
199 rb_feed_podcast_properties_dialog_update_title (dialog);
200 rb_feed_podcast_properties_dialog_update_title_label (dialog);
201 rb_feed_podcast_properties_dialog_update_author (dialog);
202 rb_feed_podcast_properties_dialog_update_language (dialog);
203 rb_feed_podcast_properties_dialog_update_last_update (dialog);
204 rb_feed_podcast_properties_dialog_update_last_episode (dialog);
205 rb_feed_podcast_properties_dialog_update_copyright (dialog);
206 rb_feed_podcast_properties_dialog_update_summary (dialog);
207 }
208
209 static void
210 rb_feed_podcast_properties_dialog_update_title (RBFeedPodcastPropertiesDialog *dialog)
211 {
212 const char *name;
213 char *tmp;
214 name = rhythmdb_entry_get_string (dialog->priv->current_entry, RHYTHMDB_PROP_TITLE);
215 tmp = g_strdup_printf (_("%s Properties"), name);
216 gtk_window_set_title (GTK_WINDOW (dialog), tmp);
217 g_free (tmp);
218 }
219
220 static void
221 rb_feed_podcast_properties_dialog_update_title_label (RBFeedPodcastPropertiesDialog *dialog)
222 {
223 const char *title;
224
225 title = rhythmdb_entry_get_string (dialog->priv->current_entry, RHYTHMDB_PROP_TITLE);
226 gtk_label_set_text (GTK_LABEL (dialog->priv->title), title);
227 }
228
229 static void
230 rb_feed_podcast_properties_dialog_update_author (RBFeedPodcastPropertiesDialog *dialog)
231 {
232 const char *artist;
233
234 artist = rhythmdb_entry_get_string (dialog->priv->current_entry, RHYTHMDB_PROP_ARTIST);
235 gtk_label_set_text (GTK_LABEL (dialog->priv->author), artist);
236 }
237
238 static void
239 rb_feed_podcast_properties_dialog_update_location (RBFeedPodcastPropertiesDialog *dialog)
240 {
241 const char *location;
242 char *unescaped;
243
244 location = rhythmdb_entry_get_string (dialog->priv->current_entry, RHYTHMDB_PROP_MOUNTPOINT);
245 if (location == NULL)
246 location = rhythmdb_entry_get_string (dialog->priv->current_entry, RHYTHMDB_PROP_LOCATION);
247 unescaped = g_uri_unescape_string (location, NULL);
248 gtk_label_set_text (GTK_LABEL (dialog->priv->location), unescaped);
249 g_free (unescaped);
250 }
251
252 static void
253 rb_feed_podcast_properties_dialog_update_copyright (RBFeedPodcastPropertiesDialog *dialog)
254 {
255 const char *copyright;
256
257 copyright = rhythmdb_entry_get_string (dialog->priv->current_entry, RHYTHMDB_PROP_COPYRIGHT);
258 gtk_label_set_text (GTK_LABEL (dialog->priv->copyright), copyright);
259 }
260
261 static void
262 rb_feed_podcast_properties_dialog_update_language (RBFeedPodcastPropertiesDialog *dialog)
263 {
264 const char *language;
265 char *separator;
266 char *iso636lang;
267 const char *langname;
268
269 language = rhythmdb_entry_get_string (dialog->priv->current_entry, RHYTHMDB_PROP_LANG);
270
271 /* language tag is language[-subcode]; we only care about the language bit */
272 iso636lang = g_strdup (language);
273 separator = strchr (iso636lang, '-');
274 if (separator != NULL) {
275 *separator = '\0';
276 }
277
278 /* map the language code to a language name */
279 langname = gst_tag_get_language_name (iso636lang);
280 g_free (iso636lang);
281 if (langname != NULL) {
282 rb_debug ("mapped language code %s to %s", language, langname);
283 gtk_label_set_text (GTK_LABEL (dialog->priv->language), langname);
284 return;
285 }
286
287 gtk_label_set_text (GTK_LABEL (dialog->priv->language), language);
288 }
289
290 static void
291 rb_feed_podcast_properties_dialog_update_last_update (RBFeedPodcastPropertiesDialog *dialog)
292 {
293 char *time_str;
294 gulong time_val;
295
296 time_val = rhythmdb_entry_get_ulong (dialog->priv->current_entry, RHYTHMDB_PROP_LAST_SEEN);
297 time_str = rb_feed_podcast_properties_dialog_parse_time (time_val);
298 gtk_label_set_text (GTK_LABEL (dialog->priv->last_update), time_str);
299 g_free (time_str);
300 }
301
302 static void
303 rb_feed_podcast_properties_dialog_update_last_episode (RBFeedPodcastPropertiesDialog *dialog)
304 {
305 char *time_str;
306 gulong time_val;
307
308 time_val = rhythmdb_entry_get_ulong (dialog->priv->current_entry, RHYTHMDB_PROP_POST_TIME);
309 time_str = rb_feed_podcast_properties_dialog_parse_time (time_val);
310 gtk_label_set_text (GTK_LABEL (dialog->priv->last_episode), time_str);
311 g_free (time_str);
312 }
313
314 static void
315 rb_feed_podcast_properties_dialog_update_summary (RBFeedPodcastPropertiesDialog *dialog)
316 {
317 const char *summary;
318
319 summary = rhythmdb_entry_get_string (dialog->priv->current_entry,
320 RHYTHMDB_PROP_SUMMARY);
321 if (summary == NULL) {
322 summary = rhythmdb_entry_get_string (dialog->priv->current_entry,
323 RHYTHMDB_PROP_DESCRIPTION);
324 }
325 if (summary == NULL) {
326 summary = rhythmdb_entry_get_string (dialog->priv->current_entry,
327 RHYTHMDB_PROP_SUBTITLE);
328 }
329
330 gtk_label_set_text (GTK_LABEL (dialog->priv->summary), summary);
331 }
332
333 static char *
334 rb_feed_podcast_properties_dialog_parse_time (gulong value)
335 {
336 char *str;
337
338 if (0 == value) {
339 str = g_strdup (_("Unknown"));
340 } else {
341 str = rb_utf_friendly_time ((time_t)value);
342 }
343
344 return str;
345 }