2
* This program is free software; you can redistribute it and/or modify
3
* it under the terms of the GNU General Public License as published by
4
* the Free Software Foundation; either version 2 of the License, or
5
* (at your option) any later version.
7
* This program is distributed in the hope that it will be useful,
8
* but WITHOUT ANY WARRANTY; without even the implied warranty of
9
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
* GNU Library General Public License for more details.
12
* You should have received a copy of the GNU General Public License
13
* along with this program; if not, write to the Free Software
14
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
#include <gconf/gconf-client.h>
18
#include <glib/gi18n.h>
20
#include <gst/pbutils/pbutils.h>
21
#include <gst/pbutils/install-plugins.h>
22
#include <libxml/xmlmemory.h>
23
#include <libxml/parser.h>
30
#include "rb_gst_media_types.h"
31
#include "rb_missing_plugins.h"
32
#include "alsa_stream.h"
34
extern int autodetect;
35
extern int alsa_loopback;
37
extern GtkWidget *preset_combo;
38
extern GtkAdjustment *adj;
41
extern gnomeradio_settings settings;
43
extern gboolean main_visible;
45
static GtkWidget *device_entry;
46
static GtkWidget *mixer_entry;
47
static GtkWidget *audio_label;
48
static GtkWidget *enabled;
49
static GtkWidget *disabled;
50
static GtkWidget *mute_on_exit;
51
static GtkWidget *list_view;
52
static GtkListStore *list_store;
53
static GtkTreeSelection *selection;
54
static GtkWidget *save_button;
55
static GtkWidget *move_up_button;
56
static GtkWidget *move_down_button;
57
static GtkWidget *add_button;
58
static GtkWidget *remove_button;
59
static GtkWidget *audio_profile_combo;
60
static GtkWidget *install_button;
62
gboolean save_settings(void)
67
GConfClient* client = NULL;
69
if (!gconf_is_initialized())
72
client = gconf_client_get_default();
76
/* Store general settings */
78
gconf_client_set_string(client, "/apps/gnomeradio/device", "auto", NULL);
80
gconf_client_set_string(client, "/apps/gnomeradio/device", settings.device, NULL);
81
gconf_client_set_string(client, "/apps/gnomeradio/driver", settings.driver, NULL);
82
gconf_client_set_string(client, "/apps/gnomeradio/mixer", settings.mixer, NULL);
83
gconf_client_set_bool(client, "/apps/gnomeradio/audio-loopback", settings.audio_loopback , NULL);
84
gconf_client_set_bool(client, "/apps/gnomeradio/mute-on-exit", settings.mute_on_exit, NULL);
85
/*gconf_client_set_float(client, "/apps/gnomeradio/volume", volume->value, NULL);*/
86
gconf_client_set_float(client, "/apps/gnomeradio/last-freq", gtk_adjustment_get_value(adj)/STEPS, NULL);
88
/* Store recording settings */
89
/* gconf_client_set_string(client, "/apps/gnomeradio/recording/audiodevice", rec_settings.audiodevice, NULL);
90
gconf_client_set_bool(client, "/apps/gnomeradio/recording/record-as-mp3", rec_settings.mp3, NULL);
91
gconf_client_set_string(client, "/apps/gnomeradio/recording/sample-rate", rec_settings.rate, NULL);
92
gconf_client_set_string(client, "/apps/gnomeradio/recording/sample-format", rec_settings.sample, NULL);
93
gconf_client_set_bool(client, "/apps/gnomeradio/recording/record-in-stereo", rec_settings.stereo, NULL);
94
gconf_client_set_string(client, "/apps/gnomeradio/recording/encoder", rec_settings.encoder, NULL);
95
gconf_client_set_string(client, "/apps/gnomeradio/recording/bitrate", rec_settings.bitrate, NULL);
98
gconf_client_set_string(client, "/apps/gnomeradio/recording/destination", rec_settings.destination, NULL);
99
gconf_client_set_string(client, "/apps/gnomeradio/recording/profile", rec_settings.profile, NULL);
101
/* Store the presets */
102
count = g_list_length(settings.presets);
103
gconf_client_set_int(client, "/apps/gnomeradio/presets/presets", count, NULL);
104
for (i = 0; i < count; i++)
106
ps = g_list_nth_data(settings.presets, i);
107
buffer = g_strdup_printf("/apps/gnomeradio/presets/%d/name", i);
108
gconf_client_set_string(client, buffer, ps->title, NULL);
110
buffer = g_strdup_printf("/apps/gnomeradio/presets/%d/freqency", i);
111
gconf_client_set_float(client, buffer, ps->freq, NULL);
114
gconf_client_set_int(client, "/apps/gnomeradio/presets/last", mom_ps, NULL);
115
/*g_print("Storing Settings in GConf database\n");*/
120
gboolean load_settings(void)
125
GConfClient *client = NULL;
128
settings.presets = NULL;
130
if (!gconf_is_initialized())
133
client = gconf_client_get_default();
137
/* Load general settings */
138
settings.device = gconf_client_get_string(client, "/apps/gnomeradio/device", NULL);
139
if (!settings.device)
140
settings.device = g_strdup("auto");
141
settings.driver = gconf_client_get_string(client, "/apps/gnomeradio/driver", NULL);
142
if (!settings.driver)
143
settings.driver = g_strdup("any");
144
settings.mixer = gconf_client_get_string(client, "/apps/gnomeradio/mixer", NULL);
146
settings.mixer = g_strdup("hw:0/Line");
147
settings.audio_loopback = gconf_client_get_bool(client, "/apps/gnomeradio/audio-loopback", NULL);
148
settings.mute_on_exit = gconf_client_get_bool(client, "/apps/gnomeradio/mute-on-exit", NULL);
149
/*volume->value = gconf_client_get_float(client, "/apps/gnomeradio/volume", NULL);*/
150
freq = gconf_client_get_float(client, "/apps/gnomeradio/last-freq", NULL);
151
if ((freq < FREQ_MIN) || (freq > FREQ_MAX))
152
gtk_adjustment_set_value(adj, FREQ_MIN * STEPS);
154
gtk_adjustment_set_value(adj, freq * STEPS);
156
/* Load recording settings */
157
/* rec_settings.audiodevice = gconf_client_get_string(client, "/apps/gnomeradio/recording/audiodevice", NULL);
158
if (!rec_settings.audiodevice)
159
rec_settings.audiodevice = g_strdup("/dev/audio");
160
rec_settings.mp3 = gconf_client_get_bool(client, "/apps/gnomeradio/recording/record-as-mp3", NULL);
161
rec_settings.rate = gconf_client_get_string(client, "/apps/gnomeradio/recording/sample-rate", NULL);
162
if (!rec_settings.rate)
163
rec_settings.rate = g_strdup("44100");
164
rec_settings.sample = gconf_client_get_string(client, "/apps/gnomeradio/recording/sample-format", NULL);
165
if (!rec_settings.sample)
166
rec_settings.sample = g_strdup("16");
167
rec_settings.stereo = gconf_client_get_bool(client, "/apps/gnomeradio/recording/record-in-stereo", NULL);
168
rec_settings.encoder = gconf_client_get_string(client, "/apps/gnomeradio/recording/encoder", NULL);
169
if (!rec_settings.encoder)
170
rec_settings.encoder = g_strdup("oggenc");
171
rec_settings.bitrate = gconf_client_get_string(client, "/apps/gnomeradio/recording/bitrate", NULL);
172
if (!rec_settings.bitrate)
173
rec_settings.bitrate = g_strdup("192");*/
175
rec_settings.destination = gconf_client_get_string(client, "/apps/gnomeradio/recording/destination", NULL);
176
if (!rec_settings.destination)
177
rec_settings.destination = g_strdup(g_get_home_dir());
178
rec_settings.profile = gconf_client_get_string(client, "/apps/gnomeradio/recording/profile", NULL);
179
if (!rec_settings.profile)
180
rec_settings.profile = g_strdup("audio/x-vorbis");
182
/* Load the presets */
183
count = gconf_client_get_int(client, "/apps/gnomeradio/presets/presets", NULL);
184
for (i = 0; i < count; i++)
186
ps = malloc(sizeof(preset));
187
buffer = g_strdup_printf("/apps/gnomeradio/presets/%d/name", i);
188
ps->title = gconf_client_get_string(client, buffer, NULL);
191
ps->title = g_strdup(_("unnamed"));
192
buffer = g_strdup_printf("/apps/gnomeradio/presets/%d/freqency", i);
193
freq = gconf_client_get_float(client, buffer, NULL);
194
if ((freq < FREQ_MIN) || (freq > FREQ_MAX))
199
settings.presets = g_list_prepend(settings.presets, (gpointer)ps);
201
settings.presets = g_list_reverse(settings.presets);
203
mom_ps = gconf_client_get_int(client, "/apps/gnomeradio/presets/last", NULL);
210
static void mute_on_exit_toggled_cb(GtkWidget* widget, gpointer data)
212
settings.mute_on_exit = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(mute_on_exit));
215
static void audio_loopback_set_visible (gboolean visible)
217
gtk_widget_set_visible (audio_label, visible);
218
gtk_widget_set_visible (enabled, visible);
219
gtk_widget_set_visible (disabled, visible);
222
static void audio_loopback_toggled_cb (GtkWidget* widget, gpointer data)
224
settings.audio_loopback = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (enabled));
226
if (settings.audio_loopback)
227
start_radio(TRUE, data);
232
static gboolean device_entry_activate_cb(GtkWidget *widget, gpointer data)
236
text = gtk_entry_get_text(GTK_ENTRY(device_entry));
238
if (!strcmp(settings.device, text) || (text[0] == '\0'))
242
g_free(settings.device);
244
settings.device = g_strdup(text);
246
start_radio(TRUE, data);
248
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (enabled)) ||
249
gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (disabled)))
250
audio_loopback_set_visible (radio_is_init());
256
device_entry_auto_activate_cb(GtkEntry* entry, const gchar* text, gpointer data)
258
GtkEditable *editable;
260
editable = GTK_EDITABLE (entry);
262
text = gtk_entry_get_text(GTK_ENTRY(device_entry));
265
if (0 == strcmp(text, "auto")) {
266
g_signal_emit_by_name(G_OBJECT (editable), "activate");
269
gtk_widget_grab_focus(add_button);
273
static gboolean mixer_entry_activate_cb(GtkWidget *widget, gpointer data)
277
text = gtk_entry_get_text(GTK_ENTRY(mixer_entry));
279
if (!strcmp(settings.mixer, text) || (text[0] == '\0'))
283
g_free(settings.mixer);
285
settings.mixer = g_strdup(text);
287
start_mixer(TRUE, data);
292
/*static gboolean bitrate_combo_change_cb(GtkComboBox *combo, gpointer data)
299
bitrates = g_object_get_data(G_OBJECT(combo), "bitrates");
300
active = gtk_combo_box_get_active(combo);
301
g_assert(active > -1);
303
bitrate = (gchar*)g_list_nth_data(bitrates, active);
306
if (rec_settings.bitrate) g_free(rec_settings.bitrate);
307
rec_settings.bitrate = g_strdup(bitrate);
312
/*static gboolean encoder_combo_change_cb(GtkComboBox *combo, gpointer bitrate_combo)
319
encoders = g_object_get_data(G_OBJECT(combo), "encoders");
320
active = gtk_combo_box_get_active(combo);
321
g_assert(active > -1);
323
encoder = (gchar*)g_list_nth_data(encoders, active);
326
if (g_str_equal(encoder, _("Wave file"))) rec_settings.mp3 = FALSE;
328
rec_settings.mp3 = TRUE;
329
if (rec_settings.encoder) g_free(rec_settings.encoder);
330
rec_settings.encoder = g_strdup(encoder);
332
gtk_widget_set_sensitive(bitrate_combo, rec_settings.mp3);
337
static void audio_profile_combo_change_cb(GtkWidget *widget, gpointer user_data)
341
char *media_type = NULL;
342
GstEncodingProfile *profile;
344
model = gtk_combo_box_get_model(GTK_COMBO_BOX(widget));
345
/* get selected media type */
346
if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter) == FALSE)
348
gtk_tree_model_get (GTK_TREE_MODEL (model),
354
rec_settings.profile = g_strdup(media_type);
356
/* indicate whether additional plugins are required to encode in this format */
357
if (rb_gst_check_missing_plugins (profile, NULL, NULL)) {
358
gtk_widget_set_visible (install_button, TRUE);
360
gtk_widget_set_sensitive (install_button,
361
gst_install_plugins_supported ());
363
gtk_widget_set_visible (install_button, FALSE);
369
audio_profile_chooser_set_active(GtkWidget *widget, const char *profile)
376
model = gtk_combo_box_get_model(GTK_COMBO_BOX(widget));
377
if (gtk_tree_model_get_iter_first(model, &iter)) {
381
gtk_tree_model_get(model, &iter, 0, &media_type, -1);
382
if (g_strcmp0(media_type, profile) == 0) {
383
gtk_combo_box_set_active_iter(GTK_COMBO_BOX(widget), &iter);
387
} while (done == FALSE && gtk_tree_model_iter_next(model, &iter));
391
gtk_combo_box_set_active_iter(GTK_COMBO_BOX(widget), NULL);
395
static GtkWidget *audio_profile_choose_new(void)
397
GstEncodingTarget *target;
400
GtkCellRenderer *renderer;
403
model = GTK_TREE_MODEL(gtk_tree_store_new(3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER));
405
target = rb_gst_get_default_encoding_target();
406
for (p = gst_encoding_target_get_profiles(target); p != NULL; p = p->next) {
407
GstEncodingProfile *profile = GST_ENCODING_PROFILE (p->data);
410
media_type = rb_gst_encoding_profile_get_media_type(profile);
411
if (media_type == NULL) {
414
gtk_tree_store_insert_with_values(GTK_TREE_STORE(model),
417
1, gst_encoding_profile_get_description(profile),
422
combo = gtk_combo_box_new_with_model(model);
423
renderer = gtk_cell_renderer_text_new();
424
gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo), renderer, TRUE);
425
gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo), renderer, "text", 1, NULL);
427
return GTK_WIDGET(combo);
431
audio_plugin_install_done_cb (gpointer inst, gboolean retry, gpointer user_data)
433
audio_profile_combo_change_cb (audio_profile_combo, user_data);
437
audio_profile_install_plugins_cb (GtkWidget *widget, gpointer user_data)
439
GstEncodingProfile *profile;
444
profile = rb_gst_get_encoding_profile (rec_settings.profile);
445
if (profile == NULL) {
446
g_free (rec_settings.profile);
449
g_free (rec_settings.profile);
451
/* get plugin details */
452
if (rb_gst_check_missing_plugins (profile, &details, NULL) == FALSE) {
456
/* attempt installation */
457
closure = g_cclosure_new ((GCallback) audio_plugin_install_done_cb,
458
g_object_ref (audio_profile_combo),
459
(GClosureNotify) g_object_unref);
460
g_closure_set_marshal (closure, g_cclosure_marshal_VOID__BOOLEAN);
462
rb_missing_plugins_install ((const char **)details, TRUE, closure);
464
g_closure_sink (closure);
465
g_strfreev (details);
468
static void add_button_clicked_cb(GtkWidget *widget, gpointer data)
472
GtkTreeIter iter = {0};
473
GtkAdjustment* v_scb;
474
GtkTreePath *path = NULL;
477
ps = malloc(sizeof(preset));
478
ps->title = g_strdup(_("unnamed"));
479
ps->freq = rint(gtk_adjustment_get_value(adj)) / STEPS;
480
settings.presets = g_list_append(settings.presets, (gpointer) ps);
481
buffer = g_strdup_printf("%.2f", ps->freq);
483
gtk_list_store_append(list_store, &iter);
484
gtk_list_store_set(GTK_LIST_STORE(list_store), &iter, 0, ps->title, 1, buffer, -1);
487
gtk_tree_selection_unselect_all(selection);
489
v_scb = gtk_scrollable_get_vadjustment(GTK_SCROLLABLE(list_view));
490
gtk_adjustment_set_value(v_scb, gtk_adjustment_get_upper(v_scb));
493
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(preset_combo), ps->title);
494
mom_ps = g_list_length(settings.presets) - 1;
495
preset_combo_set_item(mom_ps);
497
menuitem = gtk_menu_item_new_with_label(ps->title);
499
gtk_menu_shell_insert(GTK_MENU_SHELL(tray_menu), menuitem, mom_ps);
500
g_signal_connect(G_OBJECT(menuitem), "activate", (GCallback)preset_menuitem_activate_cb, GINT_TO_POINTER (mom_ps));
501
gtk_widget_show(menuitem);
504
buffer = g_strdup_printf("%d", g_list_length(settings.presets) - 1);
505
path = gtk_tree_path_new_from_string(buffer);
507
gtk_tree_view_set_cursor(GTK_TREE_VIEW(list_view), path, NULL, FALSE);
508
gtk_tree_path_free(path);
510
gtk_widget_set_sensitive(save_button, TRUE);
513
static void remove_button_clicked_cb(GtkWidget *widget, gpointer data)
515
GtkTreePath *path = NULL;
516
GtkTreeViewColumn *focus_column = NULL;
523
gtk_tree_view_get_cursor(GTK_TREE_VIEW(list_view), &path, &focus_column);
527
row = gtk_tree_path_get_indices(path);
529
g_assert(*row < g_list_length(settings.presets));
531
ps = g_list_nth_data(settings.presets, *row);
533
settings.presets = g_list_remove(settings.presets, (gpointer)ps);
537
gtk_tree_model_get_iter(GTK_TREE_MODEL(list_store), &iter, path);
538
gtk_list_store_remove(list_store, &iter);
541
gtk_combo_box_text_remove(GTK_COMBO_BOX_TEXT(preset_combo), *row + 1);
542
if (--mom_ps < 0) mom_ps = 0;
543
if (settings.presets == NULL) mom_ps = -1;
544
preset_combo_set_item(mom_ps);
546
menuitems = gtk_container_get_children(GTK_CONTAINER(tray_menu));
547
g_assert(*row < g_list_length(menuitems));
548
menuitem = g_list_nth_data(menuitems, *row);
549
gtk_widget_destroy(menuitem);
552
gtk_tree_path_prev(path);
553
gtk_tree_view_set_cursor(GTK_TREE_VIEW(list_view), path, NULL, FALSE);
554
gtk_tree_path_free(path);
556
if (settings.presets == NULL) {
557
gtk_widget_set_sensitive(save_button, FALSE);
559
gtk_widget_set_sensitive(save_button, TRUE);
563
static void move_up_button_clicked_cb(GtkWidget * widget, gpointer data)
565
GtkTreeIter iter, iter2;
566
GtkTreePath *path, *path2;
573
selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(list_view));
574
gtk_tree_selection_get_selected(selection, NULL, &iter);
575
path = gtk_tree_model_get_path(GTK_TREE_MODEL(list_store), &iter);
578
gtk_tree_path_prev(path2);
580
if (gtk_tree_model_get_iter(GTK_TREE_MODEL(list_store), &iter2, path2)) {
581
// we have a previous entry...
582
gtk_list_store_swap(GTK_LIST_STORE(GTK_TREE_MODEL(list_store)), &iter, &iter2);
585
row = gtk_tree_path_get_indices(path);
587
g_assert(*row < g_list_length(settings.presets));
589
ps = g_list_nth_data(settings.presets, *row);
591
pos = g_list_index(settings.presets, (gpointer)ps);
594
settings.presets = g_list_remove(settings.presets, (gpointer)ps);
595
settings.presets = g_list_insert(settings.presets, (gpointer)ps, pos);
598
gtk_combo_box_text_remove(GTK_COMBO_BOX_TEXT(preset_combo), *row + 1);
599
gtk_combo_box_text_insert_text(GTK_COMBO_BOX_TEXT(preset_combo), *row + 2, ps->title);
601
preset_combo_set_item(mom_ps);
603
menuitems = gtk_container_get_children(GTK_CONTAINER(tray_menu));
604
g_assert(mom_ps < g_list_length(menuitems));
605
menuitem = g_list_nth_data(menuitems, mom_ps);
606
gtk_widget_destroy(menuitem);
607
menuitem = gtk_menu_item_new_with_label(ps->title);
609
gtk_menu_shell_insert(GTK_MENU_SHELL(tray_menu), menuitem, *row + 1);
610
g_signal_connect(G_OBJECT(menuitem), "activate", (GCallback)preset_menuitem_activate_cb, GINT_TO_POINTER (mom_ps));
611
gtk_widget_show(menuitem);
614
gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(list_view), path, NULL, FALSE, 0, 0);
615
gtk_tree_path_free(path);
618
gtk_widget_set_sensitive(move_up_button, FALSE);
620
gtk_widget_set_sensitive(move_up_button, TRUE);
622
gtk_widget_set_sensitive(move_down_button, TRUE);
625
static void move_down_button_clicked_cb(GtkWidget * widget, gpointer data)
627
GtkTreeIter iter, iter2;
628
GtkTreePath *path, *path2;
635
selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(list_view));
636
gtk_tree_selection_get_selected(selection, NULL, &iter);
637
path = gtk_tree_model_get_path(GTK_TREE_MODEL(list_store), &iter);
640
gtk_tree_path_next(path2);
642
if (gtk_tree_model_get_iter(GTK_TREE_MODEL(list_store), &iter2, path2)) {
643
// we have a next entry...
644
gtk_list_store_swap(GTK_LIST_STORE(GTK_TREE_MODEL(list_store)), &iter, &iter2);
647
row = gtk_tree_path_get_indices(path);
649
g_assert(*row < g_list_length(settings.presets));
651
ps = g_list_nth_data(settings.presets, *row);
654
count = g_list_length(settings.presets);
655
pos = g_list_index(settings.presets, (gpointer)ps);
660
settings.presets = g_list_remove(settings.presets, (gpointer)ps);
661
settings.presets = g_list_insert(settings.presets, (gpointer)ps, pos);
664
gtk_combo_box_text_remove(GTK_COMBO_BOX_TEXT(preset_combo), *row + 1);
665
gtk_combo_box_text_insert_text(GTK_COMBO_BOX_TEXT(preset_combo), *row, ps->title);
667
preset_combo_set_item(mom_ps);
669
menuitems = gtk_container_get_children(GTK_CONTAINER(tray_menu));
670
g_assert(mom_ps < g_list_length(menuitems));
671
menuitem = g_list_nth_data(menuitems, mom_ps);
672
gtk_widget_destroy(menuitem);
673
menuitem = gtk_menu_item_new_with_label(ps->title);
675
gtk_menu_shell_insert(GTK_MENU_SHELL(tray_menu), menuitem, *row - 1);
676
g_signal_connect(G_OBJECT(menuitem), "activate", (GCallback)preset_menuitem_activate_cb, GINT_TO_POINTER (mom_ps));
677
gtk_widget_show(menuitem);
680
gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(list_view), path, NULL, FALSE, 0, 0);
681
gtk_tree_path_free(path);
683
if (pos + 2 == gtk_tree_model_iter_n_children(GTK_TREE_MODEL(list_store), NULL)) {
684
gtk_widget_set_sensitive(move_down_button, FALSE);
686
gtk_widget_set_sensitive(move_down_button, TRUE);
688
gtk_widget_set_sensitive(move_up_button, TRUE);
691
static void destination_button_clicked_cb(GtkWidget *button, gpointer data)
693
if (rec_settings.destination)
695
g_free(rec_settings.destination);
697
rec_settings.destination = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(button));
700
static gboolean list_view_key_press_event_cb(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
702
if (event->keyval == GDK_KEY_Delete)
703
remove_button_clicked_cb(widget, user_data);
704
if (event->keyval == GDK_KEY_Insert)
705
add_button_clicked_cb(widget, user_data);
710
static gboolean button_release_cb(GtkWidget *widget, GdkEvent *event, gpointer data)
714
GdkEventButton *event_button;
717
event_button = (GdkEventButton *) event;
719
gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(list_view), event_button->x, event_button->y, &path, NULL, NULL, NULL);
721
buffer = gtk_tree_path_to_string(path);
722
pos = (gint) g_strtod(buffer, NULL);
724
gtk_tree_path_free(path);
727
gtk_widget_set_sensitive(move_up_button, FALSE);
729
gtk_widget_set_sensitive(move_up_button, TRUE);
732
if (pos + 1 == gtk_tree_model_iter_n_children(GTK_TREE_MODEL(list_store), NULL)) {
733
gtk_widget_set_sensitive(move_down_button, FALSE);
735
gtk_widget_set_sensitive(move_down_button, TRUE);
741
static void name_cell_edited_cb(GtkCellRendererText *cellrenderertext, gchar *path_str, gchar *new_val, gpointer user_data)
743
GtkTreePath *path = NULL;
750
path = gtk_tree_path_new_from_string(path_str);
752
row = gtk_tree_path_get_indices(path);
754
g_assert(*row < g_list_length(settings.presets));
756
ps = g_list_nth_data(settings.presets, *row);
758
if (ps->title) g_free(ps->title);
759
ps->title = g_strdup(new_val);
762
gtk_combo_box_text_remove(GTK_COMBO_BOX_TEXT(preset_combo), *row + 1);
763
gtk_combo_box_text_insert_text(GTK_COMBO_BOX_TEXT(preset_combo), *row + 1, ps->title);
765
preset_combo_set_item(mom_ps);
767
menuitems = gtk_container_get_children(GTK_CONTAINER(tray_menu));
768
g_assert(mom_ps < g_list_length(menuitems));
769
menuitem = g_list_nth_data(menuitems, mom_ps);
770
gtk_widget_destroy(menuitem);
771
menuitem = gtk_menu_item_new_with_label(ps->title);
773
gtk_menu_shell_insert(GTK_MENU_SHELL(tray_menu), menuitem, *row);
774
g_signal_connect(G_OBJECT(menuitem), "activate", (GCallback)preset_menuitem_activate_cb, GINT_TO_POINTER (mom_ps));
775
gtk_widget_show(menuitem);
778
gtk_tree_model_get_iter(GTK_TREE_MODEL(list_store), &iter, path);
779
gtk_list_store_set(GTK_LIST_STORE(list_store), &iter, 0, new_val, -1);
780
gtk_tree_path_free(path);
783
static void freq_cell_edited_cb(GtkCellRendererText *cellrenderertext, gchar *path_str, gchar *new_val, gpointer user_data)
785
GtkTreePath *path = NULL;
792
if (sscanf(new_val, "%lf", &value) != 1) return;
794
if (value < FREQ_MIN) value = FREQ_MIN;
795
if (value > FREQ_MAX) value = FREQ_MAX;
796
value = rint(value * STEPS) / STEPS;
798
freq_str = g_strdup_printf("%.2f", value);
800
path = gtk_tree_path_new_from_string(path_str);
802
row = gtk_tree_path_get_indices(path);
804
g_assert(*row < g_list_length(settings.presets));
806
ps = g_list_nth_data(settings.presets, *row);
810
gtk_adjustment_set_value(adj, value * STEPS);
812
preset_combo_set_item(mom_ps);
814
gtk_tree_model_get_iter(GTK_TREE_MODEL(list_store), &iter, path);
815
gtk_list_store_set(GTK_LIST_STORE(list_store), &iter, 1, freq_str, -1);
817
gtk_tree_path_free(path);
820
static void list_view_cursor_changed_cb(GtkWidget *widget, gpointer data)
825
GtkTreePath *path = NULL;
826
GtkTreeViewColumn *focus_column = NULL;
828
if (settings.presets == NULL)
831
gtk_tree_view_get_cursor(GTK_TREE_VIEW(list_view), &path, &focus_column);
836
row = gtk_tree_path_get_indices(path);
840
preset_combo_set_item(mom_ps);
842
ps = g_list_nth_data(settings.presets, *row);
845
pos = g_list_index(settings.presets, (gpointer)ps);
848
gtk_widget_set_sensitive(move_up_button, FALSE);
850
gtk_widget_set_sensitive(move_up_button, TRUE);
853
if (pos + 1 == gtk_tree_model_iter_n_children(GTK_TREE_MODEL(list_store), NULL)) {
854
gtk_widget_set_sensitive(move_down_button, FALSE);
856
gtk_widget_set_sensitive(move_down_button, TRUE);
858
gtk_tree_path_free(path);
862
static void list_view_selection_changed_cb(GtkWidget *widget, gpointer data)
866
sel = gtk_tree_selection_get_selected(selection, NULL, NULL);
868
gtk_widget_set_sensitive(remove_button, sel);
869
gtk_widget_set_sensitive(save_button, sel);
872
static void list_view_scroll_to_active_preset_cb(GtkWidget *widget, gpointer data)
874
GtkTreePath *path = NULL;
878
if (settings.presets == NULL) {
879
gtk_widget_grab_focus(add_button);
883
active = gtk_combo_box_get_active(GTK_COMBO_BOX(preset_combo)) - 1;
886
gtk_widget_grab_focus(add_button);
890
if (!gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(list_store), &iter, NULL, active))
893
path = gtk_tree_model_get_path(GTK_TREE_MODEL(list_store), &iter);
895
gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW (list_view), path, NULL, FALSE, 0, 0);
896
gtk_tree_view_set_cursor(GTK_TREE_VIEW (list_view), path, NULL, FALSE );
897
gtk_tree_path_free(path);
899
gtk_widget_grab_focus(list_view);
902
static void free_presets_list (gpointer data)
904
preset *ps = (preset *) data;
909
/* Go through each row and add its data to the xmlDocPtr */
910
static gboolean save_to_file_foreach(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, xmlNodePtr root, gpointer user_data)
912
gchar *title, *freq, *position;
915
/* get the data stored in the model... */
916
gtk_tree_model_get(model, iter, 0, &title, 1, &freq, -1);
917
/* ...and get the path of the current row */
918
position = gtk_tree_path_to_string(path);
919
/* create a new child of the root node... */
920
/* (note that I'm using a (guchar*) cast; this is because it's the same thing as
921
* an (xmlChar*) cast, but easier to type) */
922
current = xmlNewChild(root, NULL, (guchar*)"station", NULL);
923
/* ...and set some properties */
924
xmlSetProp(current, (guchar*)"name", (guchar*)title);
925
xmlSetProp(current, (guchar*)"freq", (guchar*)freq);
926
xmlSetProp(current, (guchar*)"position", (guchar*)position);
927
/* free our data we retrieved from the model */
932
/* return FALSE to keep iterating */
936
/* Function handle saving an xml file; calls save_to_file_foreach */
937
static void save_to_file(gchar *filename)
943
/* create a new doc node */
944
doc = xmlNewDoc((guchar*)"1.0");
945
/* create a new root element. */
946
root = xmlNewDocNode(doc, NULL, (guchar*)"gnomeradio", NULL);
947
/* set it as the root element */
948
xmlDocSetRootElement(doc, root);
949
/* get the tree view's model... */
950
model = gtk_tree_view_get_model(GTK_TREE_VIEW(list_view));
951
/* ...and go through it with a foreach */
952
gtk_tree_model_foreach(model, (GtkTreeModelForeachFunc)save_to_file_foreach, (gpointer)root);
953
/* save the actual file */
954
xmlSaveFile(filename, doc);
955
/* free the doc node */
959
/* Callback for the "Save to file" button; calls save_to_file */
960
static void save_to_file_cb(GtkWidget *button, gpointer data)
963
GtkFileFilter *file_filter_all;
964
GtkFileFilter *file_filter_xml;
967
dialog = gtk_file_chooser_dialog_new (_("Select file name\xE2\x80\xA6"), NULL,
968
GTK_FILE_CHOOSER_ACTION_SAVE,
969
_("_Save"), GTK_RESPONSE_ACCEPT,
970
_("_Cancel"), GTK_RESPONSE_CANCEL,
973
file_filter_all = gtk_file_filter_new();
974
gtk_file_filter_set_name(file_filter_all, _("All Files"));
975
gtk_file_filter_add_pattern(file_filter_all, "*");
976
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), file_filter_all);
978
file_filter_xml = gtk_file_filter_new();
979
gtk_file_filter_set_name(file_filter_xml, _("XML Files (*.xml)"));
980
gtk_file_filter_add_pattern(file_filter_xml, "*.xml");
981
gtk_file_filter_add_pattern(file_filter_xml, "*.XML");
982
gtk_file_filter_add_mime_type(file_filter_xml, "text/xml");
983
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), file_filter_xml);
985
gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), TRUE);
986
gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(dialog), file_filter_xml);
987
gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), "gnomeradio.xml");
989
if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
990
filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
991
/* Check if .xml extension is added, if not add */
992
if (!g_str_has_suffix(filename, ".xml")) {
994
/* create copy of filename to release it and create a new one, using old name */
995
tmp_file = g_strdup(filename);
997
filename = g_strdup_printf("%s.xml", tmp_file);
1000
save_to_file(filename);
1003
gtk_widget_destroy(dialog);
1006
/* Gets the parent of a path string.
1007
* passing "0:1:2" would return "0:1",
1008
* passing "0:1" would return "0",
1009
* passing "0" would return NULL */
1010
gchar *gtk_tree_path_string_get_parent(gchar *path)
1014
g_return_val_if_fail(path != NULL, NULL);
1016
colon = g_strrstr(path, ":");
1020
return g_strndup(path, colon - path);
1023
/* Make sure that path exists within model */
1024
static void gtk_tree_model_generate_path(GtkTreeModel *model, gchar *path)
1026
GtkTreeIter iter, parent;
1030
/* if this returns TRUE, then this path exists and we're fine */
1031
if (gtk_tree_model_get_iter_from_string(model, &iter, path))
1035
path = gtk_tree_path_string_get_parent(path);
1036
/* if there's no parent, then it's toplevel */
1038
if (GTK_IS_TREE_STORE(model))
1039
gtk_tree_store_append(GTK_TREE_STORE(model), &parent, NULL);
1041
gtk_list_store_append(GTK_LIST_STORE(model), &parent);
1042
gtk_tree_model_generate_path(model, temp);
1045
if (GTK_IS_TREE_STORE(model)) {
1046
gtk_tree_model_generate_path(model, path);
1047
gtk_tree_model_get_iter_from_string(model, &parent, path);
1048
gtk_tree_store_append(GTK_TREE_STORE(model), &iter, &parent);
1053
/* Function to load from an xml file */
1054
static void load_from_file(gchar *filename)
1058
xmlChar *title, *freq, *position;
1059
GtkTreeModel *model;
1060
GtkTreePath *path = NULL;
1062
GtkAdjustment* v_scb;
1064
GtkWidget *menuitem;
1067
doc = xmlParseFile(filename);
1068
/* get the root item */
1072
current = xmlDocGetRootElement(doc);
1073
if (current == NULL) {
1078
if (xmlStrcmp(current->name, (guchar*)"gnomeradio")) {
1083
/* remove previous presets */
1084
if (settings.presets != NULL) {
1088
count = g_list_length (settings.presets);
1089
for (i = 0; i < count; i++)
1090
gtk_combo_box_text_remove(GTK_COMBO_BOX_TEXT(preset_combo), 1);
1092
menuitems = gtk_container_get_children (GTK_CONTAINER (tray_menu));
1094
count = g_list_length (menuitems);
1095
for (i = 0; i < count - 6; i++) {
1096
menuitem = g_list_nth_data (menuitems, i);
1097
gtk_widget_destroy (menuitem);
1101
gtk_list_store_clear(GTK_LIST_STORE(list_store));
1103
g_list_free_full (settings.presets, free_presets_list);
1104
settings.presets = NULL;
1107
/* get the tree view's model */
1108
model = gtk_tree_view_get_model(GTK_TREE_VIEW(list_view));
1110
/* iterate through the root's children items */
1111
current = current->xmlChildrenNode;
1113
if(!xmlIsBlankNode(current)) {
1114
/* check for the proper element name */
1115
if (!xmlStrcmp(current->name, (guchar*)"station")) {
1116
/* get the saved properties */
1117
title = xmlGetProp(current, (guchar*)"name");
1118
freq = xmlGetProp(current, (guchar*)"freq");
1119
position = xmlGetProp(current, (guchar*)"position");
1121
if( title && freq && position ) {
1122
preset *ps = g_malloc0(sizeof(preset));
1123
ps->title = g_strdup((gchar*)title);
1124
ps->freq = atof((gchar*)freq);
1126
settings.presets = g_list_append(settings.presets, ps);
1128
/* make sure that the path exists */
1129
gtk_tree_model_generate_path(model, (gchar*)position);
1130
/* get an iter to the path */
1131
gtk_tree_model_get_iter_from_string(model, &iter, (gchar*)position);
1133
gtk_list_store_set(GTK_LIST_STORE(list_store), &iter, 0, title, 1, freq, -1);
1135
gtk_tree_selection_unselect_all(selection);
1137
v_scb = gtk_scrollable_get_vadjustment(GTK_SCROLLABLE(list_view));
1138
gtk_adjustment_set_value(v_scb, gtk_adjustment_get_upper(v_scb));
1141
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(preset_combo), ps->title);
1142
mom_ps = g_list_length(settings.presets) - 1;
1143
preset_combo_set_item(mom_ps);
1145
menuitem = gtk_menu_item_new_with_label(ps->title);
1147
gtk_menu_shell_insert(GTK_MENU_SHELL(tray_menu), menuitem, mom_ps);
1148
g_signal_connect(G_OBJECT(menuitem), "activate",
1149
(GCallback)preset_menuitem_activate_cb,
1150
GINT_TO_POINTER (mom_ps));
1151
gtk_widget_show(menuitem);
1159
current = current->next;
1162
/* free the doc node */
1165
if (settings.presets == NULL)
1168
path = gtk_tree_model_get_path(GTK_TREE_MODEL(list_store), &iter);
1170
gtk_tree_view_set_cursor(GTK_TREE_VIEW (list_view), path, NULL, FALSE );
1171
gtk_tree_path_free(path);
1173
gtk_widget_grab_focus(list_view);
1175
list_view_cursor_changed_cb(list_view, NULL);
1176
gtk_widget_set_sensitive(save_button, TRUE);
1177
gtk_widget_set_sensitive(remove_button, TRUE);
1180
/* Callback for the "Load from file" button; calls load_from_file */
1181
static void load_from_file_cb(GtkWidget *button, gpointer data)
1184
GtkFileFilter *file_filter_all;
1185
GtkFileFilter *file_filter_xml;
1188
dialog = gtk_file_chooser_dialog_new (_("Select file name\xE2\x80\xA6"), NULL,
1189
GTK_FILE_CHOOSER_ACTION_OPEN,
1190
_("_Open"), GTK_RESPONSE_ACCEPT,
1191
_("_Cancel"), GTK_RESPONSE_CANCEL,
1194
file_filter_all = gtk_file_filter_new();
1195
gtk_file_filter_set_name(file_filter_all, _("All Files"));
1196
gtk_file_filter_add_pattern(file_filter_all, "*");
1197
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), file_filter_all);
1199
file_filter_xml = gtk_file_filter_new();
1200
gtk_file_filter_set_name(file_filter_xml, _("XML Files"));
1201
gtk_file_filter_add_pattern(file_filter_xml, "*.xml");
1202
gtk_file_filter_add_pattern(file_filter_xml, "*.XML");
1203
gtk_file_filter_add_mime_type(file_filter_xml, "text/xml");
1204
gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), file_filter_xml);
1206
gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(dialog), file_filter_xml);
1208
if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
1209
filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
1210
load_from_file(filename);
1213
gtk_widget_destroy(dialog);
1216
gboolean action_mode (gint mode)
1220
gtk_widget_grab_focus (device_entry);
1223
gtk_widget_grab_focus (mixer_entry);
1226
list_view_scroll_to_active_preset_cb(list_view, NULL);
1235
GtkWidget* prefs_window(GtkWidget *app)
1238
GtkWidget *content_area;
1242
GtkWidget *scrolled_window;
1243
GtkCellRenderer *cellrenderer;
1244
GtkTreeViewColumn *list_column;
1245
GtkWidget *button_box;
1246
GtkWidget *open_button;
1247
GtkWidget *destination_button;
1250
GstEncodingProfile *profile;
1257
dialog = gtk_dialog_new_with_buttons (_("Gnomeradio Settings"), GTK_WINDOW (app),
1258
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
1259
_("_Close"), GTK_RESPONSE_CLOSE,
1260
_("_Help"), GTK_RESPONSE_HELP,
1263
gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE);
1264
gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_CLOSE);
1266
content_area = gtk_dialog_get_content_area (GTK_DIALOG(dialog));
1268
box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 10);
1269
gtk_container_set_border_width(GTK_CONTAINER(box), 10);
1270
gtk_box_pack_start (GTK_BOX (content_area), box, TRUE, TRUE, 0);
1272
grid = gtk_grid_new();
1273
gtk_grid_set_row_spacing(GTK_GRID(grid), 5);
1274
gtk_grid_set_column_spacing(GTK_GRID(grid), 40);
1275
gtk_box_pack_start(GTK_BOX(box), grid, TRUE, TRUE, 0);
1277
/* The general settings part */
1278
label = gtk_label_new (NULL);
1279
gtk_widget_set_halign (label, GTK_ALIGN_START);
1280
markup = g_strdup_printf ("<span weight=\"bold\">%s</span>", _("General Settings"));
1281
gtk_label_set_markup (GTK_LABEL (label), markup);
1283
gtk_grid_attach(GTK_GRID(grid), label, 0, 0, 1, 1);
1285
label = gtk_label_new (_("Radio device:"));
1286
gtk_widget_set_halign (label, GTK_ALIGN_START);
1287
gtk_widget_set_margin_left (label, 10);
1288
gtk_grid_attach (GTK_GRID (grid), label, 0, 1, 1, 1);
1290
device_entry = gtk_entry_new();
1293
gtk_entry_set_placeholder_text(GTK_ENTRY(device_entry), "auto");
1295
gtk_entry_set_text(GTK_ENTRY(device_entry), settings.device);
1297
gtk_grid_attach(GTK_GRID(grid), device_entry, 1, 1, 1, 1);
1299
label = gtk_label_new (_("Mixer source:"));
1300
gtk_widget_set_halign (label, GTK_ALIGN_START);
1301
gtk_widget_set_margin_left (label, 10);
1302
gtk_grid_attach (GTK_GRID (grid), label, 0, 2, 1, 1);
1304
mixer_entry = gtk_entry_new();
1305
gtk_entry_set_text(GTK_ENTRY(mixer_entry), settings.mixer);
1306
gtk_grid_attach(GTK_GRID(grid), mixer_entry, 1, 2, 1, 1);
1308
audio_label = gtk_label_new (_("Audio Loopback mode"));
1309
gtk_widget_set_no_show_all (audio_label, TRUE);
1310
gtk_widget_set_halign (audio_label, GTK_ALIGN_START);
1311
gtk_widget_set_margin_left (audio_label, 10);
1312
gtk_grid_attach (GTK_GRID (grid), audio_label, 0, 3, 1, 1);
1314
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
1316
enabled = gtk_radio_button_new_with_label (NULL, _("Enabled"));
1317
gtk_widget_set_no_show_all (enabled, TRUE);
1318
disabled = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (enabled), _("Disabled"));
1319
gtk_widget_set_no_show_all (disabled, TRUE);
1320
gtk_box_pack_start (GTK_BOX (box), enabled, TRUE, TRUE, 0);
1321
gtk_box_pack_start (GTK_BOX (box), disabled, TRUE, TRUE, 0);
1322
gtk_grid_attach(GTK_GRID(grid), box, 1, 3, 1, 1);
1324
/* Enabled from radio button or else from command line */
1325
if (settings.audio_loopback || alsa_loopback)
1326
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (enabled), TRUE);
1328
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (disabled), TRUE);
1330
if (settings.audio_loopback)
1332
audio_loopback_set_visible (TRUE);
1334
audio_loopback_set_visible (FALSE);
1336
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (enabled)) ||
1337
gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (disabled)))
1338
audio_loopback_set_visible (radio_is_init());
1340
mute_on_exit = gtk_check_button_new_with_label(_("Mute on exit"));
1341
gtk_widget_set_margin_left (mute_on_exit, 10);
1342
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(mute_on_exit), settings.mute_on_exit);
1343
gtk_grid_attach(GTK_GRID(grid), mute_on_exit, 0, 4, 2, 1);
1345
g_signal_connect(G_OBJECT(device_entry), "hide", G_CALLBACK(device_entry_activate_cb), app);
1346
g_signal_connect(G_OBJECT(device_entry), "activate", G_CALLBACK(device_entry_activate_cb), NULL);
1347
g_signal_connect(G_OBJECT(device_entry), "changed", G_CALLBACK(device_entry_auto_activate_cb), NULL);
1348
g_signal_connect(G_OBJECT(mixer_entry), "hide", G_CALLBACK(mixer_entry_activate_cb), app);
1349
g_signal_connect(G_OBJECT(mixer_entry), "activate", G_CALLBACK(mixer_entry_activate_cb), NULL);
1350
g_signal_connect(G_OBJECT(enabled), "toggled", G_CALLBACK(audio_loopback_toggled_cb), NULL);
1351
g_signal_connect(G_OBJECT(mute_on_exit), "toggled", G_CALLBACK(mute_on_exit_toggled_cb), NULL);
1353
gtk_widget_set_tooltip_text(device_entry, _("The radio device to use (e.g. /dev/radio0)"));
1354
gtk_widget_set_tooltip_text(mixer_entry, _("The mixer device and channel to use (e.g. hw:0/Line)"));
1355
gtk_widget_set_tooltip_text(disabled, _("Stop audio streaming between the radio device and the audio output device"));
1356
gtk_widget_set_tooltip_text(enabled, _("Start an audio streaming between the radio device and the audio output device"));
1357
gtk_widget_set_tooltip_text(mute_on_exit, _("Mute radio device on exit"));
1359
/* The presets part */
1360
label = gtk_label_new (NULL);
1361
gtk_widget_set_halign (label, GTK_ALIGN_START);
1362
markup = g_strdup_printf ("<span weight=\"bold\">%s</span>", _("Presets"));
1363
gtk_label_set_markup (GTK_LABEL (label), markup);
1365
gtk_grid_attach(GTK_GRID(grid), label, 0, 5, 1, 1);
1367
scrolled_window = gtk_scrolled_window_new(NULL, NULL);
1368
gtk_widget_set_margin_left (scrolled_window, 10);
1369
gtk_scrolled_window_set_min_content_height(GTK_SCROLLED_WINDOW(scrolled_window), 75);
1370
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled_window), GTK_SHADOW_IN);
1371
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
1373
list_store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING);
1374
list_view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(list_store));
1375
gtk_tree_view_set_rules_hint (GTK_TREE_VIEW(list_view), TRUE);
1376
gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(list_view), FALSE);
1378
selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(list_view));
1379
gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
1380
gtk_container_add(GTK_CONTAINER(scrolled_window), list_view);
1382
g_signal_connect(G_OBJECT(list_view), "button-release-event", G_CALLBACK(button_release_cb), NULL);
1383
g_signal_connect(G_OBJECT(list_view), "key-press-event", G_CALLBACK(list_view_key_press_event_cb), NULL);
1384
g_signal_connect(G_OBJECT(list_view), "cursor-changed", G_CALLBACK(list_view_cursor_changed_cb), NULL);
1386
g_signal_connect(G_OBJECT(selection), "changed", G_CALLBACK(list_view_selection_changed_cb), list_view);
1388
/*gtk_tree_selection_select_path(selection, gtk_tree_path_new_from_string("0"));
1389
gtk_tree_selection_set_select_function(selection, (GtkTreeSelectionFunc)list_view_select_cb, NULL, NULL);*/
1391
cellrenderer = gtk_cell_renderer_text_new();
1392
g_object_set(G_OBJECT(cellrenderer), "mode", GTK_CELL_RENDERER_MODE_EDITABLE, NULL);
1393
g_object_set(G_OBJECT(GTK_CELL_RENDERER_TEXT(cellrenderer)), "editable", TRUE, NULL);
1394
list_column = gtk_tree_view_column_new_with_attributes(NULL, cellrenderer, "text", 0, NULL);
1395
gtk_tree_view_column_set_reorderable(list_column, TRUE);
1396
gtk_tree_view_column_set_expand(list_column, TRUE);
1397
gtk_tree_view_append_column(GTK_TREE_VIEW(list_view), list_column);
1399
g_signal_connect(G_OBJECT(cellrenderer), "edited", G_CALLBACK(name_cell_edited_cb), NULL);
1401
cellrenderer = gtk_cell_renderer_text_new();
1402
g_object_set(G_OBJECT(cellrenderer), "mode", GTK_CELL_RENDERER_MODE_EDITABLE, NULL);
1403
g_object_set(G_OBJECT(cellrenderer), "xalign", 1.0, NULL);
1404
g_object_set(G_OBJECT(GTK_CELL_RENDERER_TEXT(cellrenderer)), "editable", TRUE, NULL);
1405
list_column = gtk_tree_view_column_new_with_attributes(NULL, cellrenderer, "text", 1, NULL);
1406
gtk_tree_view_column_set_reorderable(list_column, TRUE);
1407
gtk_tree_view_column_set_expand(list_column, FALSE);
1408
gtk_tree_view_append_column(GTK_TREE_VIEW(list_view), list_column);
1410
g_signal_connect(G_OBJECT(cellrenderer), "edited", G_CALLBACK(freq_cell_edited_cb), NULL);
1413
for (l = settings.presets; l != NULL; l = l->next) {
1414
GtkTreeIter iter = {0};
1417
buffer = g_strdup_printf("%0.2f", ps->freq);
1418
gtk_list_store_append(list_store, &iter);
1419
gtk_list_store_set(GTK_LIST_STORE(list_store), &iter, 0, ps->title, 1, buffer, -1);
1424
gtk_grid_attach(GTK_GRID(grid), scrolled_window, 0, 6, 2, 1);
1426
button_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
1428
move_up_button = gtk_button_new();
1429
image = gtk_image_new_from_icon_name ("go-up", GTK_ICON_SIZE_MENU);
1430
gtk_button_set_image (GTK_BUTTON (move_up_button), image);
1431
gtk_button_set_relief (GTK_BUTTON (move_up_button), GTK_RELIEF_NONE);
1432
gtk_widget_set_sensitive(move_up_button, FALSE);
1433
gtk_widget_set_tooltip_text(move_up_button, _("Move preset up"));
1435
g_signal_connect(G_OBJECT(move_up_button), "clicked", G_CALLBACK(move_up_button_clicked_cb), NULL);
1437
move_down_button = gtk_button_new();
1438
image = gtk_image_new_from_icon_name ("go-down", GTK_ICON_SIZE_MENU);
1439
gtk_button_set_image (GTK_BUTTON (move_down_button), image);
1440
gtk_button_set_relief (GTK_BUTTON (move_down_button), GTK_RELIEF_NONE);
1441
gtk_widget_set_sensitive(move_down_button, FALSE);
1442
gtk_widget_set_tooltip_text(move_down_button, _("Move preset down"));
1444
g_signal_connect(G_OBJECT(move_down_button), "clicked", G_CALLBACK(move_down_button_clicked_cb), NULL);
1446
add_button = gtk_button_new();
1447
image = gtk_image_new_from_icon_name ("list-add", GTK_ICON_SIZE_MENU);
1448
gtk_button_set_image (GTK_BUTTON(add_button), image);
1449
gtk_button_set_relief (GTK_BUTTON (add_button), GTK_RELIEF_NONE);
1450
gtk_widget_set_tooltip_text(add_button, _("Add preset"));
1452
g_signal_connect(G_OBJECT(add_button), "clicked", G_CALLBACK(add_button_clicked_cb), NULL);
1454
remove_button = gtk_button_new();
1455
image = gtk_image_new_from_icon_name ("list-remove", GTK_ICON_SIZE_MENU);
1456
gtk_button_set_image (GTK_BUTTON (remove_button), image);
1457
gtk_button_set_relief (GTK_BUTTON (remove_button), GTK_RELIEF_NONE);
1458
gtk_widget_set_tooltip_text(remove_button, _("Remove preset"));
1459
gtk_widget_set_sensitive(remove_button, FALSE);
1461
g_signal_connect(G_OBJECT(remove_button), "clicked", G_CALLBACK(remove_button_clicked_cb), NULL);
1463
save_button = gtk_button_new();
1464
image = gtk_image_new_from_icon_name ("document-save", GTK_ICON_SIZE_MENU);
1465
gtk_button_set_image (GTK_BUTTON (save_button), image);
1466
gtk_button_set_relief (GTK_BUTTON (save_button), GTK_RELIEF_NONE);
1467
gtk_widget_set_tooltip_text(save_button, _("Save to file\xE2\x80\xA6"));
1469
if (settings.presets == NULL)
1470
gtk_widget_set_sensitive (save_button, FALSE);
1472
gtk_widget_set_sensitive (save_button, TRUE);
1474
g_signal_connect(G_OBJECT(save_button), "clicked", G_CALLBACK(save_to_file_cb), NULL);
1476
open_button = gtk_button_new();
1477
image = gtk_image_new_from_icon_name ("document-open", GTK_ICON_SIZE_MENU);
1478
gtk_button_set_image (GTK_BUTTON(open_button), image);
1479
gtk_button_set_relief (GTK_BUTTON (open_button), GTK_RELIEF_NONE);
1480
gtk_widget_set_tooltip_text(open_button, _("Load from file\xE2\x80\xA6"));
1481
gtk_widget_set_sensitive(open_button, TRUE);
1483
g_signal_connect(G_OBJECT(open_button), "clicked", G_CALLBACK(load_from_file_cb), NULL);
1485
gtk_box_pack_end(GTK_BOX(button_box), move_down_button, FALSE, FALSE, 0);
1486
gtk_box_pack_end(GTK_BOX(button_box), move_up_button, FALSE, FALSE, 0);
1487
gtk_box_pack_end(GTK_BOX(button_box), remove_button, FALSE, FALSE, 0);
1488
gtk_box_pack_end(GTK_BOX(button_box), add_button, FALSE, FALSE, 0);
1489
gtk_box_pack_end(GTK_BOX(button_box), save_button, FALSE, FALSE, 0);
1490
gtk_box_pack_end(GTK_BOX(button_box), open_button, FALSE, FALSE, 0);
1492
gtk_grid_attach(GTK_GRID(grid), button_box, 1, 7, 1, 1);
1494
/* The record settings part */
1495
label = gtk_label_new (NULL);
1496
gtk_widget_set_halign (label, GTK_ALIGN_START);
1497
markup = g_strdup_printf ("<span weight=\"bold\">%s</span>", _("Record Settings"));
1498
gtk_label_set_markup (GTK_LABEL (label), markup);
1500
gtk_grid_attach (GTK_GRID (grid), label, 0, 8, 1, 1);
1502
label = gtk_label_new (_("Destination:"));
1503
gtk_widget_set_halign (label, GTK_ALIGN_START);
1504
gtk_widget_set_margin_left (label, 10);
1505
gtk_grid_attach(GTK_GRID(grid), label, 0, 9, 1, 1);
1507
destination_button = gtk_file_chooser_button_new (_("Select a folder"), GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
1508
gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(destination_button), rec_settings.destination);
1509
gtk_grid_attach(GTK_GRID(grid), destination_button, 1, 9, 1, 1);
1511
label = gtk_label_new (_("Output format:"));
1512
gtk_widget_set_halign (label, GTK_ALIGN_START);
1513
gtk_widget_set_margin_left (label, 10);
1514
gtk_grid_attach (GTK_GRID (grid), label, 0, 10, 1, 1);
1516
audio_profile_combo = audio_profile_choose_new();
1517
audio_profile_chooser_set_active(audio_profile_combo, rec_settings.profile);
1518
gtk_grid_attach (GTK_GRID (grid), audio_profile_combo, 1, 10, 1, 1);
1520
install_button = gtk_button_new_with_label(_("Install additional software required to use this format"));
1521
gtk_widget_set_no_show_all (install_button, TRUE);
1522
gtk_grid_attach (GTK_GRID (grid), install_button, 1, 11, 1, 1);
1524
profile = rb_gst_get_encoding_profile (rec_settings.profile);
1525
if (rb_gst_check_missing_plugins (profile, NULL, NULL)) {
1526
gtk_widget_set_visible (install_button, TRUE);
1527
gtk_widget_set_sensitive (install_button,
1528
gst_install_plugins_supported ());
1530
gtk_widget_set_visible (install_button, FALSE);
1533
g_signal_connect(GTK_FILE_CHOOSER(destination_button), "selection-changed", G_CALLBACK(destination_button_clicked_cb), NULL);
1534
g_signal_connect(G_OBJECT(audio_profile_combo), "changed", G_CALLBACK(audio_profile_combo_change_cb), NULL);
1535
g_signal_connect(G_OBJECT(install_button), "clicked", G_CALLBACK(audio_profile_install_plugins_cb), NULL);
1537
gtk_widget_set_tooltip_text(destination_button, _("Select a location where to save recorded file."));
1538
gtk_widget_set_tooltip_text(audio_profile_combo, _("Choose the format that should be used for recording."));
1540
gtk_widget_show_all(dialog);