~ubuntu-branches/ubuntu/trusty/gnomeradio/trusty

« back to all changes in this revision

Viewing changes to .pc/gnomeradio-tray_menu.patch/src/prefs.c

  • Committer: Package Import Robot
  • Author(s): POJAR GEORGE
  • Date: 2013-09-20 13:31:33 UTC
  • Revision ID: package-import@ubuntu.com-20130920133133-otwactksfjh4bwev
Tags: 1.8-2ubuntu23
* Updated debian/patches/gnomeradio-tray_menu.patch:
  - Fixed menu item not update conform new order when we use move up[down]
    swap. (LP: #1232931)
  - Fixed conditional jump or move depends on uninitialized value.
  - Added function to switch to preset in settings preset list when changed
    them from tray menu.
  - Cleaned up the files relating to the tray icon. Neither gui.c, prefs.c nor
    record.c touch the internals of trayicon.c anymore.
* Updated debian/patches/gnomeradio-preferences.patch:
  - Added option to disable audio loopback mode in Preferences settings.
  - Moved in separate GOptionGroup all command line parameters which refers to
    audio loopback mode.
* Updated debian/patches/gnomeradio-device.patch: Not need radio_mute() when
  exit or session die, already is called in radio_stop().
* Updated debian/patches/gnomeradio-station_list.patch: Fixed pointer targets
  in passing argument differ in signedness.
* Removed the content against configure and Makefile.in, since we use
  autoreconf anyways, from:
  - debian/patches/gnomeradio-gstreamer-1.0.patch.
  - debian/patches/gnomeradio-volume_button.patch.
* Updated debian/patches/gnomeradio-volume_button.patch: Removed unused
  vol_down[up].xpm icons.
* debian/gnomeradio.1: Updated man page.   

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
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.
 
6
 *
 
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.
 
11
 *
 
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.
 
15
 */
 
16
 
 
17
#include <gconf/gconf-client.h>
 
18
#include <glib/gi18n.h>
 
19
#include <gtk/gtk.h>
 
20
#include <gst/pbutils/pbutils.h>
 
21
#include <gst/pbutils/install-plugins.h>
 
22
#include <libxml/xmlmemory.h>
 
23
#include <libxml/parser.h>
 
24
#include <string.h>
 
25
#include "config.h"
 
26
#include "prefs.h"
 
27
#include "trayicon.h"
 
28
#include "gui.h"
 
29
#include "rec_tech.h"
 
30
#include "rb_gst_media_types.h"
 
31
#include "rb_missing_plugins.h"
 
32
#include "alsa_stream.h"
 
33
 
 
34
extern int autodetect;
 
35
extern int alsa_loopback;
 
36
 
 
37
extern GtkWidget *preset_combo;
 
38
extern GtkAdjustment *adj;
 
39
 
 
40
extern int mom_ps;
 
41
extern gnomeradio_settings settings;
 
42
 
 
43
extern gboolean main_visible;
 
44
 
 
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;
 
61
 
 
62
gboolean save_settings(void)
 
63
{
 
64
        gint i, count;
 
65
        gchar *buffer;
 
66
        preset *ps;
 
67
        GConfClient* client = NULL;
 
68
        
 
69
        if (!gconf_is_initialized())
 
70
                return FALSE;
 
71
 
 
72
        client = gconf_client_get_default();
 
73
        if (!client)
 
74
                return FALSE;
 
75
        
 
76
        /* Store general settings */
 
77
        if (autodetect)
 
78
                gconf_client_set_string(client, "/apps/gnomeradio/device", "auto", NULL);
 
79
        else
 
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);
 
87
 
 
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);
 
96
*/
 
97
 
 
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);
 
100
 
 
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++)
 
105
        {
 
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); 
 
109
                g_free(buffer);
 
110
                buffer = g_strdup_printf("/apps/gnomeradio/presets/%d/freqency", i);
 
111
                gconf_client_set_float(client, buffer, ps->freq, NULL); 
 
112
                g_free(buffer);
 
113
        }       
 
114
        gconf_client_set_int(client, "/apps/gnomeradio/presets/last", mom_ps, NULL);
 
115
        /*g_print("Storing Settings in GConf database\n");*/
 
116
        
 
117
        return TRUE;
 
118
}                       
 
119
 
 
120
gboolean load_settings(void)
 
121
{
 
122
        gint i, count;
 
123
        gchar *buffer;
 
124
        preset *ps;
 
125
        GConfClient *client = NULL;
 
126
        double freq;
 
127
        
 
128
        settings.presets = NULL;
 
129
                
 
130
        if (!gconf_is_initialized())
 
131
                return FALSE;
 
132
        
 
133
        client = gconf_client_get_default();
 
134
        if (!client)
 
135
                return FALSE;
 
136
 
 
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);
 
145
        if (!settings.mixer)
 
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);
 
153
        else
 
154
                gtk_adjustment_set_value(adj, freq * STEPS);
 
155
        
 
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");*/
 
174
 
 
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");
 
181
        
 
182
        /* Load the presets */
 
183
        count = gconf_client_get_int(client, "/apps/gnomeradio/presets/presets", NULL);
 
184
        for (i = 0; i < count; i++)
 
185
        {
 
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); 
 
189
                g_free(buffer);
 
190
                if (!ps->title)
 
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))
 
195
                        ps->freq = FREQ_MIN;
 
196
                else
 
197
                        ps->freq = freq;
 
198
                g_free(buffer);
 
199
                settings.presets = g_list_prepend(settings.presets, (gpointer)ps);
 
200
        }       
 
201
        settings.presets = g_list_reverse(settings.presets);
 
202
 
 
203
        mom_ps = gconf_client_get_int(client, "/apps/gnomeradio/presets/last", NULL);
 
204
        if (mom_ps >= count)
 
205
                mom_ps = -1;
 
206
 
 
207
        return TRUE;
 
208
}                       
 
209
        
 
210
static void mute_on_exit_toggled_cb(GtkWidget* widget, gpointer data)
 
211
{
 
212
        settings.mute_on_exit = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(mute_on_exit));
 
213
}
 
214
 
 
215
static void audio_loopback_set_visible (gboolean visible)
 
216
{
 
217
        gtk_widget_set_visible (audio_label, visible);
 
218
        gtk_widget_set_visible (enabled, visible);
 
219
        gtk_widget_set_visible (disabled, visible);
 
220
}
 
221
 
 
222
static void audio_loopback_toggled_cb (GtkWidget* widget, gpointer data)
 
223
{
 
224
        settings.audio_loopback = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (enabled));
 
225
 
 
226
        if (settings.audio_loopback)
 
227
                start_radio(TRUE, data);
 
228
        else
 
229
                alsa_thread_stop();
 
230
}
 
231
 
 
232
static gboolean device_entry_activate_cb(GtkWidget *widget, gpointer data)
 
233
{
 
234
        const gchar *text;
 
235
 
 
236
        text = gtk_entry_get_text(GTK_ENTRY(device_entry));
 
237
 
 
238
        if (!strcmp(settings.device, text) || (text[0] == '\0'))
 
239
                return FALSE;
 
240
        
 
241
        if (settings.device)
 
242
                g_free(settings.device);
 
243
 
 
244
        settings.device = g_strdup(text);
 
245
        
 
246
        start_radio(TRUE, data);
 
247
 
 
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());
 
251
        
 
252
        return FALSE;
 
253
}
 
254
 
 
255
static void
 
256
device_entry_auto_activate_cb(GtkEntry* entry, const gchar* text, gpointer data)
 
257
{
 
258
        GtkEditable *editable;
 
259
 
 
260
        editable = GTK_EDITABLE (entry);
 
261
 
 
262
        text = gtk_entry_get_text(GTK_ENTRY(device_entry));
 
263
 
 
264
        autodetect = 0;
 
265
        if (0 == strcmp(text, "auto")) {
 
266
                g_signal_emit_by_name(G_OBJECT (editable), "activate");
 
267
                autodetect = 1;
 
268
 
 
269
                gtk_widget_grab_focus(add_button);
 
270
        }
 
271
}
 
272
 
 
273
static gboolean mixer_entry_activate_cb(GtkWidget *widget, gpointer data)
 
274
{
 
275
        const gchar *text;
 
276
 
 
277
        text = gtk_entry_get_text(GTK_ENTRY(mixer_entry));
 
278
 
 
279
        if (!strcmp(settings.mixer, text) || (text[0] == '\0'))
 
280
                return FALSE;
 
281
        
 
282
        if (settings.mixer)
 
283
                g_free(settings.mixer);
 
284
 
 
285
        settings.mixer = g_strdup(text);
 
286
        
 
287
        start_mixer(TRUE, data);
 
288
        
 
289
        return FALSE;
 
290
}
 
291
 
 
292
/*static gboolean bitrate_combo_change_cb(GtkComboBox *combo, gpointer data)
 
293
{
 
294
        GList *bitrates;
 
295
        gint active;
 
296
        gchar *bitrate;
 
297
 
 
298
        g_assert(combo);
 
299
        bitrates = g_object_get_data(G_OBJECT(combo), "bitrates");
 
300
        active = gtk_combo_box_get_active(combo);
 
301
        g_assert(active > -1);
 
302
        
 
303
        bitrate = (gchar*)g_list_nth_data(bitrates, active);
 
304
        g_assert(bitrate);
 
305
 
 
306
        if (rec_settings.bitrate) g_free(rec_settings.bitrate);
 
307
        rec_settings.bitrate = g_strdup(bitrate);
 
308
        
 
309
        return FALSE;
 
310
}*/
 
311
 
 
312
/*static gboolean encoder_combo_change_cb(GtkComboBox *combo, gpointer bitrate_combo)
 
313
{
 
314
        GList *encoders;
 
315
        gint active;
 
316
        gchar *encoder;
 
317
        
 
318
        g_assert(combo);
 
319
        encoders = g_object_get_data(G_OBJECT(combo), "encoders");
 
320
        active = gtk_combo_box_get_active(combo);
 
321
        g_assert(active > -1);
 
322
        
 
323
        encoder = (gchar*)g_list_nth_data(encoders, active);
 
324
        g_assert(encoder);
 
325
 
 
326
        if (g_str_equal(encoder, _("Wave file"))) rec_settings.mp3 = FALSE;
 
327
        else {
 
328
                rec_settings.mp3 = TRUE;
 
329
                if (rec_settings.encoder) g_free(rec_settings.encoder);
 
330
                rec_settings.encoder = g_strdup(encoder);
 
331
        }
 
332
        gtk_widget_set_sensitive(bitrate_combo, rec_settings.mp3);
 
333
        
 
334
        return FALSE;
 
335
}*/
 
336
 
 
337
static void audio_profile_combo_change_cb(GtkWidget *widget, gpointer user_data)
 
338
{
 
339
        GtkTreeModel *model;
 
340
        GtkTreeIter iter;
 
341
        char *media_type = NULL;
 
342
        GstEncodingProfile *profile;
 
343
 
 
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)
 
347
                return;
 
348
        gtk_tree_model_get (GTK_TREE_MODEL (model),
 
349
                            &iter,
 
350
                            0, &media_type,
 
351
                            2, &profile,
 
352
                            -1);
 
353
 
 
354
        rec_settings.profile = g_strdup(media_type);
 
355
 
 
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);
 
359
 
 
360
                gtk_widget_set_sensitive (install_button,
 
361
                                        gst_install_plugins_supported ());
 
362
        } else {
 
363
                gtk_widget_set_visible (install_button, FALSE);
 
364
        }
 
365
        g_free (media_type);
 
366
}
 
367
 
 
368
static void
 
369
audio_profile_chooser_set_active(GtkWidget *widget, const char *profile)
 
370
{
 
371
        GtkTreeIter iter;
 
372
        GtkTreeModel *model;
 
373
        gboolean done;
 
374
 
 
375
        done = FALSE;
 
376
        model = gtk_combo_box_get_model(GTK_COMBO_BOX(widget));
 
377
        if (gtk_tree_model_get_iter_first(model, &iter)) {
 
378
                do {
 
379
                        char *media_type;
 
380
 
 
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);
 
384
                                done = TRUE;
 
385
                        }
 
386
                        g_free (media_type);
 
387
                } while (done == FALSE && gtk_tree_model_iter_next(model, &iter));
 
388
        }
 
389
 
 
390
        if (done == FALSE) {
 
391
                gtk_combo_box_set_active_iter(GTK_COMBO_BOX(widget), NULL);
 
392
        }
 
393
}
 
394
 
 
395
static GtkWidget *audio_profile_choose_new(void)
 
396
{
 
397
        GstEncodingTarget *target;
 
398
        const GList *p;
 
399
        GtkWidget *combo;
 
400
        GtkCellRenderer *renderer;
 
401
        GtkTreeModel *model;
 
402
 
 
403
        model = GTK_TREE_MODEL(gtk_tree_store_new(3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER));
 
404
 
 
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);
 
408
                char *media_type;
 
409
 
 
410
                media_type = rb_gst_encoding_profile_get_media_type(profile);
 
411
                if (media_type == NULL) {
 
412
                        continue;
 
413
                }
 
414
                gtk_tree_store_insert_with_values(GTK_TREE_STORE(model),
 
415
                                                  NULL, NULL, -1,
 
416
                                                  0, media_type,
 
417
                                                  1, gst_encoding_profile_get_description(profile),
 
418
                                                  2, profile, -1);
 
419
                g_free(media_type);
 
420
        }
 
421
 
 
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);
 
426
 
 
427
        return GTK_WIDGET(combo);
 
428
}
 
429
 
 
430
static void
 
431
audio_plugin_install_done_cb (gpointer inst, gboolean retry, gpointer user_data)
 
432
{
 
433
        audio_profile_combo_change_cb (audio_profile_combo, user_data);
 
434
}
 
435
 
 
436
static void
 
437
audio_profile_install_plugins_cb (GtkWidget *widget, gpointer user_data)
 
438
{
 
439
        GstEncodingProfile *profile;
 
440
        char **details;
 
441
        GClosure *closure;
 
442
 
 
443
        /* get profile */
 
444
        profile = rb_gst_get_encoding_profile (rec_settings.profile);
 
445
        if (profile == NULL) {
 
446
                g_free (rec_settings.profile);
 
447
                return;
 
448
        }
 
449
        g_free (rec_settings.profile);
 
450
 
 
451
        /* get plugin details */
 
452
        if (rb_gst_check_missing_plugins (profile, &details, NULL) == FALSE) {
 
453
                return;
 
454
        }
 
455
 
 
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);
 
461
 
 
462
        rb_missing_plugins_install ((const char **)details, TRUE, closure);
 
463
 
 
464
        g_closure_sink (closure);
 
465
        g_strfreev (details);
 
466
}
 
467
 
 
468
static void add_button_clicked_cb(GtkWidget *widget, gpointer data)
 
469
{
 
470
        preset *ps;
 
471
        gchar *buffer;
 
472
        GtkTreeIter iter = {0};
 
473
        GtkAdjustment* v_scb;
 
474
        GtkTreePath *path = NULL;
 
475
        GtkWidget *menuitem;
 
476
        
 
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);
 
482
 
 
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);
 
485
 
 
486
        g_free(buffer);
 
487
        gtk_tree_selection_unselect_all(selection);
 
488
        
 
489
        v_scb = gtk_scrollable_get_vadjustment(GTK_SCROLLABLE(list_view));
 
490
        gtk_adjustment_set_value(v_scb, gtk_adjustment_get_upper(v_scb));
 
491
        
 
492
        if (main_visible) {
 
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);
 
496
 
 
497
                menuitem = gtk_menu_item_new_with_label(ps->title); 
 
498
                        
 
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);
 
502
        }
 
503
 
 
504
        buffer = g_strdup_printf("%d", g_list_length(settings.presets) - 1);
 
505
        path = gtk_tree_path_new_from_string(buffer);
 
506
        g_free(buffer);
 
507
        gtk_tree_view_set_cursor(GTK_TREE_VIEW(list_view), path, NULL, FALSE);
 
508
        gtk_tree_path_free(path);
 
509
 
 
510
        gtk_widget_set_sensitive(save_button, TRUE);
 
511
}
 
512
 
 
513
static void remove_button_clicked_cb(GtkWidget *widget, gpointer data)
 
514
{
 
515
        GtkTreePath *path = NULL;
 
516
        GtkTreeViewColumn *focus_column = NULL;
 
517
        GtkTreeIter iter;
 
518
        preset *ps;
 
519
        int *row;
 
520
        GList* menuitems;
 
521
        GtkWidget *menuitem;
 
522
        
 
523
        gtk_tree_view_get_cursor(GTK_TREE_VIEW(list_view), &path, &focus_column);
 
524
        
 
525
        if (!path) return;
 
526
 
 
527
        row = gtk_tree_path_get_indices(path);
 
528
        g_assert(row);
 
529
        g_assert(*row < g_list_length(settings.presets));
 
530
 
 
531
        ps = g_list_nth_data(settings.presets, *row);
 
532
        g_assert(ps);   
 
533
        settings.presets = g_list_remove(settings.presets, (gpointer)ps);
 
534
        g_free(ps->title);
 
535
        g_free(ps);
 
536
        
 
537
        gtk_tree_model_get_iter(GTK_TREE_MODEL(list_store), &iter, path);
 
538
        gtk_list_store_remove(list_store, &iter);
 
539
 
 
540
        if (main_visible) {
 
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);
 
545
 
 
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);
 
550
        }
 
551
        
 
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);
 
555
 
 
556
        if (settings.presets == NULL) {
 
557
                gtk_widget_set_sensitive(save_button, FALSE);
 
558
        } else {
 
559
                gtk_widget_set_sensitive(save_button, TRUE);
 
560
        }
 
561
}
 
562
 
 
563
static void move_up_button_clicked_cb(GtkWidget * widget, gpointer data)
 
564
{
 
565
        GtkTreeIter iter, iter2;
 
566
        GtkTreePath *path, *path2;
 
567
        gint pos;
 
568
        preset *ps;
 
569
        int *row;
 
570
        GList* menuitems;
 
571
        GtkWidget *menuitem;
 
572
 
 
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);
 
576
 
 
577
        path2 = path;
 
578
        gtk_tree_path_prev(path2);
 
579
 
 
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);
 
583
        }
 
584
 
 
585
        row = gtk_tree_path_get_indices(path);
 
586
        g_assert(row);
 
587
        g_assert(*row < g_list_length(settings.presets));
 
588
 
 
589
        ps = g_list_nth_data(settings.presets, *row);
 
590
        g_assert(ps);
 
591
        pos = g_list_index(settings.presets, (gpointer)ps);
 
592
        pos++;
 
593
 
 
594
        settings.presets = g_list_remove(settings.presets, (gpointer)ps);
 
595
        settings.presets = g_list_insert(settings.presets, (gpointer)ps, pos);
 
596
 
 
597
        if (main_visible) {
 
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);
 
600
                mom_ps = *row;
 
601
                preset_combo_set_item(mom_ps);
 
602
 
 
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);
 
608
 
 
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);
 
612
        }
 
613
 
 
614
        gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(list_view), path, NULL, FALSE, 0, 0);
 
615
        gtk_tree_path_free(path);
 
616
 
 
617
        if (pos - 1 <= 0) {
 
618
                gtk_widget_set_sensitive(move_up_button, FALSE);
 
619
        } else {
 
620
                gtk_widget_set_sensitive(move_up_button, TRUE);
 
621
        }
 
622
        gtk_widget_set_sensitive(move_down_button, TRUE);
 
623
}
 
624
 
 
625
static void move_down_button_clicked_cb(GtkWidget * widget, gpointer data)
 
626
{
 
627
        GtkTreeIter iter, iter2;
 
628
        GtkTreePath *path, *path2;
 
629
        gint pos, count;
 
630
        preset *ps;
 
631
        int *row;
 
632
        GList* menuitems;
 
633
        GtkWidget *menuitem;
 
634
 
 
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);
 
638
 
 
639
        path2 = path;
 
640
        gtk_tree_path_next(path2);
 
641
 
 
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);
 
645
        }
 
646
 
 
647
        row = gtk_tree_path_get_indices(path);
 
648
        g_assert(row);
 
649
        g_assert(*row < g_list_length(settings.presets));
 
650
 
 
651
        ps = g_list_nth_data(settings.presets, *row);
 
652
        g_assert(ps);
 
653
 
 
654
        count = g_list_length(settings.presets);
 
655
        pos = g_list_index(settings.presets, (gpointer)ps);
 
656
        pos--;
 
657
        if (pos == count)
 
658
                pos = 0;
 
659
 
 
660
        settings.presets = g_list_remove(settings.presets, (gpointer)ps);
 
661
        settings.presets = g_list_insert(settings.presets, (gpointer)ps, pos);
 
662
 
 
663
        if (main_visible) {
 
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);
 
666
                mom_ps = *row;
 
667
                preset_combo_set_item(mom_ps);
 
668
 
 
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);
 
674
 
 
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);
 
678
        }
 
679
 
 
680
        gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(list_view), path, NULL, FALSE, 0, 0);
 
681
        gtk_tree_path_free(path);
 
682
 
 
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);
 
685
        } else {
 
686
                gtk_widget_set_sensitive(move_down_button, TRUE);
 
687
        }
 
688
        gtk_widget_set_sensitive(move_up_button, TRUE);
 
689
}
 
690
 
 
691
static void destination_button_clicked_cb(GtkWidget *button, gpointer data)
 
692
{
 
693
        if (rec_settings.destination)
 
694
        {
 
695
                g_free(rec_settings.destination);
 
696
        }
 
697
        rec_settings.destination = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(button));
 
698
}
 
699
 
 
700
static gboolean list_view_key_press_event_cb(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
 
701
{
 
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);
 
706
        
 
707
        return FALSE;
 
708
}               
 
709
 
 
710
static gboolean button_release_cb(GtkWidget *widget, GdkEvent *event, gpointer data)
 
711
{
 
712
        GtkTreePath *path;
 
713
        gint pos;
 
714
        GdkEventButton *event_button;
 
715
        gchar *buffer;
 
716
 
 
717
        event_button = (GdkEventButton *) event;
 
718
 
 
719
        gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(list_view), event_button->x, event_button->y, &path, NULL, NULL, NULL);
 
720
        if (path != NULL) {
 
721
                buffer = gtk_tree_path_to_string(path);
 
722
                pos = (gint) g_strtod(buffer, NULL);
 
723
                g_free(buffer);
 
724
                gtk_tree_path_free(path);
 
725
 
 
726
                if (pos == 0) {
 
727
                        gtk_widget_set_sensitive(move_up_button, FALSE);
 
728
                } else {
 
729
                        gtk_widget_set_sensitive(move_up_button, TRUE);
 
730
                }
 
731
 
 
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);
 
734
                } else {
 
735
                        gtk_widget_set_sensitive(move_down_button, TRUE);
 
736
                }
 
737
        }
 
738
        return FALSE;
 
739
}
 
740
 
 
741
static void name_cell_edited_cb(GtkCellRendererText *cellrenderertext, gchar *path_str, gchar *new_val, gpointer user_data)
 
742
{
 
743
        GtkTreePath *path = NULL;
 
744
        GtkTreeIter iter;
 
745
        preset *ps;
 
746
        int *row;
 
747
        GList* menuitems;
 
748
        GtkWidget *menuitem;
 
749
        
 
750
        path = gtk_tree_path_new_from_string(path_str);
 
751
 
 
752
        row = gtk_tree_path_get_indices(path);
 
753
        g_assert(row);
 
754
        g_assert(*row < g_list_length(settings.presets));
 
755
 
 
756
        ps = g_list_nth_data(settings.presets, *row);
 
757
        g_assert(ps);   
 
758
        if (ps->title) g_free(ps->title);
 
759
        ps->title = g_strdup(new_val);
 
760
 
 
761
        if (main_visible) {
 
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);
 
764
                mom_ps = *row;
 
765
                preset_combo_set_item(mom_ps);
 
766
 
 
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); 
 
772
                        
 
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);
 
776
        }
 
777
        
 
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);       
 
781
}       
 
782
 
 
783
static void freq_cell_edited_cb(GtkCellRendererText *cellrenderertext, gchar *path_str, gchar *new_val, gpointer user_data)
 
784
{
 
785
        GtkTreePath *path = NULL;
 
786
        GtkTreeIter iter;
 
787
        preset *ps;
 
788
        int *row;
 
789
        double value;
 
790
        gchar *freq_str;
 
791
        
 
792
        if (sscanf(new_val, "%lf", &value) != 1) return;
 
793
        
 
794
        if (value < FREQ_MIN) value = FREQ_MIN;
 
795
        if (value > FREQ_MAX) value = FREQ_MAX;
 
796
        value = rint(value * STEPS) / STEPS;
 
797
        
 
798
        freq_str = g_strdup_printf("%.2f", value);
 
799
        
 
800
        path = gtk_tree_path_new_from_string(path_str);
 
801
        
 
802
        row = gtk_tree_path_get_indices(path);
 
803
        g_assert(row);
 
804
        g_assert(*row < g_list_length(settings.presets));
 
805
 
 
806
        ps = g_list_nth_data(settings.presets, *row);
 
807
        g_assert(ps);   
 
808
        ps->freq = value;
 
809
 
 
810
        gtk_adjustment_set_value(adj, value * STEPS);
 
811
        mom_ps = *row;
 
812
        preset_combo_set_item(mom_ps);
 
813
        
 
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);
 
816
        g_free(freq_str);
 
817
        gtk_tree_path_free(path);       
 
818
}       
 
819
 
 
820
static void list_view_cursor_changed_cb(GtkWidget *widget, gpointer data)
 
821
{
 
822
        int *row;
 
823
        preset *ps;
 
824
        gint pos;
 
825
        GtkTreePath *path = NULL;
 
826
        GtkTreeViewColumn *focus_column = NULL;
 
827
        
 
828
        if (settings.presets == NULL)
 
829
                return;
 
830
 
 
831
        gtk_tree_view_get_cursor(GTK_TREE_VIEW(list_view), &path, &focus_column);
 
832
        
 
833
        if (!path)
 
834
                return;
 
835
 
 
836
        row = gtk_tree_path_get_indices(path);
 
837
        g_assert(row);
 
838
 
 
839
        mom_ps = *row;
 
840
        preset_combo_set_item(mom_ps);
 
841
 
 
842
        ps = g_list_nth_data(settings.presets, *row);
 
843
        g_assert(ps);
 
844
 
 
845
        pos = g_list_index(settings.presets, (gpointer)ps);
 
846
 
 
847
        if (pos == 0) {
 
848
                gtk_widget_set_sensitive(move_up_button, FALSE);
 
849
        } else {
 
850
                gtk_widget_set_sensitive(move_up_button, TRUE);
 
851
        }
 
852
 
 
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);
 
855
        } else {
 
856
                        gtk_widget_set_sensitive(move_down_button, TRUE);
 
857
        }
 
858
        gtk_tree_path_free(path);
 
859
        return;
 
860
}
 
861
 
 
862
static void list_view_selection_changed_cb(GtkWidget *widget, gpointer data)
 
863
{
 
864
        gboolean sel;
 
865
 
 
866
        sel = gtk_tree_selection_get_selected(selection, NULL, NULL);
 
867
 
 
868
        gtk_widget_set_sensitive(remove_button, sel);
 
869
        gtk_widget_set_sensitive(save_button, sel);
 
870
}
 
871
 
 
872
static void list_view_scroll_to_active_preset_cb(GtkWidget *widget, gpointer data)
 
873
{
 
874
        GtkTreePath *path = NULL;
 
875
        GtkTreeIter iter;
 
876
        gint active;
 
877
 
 
878
        if (settings.presets == NULL) {
 
879
                gtk_widget_grab_focus(add_button);
 
880
                return;
 
881
        }
 
882
 
 
883
        active = gtk_combo_box_get_active(GTK_COMBO_BOX(preset_combo)) - 1;
 
884
 
 
885
        if (active < 0) {
 
886
                gtk_widget_grab_focus(add_button);
 
887
                return;
 
888
        }
 
889
 
 
890
        if (!gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(list_store), &iter, NULL, active))
 
891
                return;
 
892
 
 
893
        path = gtk_tree_model_get_path(GTK_TREE_MODEL(list_store), &iter);
 
894
 
 
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);
 
898
 
 
899
        gtk_widget_grab_focus(list_view);
 
900
}
 
901
 
 
902
static void free_presets_list (gpointer data)
 
903
{
 
904
        preset *ps = (preset *) data;
 
905
        g_free (ps->title);
 
906
        g_free (ps);
 
907
}
 
908
 
 
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)
 
911
{
 
912
        gchar *title, *freq, *position;
 
913
        xmlNodePtr current;
 
914
 
 
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 */
 
928
        g_free(title);
 
929
        g_free(freq);
 
930
        g_free(position);
 
931
 
 
932
        /* return FALSE to keep iterating */
 
933
        return FALSE;
 
934
}
 
935
 
 
936
/* Function handle saving an xml file; calls save_to_file_foreach */
 
937
static void save_to_file(gchar *filename)
 
938
{
 
939
        GtkTreeModel *model;
 
940
        xmlDocPtr doc;
 
941
        xmlNodePtr root;
 
942
 
 
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 */
 
956
        xmlFreeDoc(doc);
 
957
}
 
958
 
 
959
/* Callback for the "Save to file" button; calls save_to_file */
 
960
static void save_to_file_cb(GtkWidget *button, gpointer data)
 
961
{
 
962
        GtkWidget *dialog;
 
963
        GtkFileFilter *file_filter_all;
 
964
        GtkFileFilter *file_filter_xml;
 
965
        gchar *filename;
 
966
 
 
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,
 
971
                                              NULL);
 
972
 
 
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);
 
977
 
 
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);
 
984
 
 
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");
 
988
 
 
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")) {
 
993
                        char *tmp_file;
 
994
                        /* create copy of filename to release it and create a new one, using old name */
 
995
                        tmp_file = g_strdup(filename);
 
996
                        g_free(filename);
 
997
                        filename = g_strdup_printf("%s.xml", tmp_file);
 
998
                        g_free(tmp_file);
 
999
                }
 
1000
                save_to_file(filename);
 
1001
                g_free(filename);
 
1002
        }
 
1003
        gtk_widget_destroy(dialog);
 
1004
}
 
1005
 
 
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)
 
1011
{
 
1012
        gchar *colon;
 
1013
 
 
1014
        g_return_val_if_fail(path != NULL, NULL);
 
1015
 
 
1016
        colon = g_strrstr(path, ":");
 
1017
        if (colon == NULL)
 
1018
                  return NULL;
 
1019
 
 
1020
        return g_strndup(path, colon - path);
 
1021
}
 
1022
 
 
1023
/* Make sure that path exists within model */
 
1024
static void gtk_tree_model_generate_path(GtkTreeModel *model, gchar *path)
 
1025
{
 
1026
        GtkTreeIter iter, parent;
 
1027
        gchar *temp;
 
1028
 
 
1029
        while (TRUE) {
 
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))
 
1032
                        break;
 
1033
 
 
1034
                temp = path;
 
1035
                path = gtk_tree_path_string_get_parent(path);
 
1036
                /* if there's no parent, then it's toplevel */
 
1037
                if (path == NULL) {
 
1038
                        if (GTK_IS_TREE_STORE(model))
 
1039
                                gtk_tree_store_append(GTK_TREE_STORE(model), &parent, NULL);
 
1040
                        else
 
1041
                                gtk_list_store_append(GTK_LIST_STORE(model), &parent);
 
1042
                                gtk_tree_model_generate_path(model, temp);
 
1043
                                break;
 
1044
                }
 
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);
 
1049
                }
 
1050
        }
 
1051
}
 
1052
 
 
1053
/* Function to load from an xml file */
 
1054
static void load_from_file(gchar *filename)
 
1055
{
 
1056
        xmlDocPtr doc;
 
1057
        xmlNodePtr current;
 
1058
        xmlChar *title, *freq, *position;
 
1059
        GtkTreeModel *model;
 
1060
        GtkTreePath *path = NULL;
 
1061
        GtkTreeIter iter;
 
1062
        GtkAdjustment* v_scb;
 
1063
        GList* menuitems;
 
1064
        GtkWidget *menuitem;
 
1065
 
 
1066
        /* load the file */
 
1067
        doc = xmlParseFile(filename);
 
1068
        /* get the root item */
 
1069
        if (doc == NULL)
 
1070
                return;
 
1071
 
 
1072
        current = xmlDocGetRootElement(doc);
 
1073
        if (current == NULL) {
 
1074
                xmlFreeDoc(doc);
 
1075
                return;
 
1076
        }
 
1077
 
 
1078
        if (xmlStrcmp(current->name, (guchar*)"gnomeradio")) {
 
1079
                xmlFreeDoc(doc);
 
1080
                return;
 
1081
        }
 
1082
 
 
1083
        /* remove previous presets */
 
1084
        if (settings.presets != NULL) {
 
1085
                if (main_visible) {
 
1086
                        gint i, count;
 
1087
 
 
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);
 
1091
 
 
1092
                        menuitems = gtk_container_get_children (GTK_CONTAINER (tray_menu));
 
1093
 
 
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);
 
1098
                        }
 
1099
                }
 
1100
 
 
1101
                gtk_list_store_clear(GTK_LIST_STORE(list_store));
 
1102
 
 
1103
                g_list_free_full (settings.presets, free_presets_list);
 
1104
                settings.presets = NULL;
 
1105
        }
 
1106
 
 
1107
        /* get the tree view's model */
 
1108
        model = gtk_tree_view_get_model(GTK_TREE_VIEW(list_view));
 
1109
 
 
1110
        /* iterate through the root's children items */
 
1111
        current = current->xmlChildrenNode;
 
1112
        while (current) {
 
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");
 
1120
 
 
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);
 
1125
 
 
1126
                                        settings.presets = g_list_append(settings.presets, ps);
 
1127
 
 
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);
 
1132
                                        /* set the data */
 
1133
                                        gtk_list_store_set(GTK_LIST_STORE(list_store), &iter, 0, title, 1, freq, -1);
 
1134
 
 
1135
                                        gtk_tree_selection_unselect_all(selection);
 
1136
 
 
1137
                                        v_scb = gtk_scrollable_get_vadjustment(GTK_SCROLLABLE(list_view));
 
1138
                                        gtk_adjustment_set_value(v_scb, gtk_adjustment_get_upper(v_scb));
 
1139
 
 
1140
                                        if (main_visible) {
 
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);
 
1144
 
 
1145
                                                menuitem = gtk_menu_item_new_with_label(ps->title);
 
1146
 
 
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);
 
1152
                                        }
 
1153
                                }
 
1154
                                /* free the data */
 
1155
                                xmlFree(title);
 
1156
                                xmlFree(freq);
 
1157
                                xmlFree(position);
 
1158
                        }
 
1159
                        current = current->next;
 
1160
                }
 
1161
        }
 
1162
        /* free the doc node */
 
1163
        xmlFreeDoc(doc);
 
1164
 
 
1165
        if (settings.presets == NULL)
 
1166
                return;
 
1167
 
 
1168
        path = gtk_tree_model_get_path(GTK_TREE_MODEL(list_store), &iter);
 
1169
 
 
1170
        gtk_tree_view_set_cursor(GTK_TREE_VIEW (list_view), path, NULL, FALSE );
 
1171
        gtk_tree_path_free(path);
 
1172
 
 
1173
        gtk_widget_grab_focus(list_view);
 
1174
 
 
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);
 
1178
}
 
1179
 
 
1180
/* Callback for the "Load from file" button; calls load_from_file */
 
1181
static void load_from_file_cb(GtkWidget *button, gpointer data)
 
1182
{
 
1183
        GtkWidget *dialog;
 
1184
        GtkFileFilter *file_filter_all;
 
1185
        GtkFileFilter *file_filter_xml;
 
1186
        gchar *filename;
 
1187
 
 
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,
 
1192
                                              NULL);
 
1193
 
 
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);
 
1198
 
 
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);
 
1205
 
 
1206
        gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(dialog), file_filter_xml);
 
1207
 
 
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);
 
1211
                g_free(filename);
 
1212
        }
 
1213
        gtk_widget_destroy(dialog);
 
1214
}
 
1215
 
 
1216
gboolean action_mode (gint mode)
 
1217
{
 
1218
        switch (mode) {
 
1219
                case RADIO_DEVICE:
 
1220
                        gtk_widget_grab_focus (device_entry);
 
1221
                        break;
 
1222
                case MIXER_DEVICE:
 
1223
                        gtk_widget_grab_focus (mixer_entry);
 
1224
                        break;
 
1225
                case PRESETS:
 
1226
                        list_view_scroll_to_active_preset_cb(list_view, NULL);
 
1227
                        break;
 
1228
                default:
 
1229
                        break;
 
1230
        }
 
1231
 
 
1232
        return TRUE;
 
1233
}
 
1234
 
 
1235
GtkWidget* prefs_window(GtkWidget *app)
 
1236
{
 
1237
        GtkWidget *dialog;
 
1238
        GtkWidget *content_area;
 
1239
        GtkWidget *box;
 
1240
        GtkWidget *grid;
 
1241
        GtkWidget *label;
 
1242
        GtkWidget *scrolled_window;
 
1243
        GtkCellRenderer *cellrenderer;
 
1244
        GtkTreeViewColumn *list_column;
 
1245
        GtkWidget *button_box;
 
1246
        GtkWidget *open_button;
 
1247
        GtkWidget *destination_button;
 
1248
        GtkWidget *image;
 
1249
 
 
1250
        GstEncodingProfile *profile;
 
1251
 
 
1252
        gint i;
 
1253
        gchar *markup;
 
1254
        preset* ps;
 
1255
        GList *l;
 
1256
        
 
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,
 
1261
                                              NULL);
 
1262
        
 
1263
        gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE);
 
1264
        gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_CLOSE);
 
1265
 
 
1266
        content_area = gtk_dialog_get_content_area (GTK_DIALOG(dialog));
 
1267
 
 
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);
 
1271
        
 
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);
 
1276
 
 
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);
 
1282
        g_free (markup);
 
1283
        gtk_grid_attach(GTK_GRID(grid), label, 0, 0, 1, 1);
 
1284
 
 
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);
 
1289
 
 
1290
        device_entry = gtk_entry_new();
 
1291
 
 
1292
        if (autodetect)
 
1293
                gtk_entry_set_placeholder_text(GTK_ENTRY(device_entry), "auto");
 
1294
        else
 
1295
                gtk_entry_set_text(GTK_ENTRY(device_entry), settings.device);
 
1296
 
 
1297
        gtk_grid_attach(GTK_GRID(grid), device_entry, 1, 1, 1, 1);
 
1298
 
 
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);
 
1303
 
 
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);
 
1307
 
 
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);
 
1313
 
 
1314
        box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
 
1315
 
 
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);
 
1323
 
 
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);
 
1327
        else
 
1328
                gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (disabled), TRUE);
 
1329
 
 
1330
        if (settings.audio_loopback)
 
1331
                if (alsa_loopback)
 
1332
                        audio_loopback_set_visible (TRUE);
 
1333
                else
 
1334
                        audio_loopback_set_visible (FALSE);
 
1335
        else
 
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());
 
1339
 
 
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);
 
1344
 
 
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);
 
1352
 
 
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"));
 
1358
 
 
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);
 
1364
        g_free (markup);
 
1365
        gtk_grid_attach(GTK_GRID(grid), label, 0, 5, 1, 1);
 
1366
 
 
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);
 
1372
 
 
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);
 
1377
 
 
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);
 
1381
 
 
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);
 
1385
 
 
1386
        g_signal_connect(G_OBJECT(selection), "changed", G_CALLBACK(list_view_selection_changed_cb), list_view);
 
1387
 
 
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);*/
 
1390
        
 
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);
 
1398
 
 
1399
        g_signal_connect(G_OBJECT(cellrenderer), "edited", G_CALLBACK(name_cell_edited_cb), NULL);
 
1400
 
 
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);
 
1409
 
 
1410
        g_signal_connect(G_OBJECT(cellrenderer), "edited", G_CALLBACK(freq_cell_edited_cb), NULL);
 
1411
 
 
1412
        i = 0;
 
1413
        for (l = settings.presets; l != NULL; l = l->next) {
 
1414
                GtkTreeIter iter = {0};
 
1415
                char *buffer;
 
1416
                ps = l->data;
 
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);
 
1420
                g_free(buffer);
 
1421
                i++;
 
1422
        }
 
1423
 
 
1424
        gtk_grid_attach(GTK_GRID(grid), scrolled_window, 0, 6, 2, 1);
 
1425
 
 
1426
        button_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
 
1427
 
 
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"));
 
1434
 
 
1435
        g_signal_connect(G_OBJECT(move_up_button), "clicked", G_CALLBACK(move_up_button_clicked_cb), NULL);
 
1436
 
 
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"));
 
1443
 
 
1444
        g_signal_connect(G_OBJECT(move_down_button), "clicked", G_CALLBACK(move_down_button_clicked_cb), NULL);
 
1445
 
 
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"));
 
1451
 
 
1452
        g_signal_connect(G_OBJECT(add_button), "clicked", G_CALLBACK(add_button_clicked_cb), NULL);
 
1453
 
 
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);
 
1460
 
 
1461
        g_signal_connect(G_OBJECT(remove_button), "clicked", G_CALLBACK(remove_button_clicked_cb), NULL);
 
1462
 
 
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"));
 
1468
 
 
1469
        if (settings.presets == NULL)
 
1470
                gtk_widget_set_sensitive (save_button, FALSE);
 
1471
        else
 
1472
                gtk_widget_set_sensitive (save_button, TRUE);
 
1473
 
 
1474
        g_signal_connect(G_OBJECT(save_button), "clicked", G_CALLBACK(save_to_file_cb), NULL);
 
1475
 
 
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);
 
1482
 
 
1483
        g_signal_connect(G_OBJECT(open_button), "clicked", G_CALLBACK(load_from_file_cb), NULL);
 
1484
 
 
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);
 
1491
 
 
1492
        gtk_grid_attach(GTK_GRID(grid), button_box, 1, 7, 1, 1);
 
1493
 
 
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);
 
1499
        g_free (markup);
 
1500
        gtk_grid_attach (GTK_GRID (grid), label, 0, 8, 1, 1);
 
1501
 
 
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);
 
1506
 
 
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);
 
1510
 
 
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);
 
1515
 
 
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);
 
1519
 
 
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);
 
1523
 
 
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 ());
 
1529
        } else {
 
1530
                gtk_widget_set_visible (install_button, FALSE);
 
1531
        }
 
1532
 
 
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);
 
1536
 
 
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."));
 
1539
 
 
1540
        gtk_widget_show_all(dialog);
 
1541
 
 
1542
        return dialog;
 
1543
}