1
## Description: Redesigned 'Gnomeradio recording status' window to show more recording information.
2
## Origin: upstream, no
3
## Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/gnomeradio/+bug/1019981
4
## Author: Pojar George <geoubuntu@gmail.com>
6
Index: gnomeradio-1.8/src/record.c
7
===================================================================
8
--- gnomeradio-1.8.orig/src/record.c 2012-07-18 02:19:56.276969089 +0000
9
+++ gnomeradio-1.8/src/record.c 2012-07-18 02:23:05.176973499 +0000
13
static int timeout_id = -1;
14
-static GtkWidget *file_lbl, *size_lbl;
15
+static GtkWidget *file_lbl, *length_lbl, *size_lbl;
16
static GtkWidget *status_dialog;
18
+extern GtkWidget *level;
20
void close_status_window(void)
24
tray_icon_items_set_sensible(TRUE);
27
+static char *seconds_to_full_string (guint seconds)
29
+ long days, hours, minutes;
31
+ const char *minutefmt;
32
+ const char *hourfmt;
33
+ const char *secondfmt;
35
+ days = seconds / (60 * 60 * 24);
36
+ hours = (seconds / (60 * 60));
37
+ minutes = (seconds / 60) - ((days * 24 * 60) + (hours * 60));
38
+ seconds = seconds % 60;
40
+ minutefmt = ngettext ("%ld minute", "%ld minutes", minutes);
41
+ hourfmt = ngettext ("%ld hour", "%ld hours", hours);
42
+ secondfmt = ngettext ("%ld second", "%ld seconds", seconds);
48
+ /* Translators: the format is "X hours X minutes X seconds" */
49
+ fmt = g_strdup_printf (_("%s %s %s"), hourfmt, minutefmt, secondfmt);
50
+ time = g_strdup_printf (fmt, hours, minutes, seconds);
54
+ /* Translators: the format is "X hours X minutes" */
55
+ fmt = g_strdup_printf (_("%s %s"), hourfmt, minutefmt);
56
+ time = g_strdup_printf (fmt, hours, minutes);
62
+ /* Translators: the format is "X minutes X seconds" */
63
+ fmt = g_strdup_printf (_("%s %s"), minutefmt, secondfmt);
64
+ time = g_strdup_printf (fmt, minutes, seconds);
67
+ time = g_strdup_printf (minutefmt, minutes);
73
+ /* Translators: the format is "X minutes X seconds" */
74
+ fmt = g_strdup_printf (_("%s %s"), minutefmt, secondfmt);
75
+ time = g_strdup_printf (fmt, minutes, seconds);
78
+ time = g_strdup_printf (minutefmt, minutes);
82
+ time = g_strdup_printf (secondfmt, seconds);
89
static gboolean timeout_cb(gpointer data)
91
Recording *recording = data;
95
+ gchar *utf8_name = NULL;
99
if (!gtk_widget_get_visible(status_dialog))
100
gtk_widget_show_all(status_dialog);
103
+ name = g_path_get_basename(recording->filename);
104
+ utf8_name = g_filename_to_utf8 (name, -1, NULL, NULL, NULL);
105
+ gtk_label_set_text(GTK_LABEL(file_lbl), utf8_name);
109
+ GstElement *pipeline;
110
+ GstFormat fmt = GST_FORMAT_TIME;
114
+ pipeline = recording->pipeline;
116
+ if (gst_element_query_position (pipeline, &fmt, &val) && val != -1) {
118
+ secs = val / GST_SECOND;
120
+ length = seconds_to_full_string(secs);
121
+ gtk_label_set_text(GTK_LABEL(length_lbl), length);
126
s = get_file_size(recording->filename);
128
- if (s < 1024) size = g_strdup_printf(_("%i byte"), s);
130
- if ((s >= 1024) && (s < 1024*1024)) size = g_strdup_printf(_("%i kB"), s>>10);
131
- if (s >= 1024*1024) size = g_strdup_printf(_("%.2f MB"), (float)s/1024/1024);
133
- if (s) size = g_strdup(_("Error"));
134
- else size = g_strdup(_("0 byte"));
136
+ size = g_format_size_full(s, G_FORMAT_SIZE_LONG_FORMAT);
138
+ close_status_window();
139
+ recording_stop(recording);
142
+ text = g_strdup_printf(_("Error writing to file \"%s\"!"), utf8_name);
144
+ detail = g_strdup_printf("Please check for sufficient write file permissions.");
145
+ show_error_message(text, detail);
146
+ g_free (utf8_name);
153
- gtk_label_set_text(GTK_LABEL(file_lbl), recording->filename);
155
gtk_label_set_text(GTK_LABEL(size_lbl), size);
162
+static void expander_callback_cb (GtkExpander *expander, gpointer data)
164
+ if (gtk_expander_get_expanded (expander))
165
+ gtk_expander_set_label (expander, _("Hide details"));
167
+ gtk_expander_set_label (expander, _("Show details"));
170
GtkWidget* record_status_window(Recording *recording)
172
GtkWidget *btn_label, *btn_pixmap, *button;
173
GtkWidget *vbox, *btn_box, *hbox;
175
- GtkWidget *title, *f_lbl, *s_lbl;
176
+ GtkWidget *title, *f_lbl, *l_lbl, *s_lbl;
177
+ GtkIconTheme *theme;
179
+ GtkWidget *box, *image, *r_grid;
180
+ GtkWidget *level_box, *lbox;
181
+ GtkWidget *expander;
184
status_dialog = gtk_window_new(GTK_WINDOW_TOPLEVEL);
185
gtk_window_set_title(GTK_WINDOW(status_dialog),_("Gnomeradio recording status"));
186
- /*gtk_window_set_resizable(GTK_WINDOW(status_dialog), FALSE);*/
187
- gtk_window_set_default_size(GTK_WINDOW(status_dialog), 400, -1);
188
+ gtk_window_set_resizable(GTK_WINDOW(status_dialog), FALSE);
190
vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
191
- gtk_container_set_border_width(GTK_CONTAINER(vbox), 6);
192
+ gtk_container_set_border_width(GTK_CONTAINER(vbox), 8);
194
+ grid = gtk_grid_new();
195
+ gtk_grid_set_row_spacing(GTK_GRID(grid), 5);
196
+ gtk_grid_set_column_spacing(GTK_GRID(grid), 15);
197
+ gtk_container_set_border_width(GTK_CONTAINER(grid), 5);
199
+ box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
200
+ theme = gtk_icon_theme_get_default();
201
+ pixbuf = gtk_icon_theme_load_icon(theme, "gnomeradio", 48, 0, NULL);
202
+ image = gtk_image_new_from_pixbuf (pixbuf);
203
+ gtk_container_add (GTK_CONTAINER (box), image);
204
+ gtk_grid_attach(GTK_GRID(grid), box, 0, 0, 1, 2);
206
- grid = gtk_grid_new();
207
- gtk_grid_set_row_spacing(GTK_GRID(grid), 10);
208
- gtk_grid_set_column_spacing(GTK_GRID(grid), 12);
209
- gtk_container_set_border_width(GTK_CONTAINER(grid), 6);
211
str = g_strdup_printf(_("Recording from station %s"), recording->station);
212
text = g_strdup_printf("<b><big>%s</big></b>", str);
214
title = gtk_label_new(text);
216
+ gtk_misc_set_alignment(GTK_MISC(title), 0.0, 0.0);
217
gtk_label_set_use_markup(GTK_LABEL(title), TRUE);
219
- text = g_strdup_printf(" <b>%s</b>", _("Destination:"));
220
- f_lbl = gtk_label_new(text);
222
- gtk_label_set_use_markup(GTK_LABEL(f_lbl), TRUE);
223
+ gtk_grid_attach(GTK_GRID(grid), title, 1, 0, 1, 1);
225
+ level_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 10);
227
+ level = gtk_progress_bar_new();
228
+ lbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
229
+ gtk_box_pack_start(GTK_BOX (lbox), level, TRUE, FALSE, 0);
230
+ gtk_box_pack_start(GTK_BOX (level_box), lbox, TRUE, TRUE, 0);
231
+ gtk_grid_attach(GTK_GRID(grid), level_box, 1, 1, 1, 1);
233
+ expander = gtk_expander_new(_("Show details"));
234
+ gtk_grid_attach(GTK_GRID(grid), expander, 1, 2, 1, 1);
236
+ g_signal_connect (expander, "notify::expanded", G_CALLBACK (expander_callback_cb), NULL);
238
+ r_grid = gtk_grid_new();
239
+ gtk_grid_set_row_spacing(GTK_GRID(r_grid), 5);
240
+ gtk_grid_set_column_spacing(GTK_GRID(r_grid), 15);
241
+ gtk_container_set_border_width(GTK_CONTAINER(r_grid), 5);
243
+ f_lbl = gtk_label_new(_("Name:"));
244
+ gtk_misc_set_alignment(GTK_MISC(f_lbl), 0.0, 0.5);
245
+ gtk_grid_attach(GTK_GRID(r_grid), f_lbl, 0, 0, 1, 1);
247
+ l_lbl = gtk_label_new(_("Length:"));
248
+ gtk_misc_set_alignment(GTK_MISC(l_lbl), 0.0, 0.5);
249
+ gtk_grid_attach(GTK_GRID(r_grid), l_lbl, 0, 1, 1, 1);
251
+ s_lbl = gtk_label_new(_("Size:"));
252
+ gtk_misc_set_alignment(GTK_MISC(s_lbl), 0.0, 0.5);
253
+ gtk_grid_attach(GTK_GRID(r_grid), s_lbl, 0, 2, 1, 1);
255
- text = g_strdup_printf(" <b>%s</b>", _("Filesize:"));
256
- s_lbl = gtk_label_new(text);
258
- gtk_label_set_use_markup(GTK_LABEL(s_lbl), TRUE);
260
file_lbl = gtk_label_new("");
261
gtk_label_set_ellipsize(GTK_LABEL(file_lbl), PANGO_ELLIPSIZE_START);
262
- gtk_widget_set_hexpand(file_lbl, TRUE);
263
- gtk_widget_set_halign(file_lbl, GTK_ALIGN_FILL);
264
+ gtk_misc_set_alignment(GTK_MISC(file_lbl), 0.0, 0.5);
265
+ gtk_grid_attach(GTK_GRID(r_grid), file_lbl, 1, 0, 1, 1);
267
+ length_lbl = gtk_label_new("");
268
+ gtk_misc_set_alignment(GTK_MISC(length_lbl), 0.0, 0.5);
269
+ gtk_grid_attach(GTK_GRID(r_grid), length_lbl, 1, 1, 1, 1);
271
size_lbl = gtk_label_new("");
272
- gtk_widget_set_hexpand(size_lbl, TRUE);
273
- gtk_widget_set_halign(size_lbl, GTK_ALIGN_FILL);
275
- gtk_misc_set_alignment(GTK_MISC(title), 0.0f, 0.0f);
276
- gtk_misc_set_alignment(GTK_MISC(f_lbl), 1.0f, 0.5f);
277
- gtk_misc_set_alignment(GTK_MISC(s_lbl), 1.0f, 0.5f);
278
- gtk_misc_set_alignment(GTK_MISC(file_lbl), 0.0f, 0.5f);
279
- gtk_misc_set_alignment(GTK_MISC(size_lbl), 0.0f, 0.5f);
281
- gtk_grid_attach(GTK_GRID(grid), title, 0, 0, 2, 1);
282
- gtk_grid_attach(GTK_GRID(grid), f_lbl, 0, 1, 1, 1);
283
- gtk_grid_attach(GTK_GRID(grid), s_lbl, 0, 2, 1, 1);
284
+ gtk_misc_set_alignment(GTK_MISC(size_lbl), 0.0, 0.5);
285
+ gtk_grid_attach(GTK_GRID(r_grid), size_lbl, 1, 2, 1, 1);
287
- gtk_grid_attach(GTK_GRID(grid), file_lbl, 1, 1, 1, 1);
288
- gtk_grid_attach(GTK_GRID(grid), size_lbl, 1, 2, 1, 1);
289
+ gtk_container_add(GTK_CONTAINER(expander), r_grid);
291
button = gtk_button_new();
292
btn_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
293
@@ -169,10 +301,11 @@
294
hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
295
gtk_box_pack_end (GTK_BOX(hbox), button, TRUE, FALSE, 0);
297
- gtk_box_pack_start (GTK_BOX(vbox), grid, TRUE, TRUE, 0);
298
+ gtk_box_pack_start(GTK_BOX(vbox), grid, TRUE, TRUE, 0);
299
gtk_box_pack_start (GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
301
gtk_container_add(GTK_CONTAINER(status_dialog), vbox);
302
+ gtk_widget_grab_focus (button);
304
g_signal_connect(G_OBJECT(status_dialog), "delete_event", G_CALLBACK(delete_event_cb), recording);
305
g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(button_clicked_cb), recording);
306
Index: gnomeradio-1.8/src/gui.c
307
===================================================================
308
--- gnomeradio-1.8.orig/src/gui.c 2012-07-18 02:19:56.256969089 +0000
309
+++ gnomeradio-1.8/src/gui.c 2012-07-18 02:21:53.440971824 +0000
313
/* consult man strftime to translate this. This is a filename, so don't use "/" or ":", please */
314
- strftime(time_str, 100, _("%B-%d-%Y_%H-%M-%S"), localtime(&t));
315
+ strftime(time_str, 100, _("%Y%m%d-%H%M%S"), localtime(&t));
318
station = g_strdup_printf(_("%.2f MHz"), rint(gtk_adjustment_get_value(adj))/STEPS);
319
Index: gnomeradio-1.8/src/rec_tech.c
320
===================================================================
321
--- gnomeradio-1.8.orig/src/rec_tech.c 2012-07-18 02:19:56.248969088 +0000
322
+++ gnomeradio-1.8/src/rec_tech.c 2012-07-18 02:21:53.440971824 +0000
324
#include <sys/stat.h>
329
-static void error_cb(GstBus *bus, GstMessage *message, gpointer user_data)
333
+show_error_dialog (GtkWindow *win, const gchar *dbg, const gchar * format, ...)
339
+ va_start (args, format);
340
+ s = g_strdup_vprintf (format, args);
343
+ dialog = gtk_message_dialog_new (win,
344
+ GTK_DIALOG_DESTROY_WITH_PARENT,
351
+ g_printerr ("ERROR: %s\nDEBUG MESSAGE: %s\n", s, dbg);
354
+ gtk_dialog_run (GTK_DIALOG (dialog));
355
+ gtk_widget_destroy (dialog);
360
+show_missing_known_element_error (GtkWindow *win, gchar *description,
361
+ gchar *element, gchar *plugin, gchar *module)
363
+ show_error_dialog (win, NULL,
364
+ _("Could not create the GStreamer %s element.\n"
365
+ "Please install the '%s' plugin from the '%s' module.\n"
366
+ "Verify that the installation is correct by running\n"
367
+ " gst-inspect-0.10 %s\n"
368
+ "and then restart gnome-sound-recorder."),
369
+ description, plugin, module, element);
373
+show_profile_error (GtkWindow *win, gchar *debug, gchar *description,
374
+ const char *profile)
378
+ first = g_strdup_printf (description, profile);
379
+ show_error_dialog (win, debug, "%s%s", first,
380
+ _("Please verify its settings.\n"
381
+ "You may be missing the necessary plugins."));
385
+static void pipeline_error_cb(GstBus *bus, GstMessage *message, gpointer user_data)
387
GError *error = NULL;
388
GstElement *pipeline = user_data;
394
+level_message_handler_cb (GstBus *bus, GstMessage *message, gpointer user_data)
396
+ if (message->type == GST_MESSAGE_ELEMENT) {
397
+ const GstStructure *s = gst_message_get_structure (message);
398
+ const gchar *name = gst_structure_get_name (s);
400
+ if (g_str_equal (name, "level")) {
404
+ const GValue *list;
405
+ const GValue *value;
408
+ /* we can get the number of channels as the length of any of the value
411
+ list = gst_structure_get_value (s, "rms");
412
+ channels = gst_value_list_get_size (list);
414
+ for (i = 0; i < channels; ++i) {
415
+ list = gst_structure_get_value (s, "peak");
416
+ value = gst_value_list_get_value (list, i);
417
+ peak_dB = g_value_get_double (value);
418
+ myind = exp (peak_dB / 20);
421
+ gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (level), myind);
425
+ /* we handled the message we want, and ignored the ones we didn't want.
426
+ * so the core can unref the message for us */
431
recording_start(const char* filename)
433
GMAudioProfile *profile;
434
- GstElement *pipeline, *source, *encoder, *filesink;
435
- pipeline = source = encoder = filesink = NULL;
437
- profile = gm_audio_profile_lookup(rec_settings.profile);
440
+ const gchar *profile_pipeline_desc;
441
+ GstElement *pipeline, *source, *encoder, *filesink, *level;
442
+ pipeline = source = encoder = filesink = level = NULL;
443
+ GError *err = NULL;
444
+ gchar *pipeline_desc;
447
+ source = gst_element_factory_make ("gconfaudiosrc", "gconfaudiosource");
448
+ if (source == NULL) {
449
+ show_missing_known_element_error (NULL,
450
+ _("GConf audio recording"), "gconfaudiosrc",
451
+ "gconfelements", "gst-plugins-good");
455
+ if (!gst_element_set_state (source, GST_STATE_READY)) {
456
+ show_error_dialog (NULL, NULL,
457
+ _("Your audio capture settings are invalid. "
458
+ "Please correct them with the \"Sound Preferences\" "
459
+ "under the System Preferences menu."));
463
+ filesink = gst_element_factory_make ("filesink", "sink");
464
+ if (filesink == NULL)
466
+ show_missing_known_element_error (NULL,
467
+ _("file output"), "filesink", "coreelements",
469
+ gst_object_unref (source);
473
pipeline = gst_pipeline_new("gnomeradio-record-pipeline");
475
- g_warning(_("Could not create GStreamer pipeline. Check your Gstreamer installation!\n"));
479
- source = gst_element_factory_make("autoaudiosrc", "audio_source");
481
- g_warning(_("Could not open Gstreamer AUDIO Source. Verify your Gstreamer AUDIO subsystem installation!\n"));
484
+ gst_bin_add (GST_BIN (pipeline), source);
486
+ level = gst_element_factory_make ("level", "level");
489
+ show_missing_known_element_error (NULL,
490
+ _("level"), "level", "level",
492
+ gst_object_unref (source);
496
- GstBus *bus = gst_element_get_bus(pipeline);
497
- gst_bus_add_signal_watch(bus);
498
- g_signal_connect(G_OBJECT(bus), "message::error", G_CALLBACK(error_cb), pipeline);
499
+ gst_element_set_name (level, "level");
501
+ profile = gm_audio_profile_lookup(rec_settings.profile);
503
+ if (profile == NULL)
505
+ profile_pipeline_desc = gm_audio_profile_get_pipeline (profile);
506
+ name = gm_audio_profile_get_name (profile);
508
+ GST_DEBUG ("encoder profile pipeline: '%s'",
509
+ GST_STR_NULL (profile_pipeline_desc));
511
- char* pipeline_str = g_strdup_printf("audioconvert ! %s", gm_audio_profile_get_pipeline(profile));
512
- encoder = gst_parse_bin_from_description(pipeline_str, TRUE, NULL);
513
- g_free(pipeline_str);
515
- char *caption = g_strdup_printf(_("Could not create encoder \"%s\"."), gm_audio_profile_get_name (profile));
516
- g_warning(_("%s Verify your Gstreamer plugins installation!\n"), caption);
519
+ pipeline_desc = g_strdup_printf ("audioconvert ! %s", profile_pipeline_desc);
520
+ GST_DEBUG ("making encoder bin from description '%s'", pipeline_desc);
521
+ encoder = gst_parse_bin_from_description (pipeline_desc, TRUE, &err);
522
+ g_free (pipeline_desc);
523
+ pipeline_desc = NULL;
526
+ show_profile_error (NULL, err->message,
527
+ _("Could not parse the '%s' audio profile. "), name);
528
+ g_printerr ("Failed to create GStreamer encoder plugins [%s]: %s\n",
529
+ profile_pipeline_desc, err->message);
530
+ g_error_free (err);
531
+ gst_object_unref (pipeline);
532
+ gst_object_unref (filesink);
537
- /* Write to disk */
538
- filesink = gst_element_factory_make("filesink", "file-sink");
540
- g_warning(_("Could not create Gstreamer filesink. Check your Gstreamer installation!"));
543
+ gst_bin_add (GST_BIN (pipeline), level);
544
+ gst_bin_add (GST_BIN (pipeline), encoder);
545
+ gst_bin_add (GST_BIN (pipeline), filesink);
547
+ if (!(gst_element_link_many (source, level, encoder, NULL))) {
548
+ show_profile_error (NULL, NULL,
549
+ _("Could not capture using the '%s' audio profile. "),
551
+ gst_object_unref (pipeline);
556
- /* Add the elements to the pipeline */
557
- gst_bin_add_many(GST_BIN(pipeline), source, encoder, filesink, NULL);
559
- /* Link it all together */
560
- if (!gst_element_link_many(source, encoder, filesink, NULL)) {
561
- g_warning("Could not link elements. This is bad!\n");
564
+ if (!gst_element_link (encoder, filesink)) {
565
+ show_profile_error (NULL, NULL,
566
+ _("Could not write to a file using the '%s' audio profile. "),
568
+ gst_object_unref (pipeline);
573
+ GstBus *bus = gst_element_get_bus(pipeline);
574
+ gst_bus_add_signal_watch(bus);
576
+ g_signal_connect(G_OBJECT(bus), "message::error",
577
+ G_CALLBACK(pipeline_error_cb),
580
+ g_signal_connect (G_OBJECT(bus), "message::element",
581
+ G_CALLBACK (level_message_handler_cb),
584
char* path = g_strdup_printf("%s.%s", filename, gm_audio_profile_get_extension(profile));
585
g_object_set(G_OBJECT(filesink), "location", path, NULL);
588
recording->pipeline = pipeline;
594
- gst_object_unref(GST_OBJECT(pipeline));
596
- gst_object_unref(GST_OBJECT(source));
598
- gst_object_unref(GST_OBJECT(encoder));
600
- gst_object_unref(GST_OBJECT(filesink));
608
gst_element_get_state(recording->pipeline, &state, NULL, GST_CLOCK_TIME_NONE);
609
if (state != GST_STATE_PLAYING) {
611
+ GST_DEBUG ("pipeline in wrong state: %s",
612
+ gst_element_state_get_name (state));
614
gst_element_set_state(recording->pipeline, GST_STATE_NULL);