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

« back to all changes in this revision

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

  • Committer: Package Import Robot
  • Author(s): POJAR GEORGE
  • Date: 2013-09-11 15:06:44 UTC
  • Revision ID: package-import@ubuntu.com-20130911150644-l8x3ubsyqmrvnkh8
Tags: 1.8-2ubuntu20
* Updated debian/patches/gnomeradio-station_list.patch: Prevent to parse
  malformed/incomplete/invalid XML file.
* Updated debian/patches/gnomeradio-auto_device.patch:
  - Automatically detect radio device when users type auto in settings field.
  - Updated error messages to be clear and precise.
* Updated debian/patches/gnomeradio-alsamixer.patch: Make presets list the
  default widget when open settings dialog. Presets are the most common
  settings for users than devices settings.
* Updated debian/patches/gnomeradio-about.patch: It is not safe in principle
  to write raw UTF-8 in narrow string literals, made to be multibyte
  encodings.
* debian/patches/gnomeradio-prefs.patch: Renamed to
  debian/patches/gnomeradio-about.patch.
* debian/patches/gnomeradio-preferences.patch: Make sentence capitalization in
  text and increased preferences dialog.

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
 
 
33
extern int autodetect;
 
34
 
 
35
extern GtkWidget *preset_combo;
 
36
extern GtkAdjustment *adj;
 
37
 
 
38
extern int mom_ps;
 
39
extern gnomeradio_settings settings;
 
40
 
 
41
extern gboolean main_visible;
 
42
 
 
43
static GtkWidget *device_entry;
 
44
static GtkWidget *mixer_entry;
 
45
static GtkWidget *mute_on_exit_cb;
 
46
static GtkWidget *list_view;
 
47
static GtkListStore *list_store;
 
48
static GtkTreeSelection *selection;
 
49
static GtkWidget *save_button;
 
50
static GtkWidget *move_up_button;
 
51
static GtkWidget *move_down_button;
 
52
static GtkWidget *add_button;
 
53
static GtkWidget *remove_button;
 
54
static GtkWidget *audio_profile_combo;
 
55
static GtkWidget *install_button;
 
56
 
 
57
gboolean save_settings(void)
 
58
{
 
59
        gint i, count;
 
60
        gchar *buffer;
 
61
        preset *ps;
 
62
        GConfClient* client = NULL;
 
63
        
 
64
        if (!gconf_is_initialized())
 
65
                return FALSE;
 
66
 
 
67
        client = gconf_client_get_default();
 
68
        if (!client)
 
69
                return FALSE;
 
70
        
 
71
        /* Store general settings */
 
72
        if (autodetect)
 
73
                gconf_client_set_string(client, "/apps/gnomeradio/device", "auto", NULL);
 
74
        else
 
75
                gconf_client_set_string(client, "/apps/gnomeradio/device", settings.device, NULL);
 
76
        gconf_client_set_string(client, "/apps/gnomeradio/driver", settings.driver, NULL);
 
77
        gconf_client_set_string(client, "/apps/gnomeradio/mixer", settings.mixer, NULL);
 
78
        gconf_client_set_bool(client, "/apps/gnomeradio/mute-on-exit", settings.mute_on_exit, NULL);
 
79
        /*gconf_client_set_float(client, "/apps/gnomeradio/volume", volume->value, NULL);*/
 
80
        gconf_client_set_float(client, "/apps/gnomeradio/last-freq", gtk_adjustment_get_value(adj)/STEPS, NULL);
 
81
 
 
82
        /* Store recording settings */
 
83
/*      gconf_client_set_string(client, "/apps/gnomeradio/recording/audiodevice", rec_settings.audiodevice, NULL);
 
84
        gconf_client_set_bool(client, "/apps/gnomeradio/recording/record-as-mp3", rec_settings.mp3, NULL);
 
85
        gconf_client_set_string(client, "/apps/gnomeradio/recording/sample-rate", rec_settings.rate, NULL);
 
86
        gconf_client_set_string(client, "/apps/gnomeradio/recording/sample-format", rec_settings.sample, NULL);
 
87
        gconf_client_set_bool(client, "/apps/gnomeradio/recording/record-in-stereo", rec_settings.stereo, NULL);
 
88
        gconf_client_set_string(client, "/apps/gnomeradio/recording/encoder", rec_settings.encoder, NULL);
 
89
        gconf_client_set_string(client, "/apps/gnomeradio/recording/bitrate", rec_settings.bitrate, NULL);
 
90
*/
 
91
 
 
92
        gconf_client_set_string(client, "/apps/gnomeradio/recording/destination", rec_settings.destination, NULL);
 
93
        gconf_client_set_string(client, "/apps/gnomeradio/recording/profile", rec_settings.profile, NULL);
 
94
 
 
95
        /* Store the presets */
 
96
        count = g_list_length(settings.presets);
 
97
        gconf_client_set_int(client, "/apps/gnomeradio/presets/presets", count, NULL);
 
98
        for (i = 0; i < count; i++)
 
99
        {
 
100
                ps = g_list_nth_data(settings.presets, i);
 
101
                buffer = g_strdup_printf("/apps/gnomeradio/presets/%d/name", i);
 
102
                gconf_client_set_string(client, buffer, ps->title, NULL); 
 
103
                g_free(buffer);
 
104
                buffer = g_strdup_printf("/apps/gnomeradio/presets/%d/freqency", i);
 
105
                gconf_client_set_float(client, buffer, ps->freq, NULL); 
 
106
                g_free(buffer);
 
107
        }       
 
108
        gconf_client_set_int(client, "/apps/gnomeradio/presets/last", mom_ps, NULL);
 
109
        /*g_print("Storing Settings in GConf database\n");*/
 
110
        
 
111
        return TRUE;
 
112
}                       
 
113
 
 
114
gboolean load_settings(void)
 
115
{
 
116
        gint i, count;
 
117
        gchar *buffer;
 
118
        preset *ps;
 
119
        GConfClient *client = NULL;
 
120
        double freq;
 
121
        
 
122
        settings.presets = NULL;
 
123
                
 
124
        if (!gconf_is_initialized())
 
125
                return FALSE;
 
126
        
 
127
        client = gconf_client_get_default();
 
128
        if (!client)
 
129
                return FALSE;
 
130
 
 
131
        /* Load general settings */
 
132
        settings.device = gconf_client_get_string(client, "/apps/gnomeradio/device" , NULL);
 
133
        if (!settings.device)
 
134
                settings.device = g_strdup("auto");
 
135
        settings.driver = gconf_client_get_string(client, "/apps/gnomeradio/driver" , NULL);
 
136
        if (!settings.driver)
 
137
                settings.driver = g_strdup("any");
 
138
        settings.mixer = gconf_client_get_string(client, "/apps/gnomeradio/mixer", NULL);
 
139
        if (!settings.mixer)
 
140
                settings.mixer = g_strdup("hw:0/Line");
 
141
        settings.mute_on_exit = gconf_client_get_bool(client, "/apps/gnomeradio/mute-on-exit", NULL);
 
142
        /*volume->value = gconf_client_get_float(client, "/apps/gnomeradio/volume", NULL);*/
 
143
        freq = gconf_client_get_float(client, "/apps/gnomeradio/last-freq", NULL);
 
144
        if ((freq < FREQ_MIN) || (freq > FREQ_MAX))
 
145
                gtk_adjustment_set_value(adj, FREQ_MIN * STEPS);
 
146
        else
 
147
                gtk_adjustment_set_value(adj, freq * STEPS);
 
148
        
 
149
        /* Load recording settings */
 
150
/*      rec_settings.audiodevice = gconf_client_get_string(client, "/apps/gnomeradio/recording/audiodevice", NULL);
 
151
        if (!rec_settings.audiodevice)
 
152
                rec_settings.audiodevice = g_strdup("/dev/audio");
 
153
        rec_settings.mp3 = gconf_client_get_bool(client, "/apps/gnomeradio/recording/record-as-mp3", NULL);
 
154
        rec_settings.rate = gconf_client_get_string(client, "/apps/gnomeradio/recording/sample-rate", NULL);
 
155
        if (!rec_settings.rate)
 
156
                rec_settings.rate = g_strdup("44100");
 
157
        rec_settings.sample = gconf_client_get_string(client, "/apps/gnomeradio/recording/sample-format", NULL);
 
158
        if (!rec_settings.sample)
 
159
                rec_settings.sample = g_strdup("16");
 
160
        rec_settings.stereo = gconf_client_get_bool(client, "/apps/gnomeradio/recording/record-in-stereo", NULL);
 
161
        rec_settings.encoder = gconf_client_get_string(client, "/apps/gnomeradio/recording/encoder", NULL);
 
162
        if (!rec_settings.encoder)
 
163
                rec_settings.encoder = g_strdup("oggenc");
 
164
        rec_settings.bitrate = gconf_client_get_string(client, "/apps/gnomeradio/recording/bitrate", NULL);
 
165
        if (!rec_settings.bitrate)
 
166
                rec_settings.bitrate = g_strdup("192");*/
 
167
 
 
168
        rec_settings.destination = gconf_client_get_string(client, "/apps/gnomeradio/recording/destination", NULL);
 
169
        if (!rec_settings.destination)
 
170
                rec_settings.destination = g_strdup(g_get_home_dir());
 
171
        rec_settings.profile = gconf_client_get_string(client, "/apps/gnomeradio/recording/profile", NULL);
 
172
        if (!rec_settings.profile)
 
173
                rec_settings.profile = g_strdup("audio/x-vorbis");
 
174
        
 
175
        /* Load the presets */
 
176
        count = gconf_client_get_int(client, "/apps/gnomeradio/presets/presets", NULL);
 
177
        for (i = 0; i < count; i++)
 
178
        {
 
179
                ps = malloc(sizeof(preset));
 
180
                buffer = g_strdup_printf("/apps/gnomeradio/presets/%d/name", i);
 
181
                ps->title = gconf_client_get_string(client, buffer, NULL); 
 
182
                g_free(buffer);
 
183
                if (!ps->title)
 
184
                        ps->title = g_strdup(_("unnamed"));
 
185
                buffer = g_strdup_printf("/apps/gnomeradio/presets/%d/freqency", i);
 
186
                freq = gconf_client_get_float(client, buffer, NULL); 
 
187
                if ((freq < FREQ_MIN) || (freq > FREQ_MAX))
 
188
                        ps->freq = FREQ_MIN;
 
189
                else
 
190
                        ps->freq = freq;
 
191
                g_free(buffer);
 
192
                settings.presets = g_list_prepend(settings.presets, (gpointer)ps);
 
193
        }       
 
194
        settings.presets = g_list_reverse(settings.presets);
 
195
 
 
196
        mom_ps = gconf_client_get_int(client, "/apps/gnomeradio/presets/last", NULL);
 
197
        if (mom_ps >= count)
 
198
                mom_ps = -1;
 
199
 
 
200
        return TRUE;
 
201
}                       
 
202
        
 
203
static void mute_on_exit_toggled_cb(GtkWidget* widget, gpointer data)
 
204
{
 
205
        settings.mute_on_exit = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(mute_on_exit_cb));
 
206
}       
 
207
 
 
208
static gboolean device_entry_activate_cb(GtkWidget *widget, gpointer data)
 
209
{
 
210
        const gchar *text;
 
211
 
 
212
        text = gtk_entry_get_text(GTK_ENTRY(device_entry));
 
213
 
 
214
        if (!strcmp(settings.device, text) || (text[0] == '\0'))
 
215
                return FALSE;
 
216
        
 
217
        if (settings.device)
 
218
                g_free(settings.device);
 
219
 
 
220
        settings.device = g_strdup(text);
 
221
        
 
222
        start_radio(TRUE, data);
 
223
        
 
224
        return FALSE;
 
225
}
 
226
 
 
227
static void
 
228
device_entry_auto_activate_cb(GtkEntry* entry, const gchar* text, gpointer data)
 
229
{
 
230
        GtkEditable *editable;
 
231
 
 
232
        editable = GTK_EDITABLE (entry);
 
233
 
 
234
        text = gtk_entry_get_text(GTK_ENTRY(device_entry));
 
235
 
 
236
        autodetect = 0;
 
237
        if (0 == strcmp(text, "auto")) {
 
238
                g_signal_emit_by_name(G_OBJECT (editable), "activate");
 
239
                autodetect = 1;
 
240
 
 
241
                gtk_widget_grab_focus(add_button);
 
242
        }
 
243
}
 
244
 
 
245
static gboolean mixer_entry_activate_cb(GtkWidget *widget, gpointer data)
 
246
{
 
247
        const gchar *text;
 
248
 
 
249
        text = gtk_entry_get_text(GTK_ENTRY(mixer_entry));
 
250
 
 
251
        if (!strcmp(settings.mixer, text) || (text[0] == '\0'))
 
252
                return FALSE;
 
253
        
 
254
        if (settings.mixer)
 
255
                g_free(settings.mixer);
 
256
 
 
257
        settings.mixer = g_strdup(text);
 
258
        
 
259
        start_mixer(TRUE, data);
 
260
        
 
261
        return FALSE;
 
262
}
 
263
 
 
264
/*static gboolean bitrate_combo_change_cb(GtkComboBox *combo, gpointer data)
 
265
{
 
266
        GList *bitrates;
 
267
        gint active;
 
268
        gchar *bitrate;
 
269
 
 
270
        g_assert(combo);
 
271
        bitrates = g_object_get_data(G_OBJECT(combo), "bitrates");
 
272
        active = gtk_combo_box_get_active(combo);
 
273
        g_assert(active > -1);
 
274
        
 
275
        bitrate = (gchar*)g_list_nth_data(bitrates, active);
 
276
        g_assert(bitrate);
 
277
 
 
278
        if (rec_settings.bitrate) g_free(rec_settings.bitrate);
 
279
        rec_settings.bitrate = g_strdup(bitrate);
 
280
        
 
281
        return FALSE;
 
282
}*/
 
283
 
 
284
/*static gboolean encoder_combo_change_cb(GtkComboBox *combo, gpointer bitrate_combo)
 
285
{
 
286
        GList *encoders;
 
287
        gint active;
 
288
        gchar *encoder;
 
289
        
 
290
        g_assert(combo);
 
291
        encoders = g_object_get_data(G_OBJECT(combo), "encoders");
 
292
        active = gtk_combo_box_get_active(combo);
 
293
        g_assert(active > -1);
 
294
        
 
295
        encoder = (gchar*)g_list_nth_data(encoders, active);
 
296
        g_assert(encoder);
 
297
 
 
298
        if (g_str_equal(encoder, _("Wave file"))) rec_settings.mp3 = FALSE;
 
299
        else {
 
300
                rec_settings.mp3 = TRUE;
 
301
                if (rec_settings.encoder) g_free(rec_settings.encoder);
 
302
                rec_settings.encoder = g_strdup(encoder);
 
303
        }
 
304
        gtk_widget_set_sensitive(bitrate_combo, rec_settings.mp3);
 
305
        
 
306
        return FALSE;
 
307
}*/
 
308
 
 
309
static void audio_profile_combo_change_cb(GtkWidget *widget, gpointer user_data)
 
310
{
 
311
        GtkTreeModel *model;
 
312
        GtkTreeIter iter;
 
313
        char *media_type = NULL;
 
314
        GstEncodingProfile *profile;
 
315
 
 
316
        model = gtk_combo_box_get_model(GTK_COMBO_BOX(widget));
 
317
        /* get selected media type */
 
318
        if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter) == FALSE)
 
319
                return;
 
320
        gtk_tree_model_get (GTK_TREE_MODEL (model),
 
321
                            &iter,
 
322
                            0, &media_type,
 
323
                            2, &profile,
 
324
                            -1);
 
325
 
 
326
        rec_settings.profile = g_strdup(media_type);
 
327
 
 
328
        /* indicate whether additional plugins are required to encode in this format */
 
329
        if (rb_gst_check_missing_plugins (profile, NULL, NULL)) {
 
330
                gtk_widget_set_visible (install_button, TRUE);
 
331
 
 
332
                gtk_widget_set_sensitive (install_button,
 
333
                                        gst_install_plugins_supported ());
 
334
        } else {
 
335
                gtk_widget_set_visible (install_button, FALSE);
 
336
        }
 
337
        g_free (media_type);
 
338
}
 
339
 
 
340
static void
 
341
audio_profile_chooser_set_active(GtkWidget *widget, const char *profile)
 
342
{
 
343
        GtkTreeIter iter;
 
344
        GtkTreeModel *model;
 
345
        gboolean done;
 
346
 
 
347
        done = FALSE;
 
348
        model = gtk_combo_box_get_model(GTK_COMBO_BOX(widget));
 
349
        if (gtk_tree_model_get_iter_first(model, &iter)) {
 
350
                do {
 
351
                        char *media_type;
 
352
 
 
353
                        gtk_tree_model_get(model, &iter, 0, &media_type, -1);
 
354
                        if (g_strcmp0(media_type, profile) == 0) {
 
355
                                gtk_combo_box_set_active_iter(GTK_COMBO_BOX(widget), &iter);
 
356
                                done = TRUE;
 
357
                        }
 
358
                        g_free (media_type);
 
359
                } while (done == FALSE && gtk_tree_model_iter_next(model, &iter));
 
360
        }
 
361
 
 
362
        if (done == FALSE) {
 
363
                gtk_combo_box_set_active_iter(GTK_COMBO_BOX(widget), NULL);
 
364
        }
 
365
}
 
366
 
 
367
static GtkWidget *audio_profile_choose_new(void)
 
368
{
 
369
        GstEncodingTarget *target;
 
370
        const GList *p;
 
371
        GtkWidget *combo;
 
372
        GtkCellRenderer *renderer;
 
373
        GtkTreeModel *model;
 
374
 
 
375
        model = GTK_TREE_MODEL(gtk_tree_store_new(3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER));
 
376
 
 
377
        target = rb_gst_get_default_encoding_target();
 
378
        for (p = gst_encoding_target_get_profiles(target); p != NULL; p = p->next) {
 
379
                GstEncodingProfile *profile = GST_ENCODING_PROFILE (p->data);
 
380
                char *media_type;
 
381
 
 
382
                media_type = rb_gst_encoding_profile_get_media_type(profile);
 
383
                if (media_type == NULL) {
 
384
                        continue;
 
385
                }
 
386
                gtk_tree_store_insert_with_values(GTK_TREE_STORE(model),
 
387
                                                  NULL, NULL, -1,
 
388
                                                  0, media_type,
 
389
                                                  1, gst_encoding_profile_get_description(profile),
 
390
                                                  2, profile, -1);
 
391
                g_free(media_type);
 
392
        }
 
393
 
 
394
        combo = gtk_combo_box_new_with_model(model);
 
395
        renderer = gtk_cell_renderer_text_new();
 
396
        gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo), renderer, TRUE);
 
397
        gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combo), renderer, "text", 1, NULL);
 
398
 
 
399
        return GTK_WIDGET(combo);
 
400
}
 
401
 
 
402
static void
 
403
audio_plugin_install_done_cb (gpointer inst, gboolean retry, gpointer user_data)
 
404
{
 
405
        audio_profile_combo_change_cb (audio_profile_combo, user_data);
 
406
}
 
407
 
 
408
static void
 
409
audio_profile_install_plugins_cb (GtkWidget *widget, gpointer user_data)
 
410
{
 
411
        GstEncodingProfile *profile;
 
412
        char **details;
 
413
        GClosure *closure;
 
414
 
 
415
        /* get profile */
 
416
        profile = rb_gst_get_encoding_profile (rec_settings.profile);
 
417
        if (profile == NULL) {
 
418
                g_free (rec_settings.profile);
 
419
                return;
 
420
        }
 
421
        g_free (rec_settings.profile);
 
422
 
 
423
        /* get plugin details */
 
424
        if (rb_gst_check_missing_plugins (profile, &details, NULL) == FALSE) {
 
425
                return;
 
426
        }
 
427
 
 
428
        /* attempt installation */
 
429
        closure = g_cclosure_new ((GCallback) audio_plugin_install_done_cb,
 
430
                                  g_object_ref (audio_profile_combo),
 
431
                                  (GClosureNotify) g_object_unref);
 
432
        g_closure_set_marshal (closure, g_cclosure_marshal_VOID__BOOLEAN);
 
433
 
 
434
        rb_missing_plugins_install ((const char **)details, TRUE, closure);
 
435
 
 
436
        g_closure_sink (closure);
 
437
        g_strfreev (details);
 
438
}
 
439
 
 
440
static void add_button_clicked_cb(GtkWidget *widget, gpointer data)
 
441
{
 
442
        preset *ps;
 
443
        gchar *buffer;
 
444
        GtkTreeIter iter = {0};
 
445
        GtkAdjustment* v_scb;
 
446
        GtkTreePath *path = NULL;
 
447
        GtkWidget *menuitem;
 
448
        
 
449
        ps = malloc(sizeof(preset));
 
450
        ps->title = g_strdup(_("unnamed"));
 
451
        ps->freq = rint(gtk_adjustment_get_value(adj)) / STEPS;
 
452
        settings.presets = g_list_append(settings.presets, (gpointer) ps);
 
453
        buffer = g_strdup_printf("%.2f", ps->freq);
 
454
 
 
455
        gtk_list_store_append(list_store, &iter);
 
456
        gtk_list_store_set(GTK_LIST_STORE(list_store), &iter, 0, ps->title, 1, buffer, -1);
 
457
 
 
458
        g_free(buffer);
 
459
        gtk_tree_selection_unselect_all(selection);
 
460
        
 
461
        v_scb = gtk_scrollable_get_vadjustment(GTK_SCROLLABLE(list_view));
 
462
        gtk_adjustment_set_value(v_scb, gtk_adjustment_get_upper(v_scb));
 
463
        
 
464
        if (main_visible) {
 
465
                gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(preset_combo), ps->title);
 
466
                mom_ps = g_list_length(settings.presets) - 1;
 
467
                preset_combo_set_item(mom_ps);
 
468
 
 
469
                menuitem = gtk_menu_item_new_with_label(ps->title); 
 
470
                        
 
471
                gtk_menu_shell_insert(GTK_MENU_SHELL(tray_menu), menuitem, mom_ps);             
 
472
                g_signal_connect(G_OBJECT(menuitem), "activate", (GCallback)preset_menuitem_activate_cb, GINT_TO_POINTER (mom_ps));
 
473
                gtk_widget_show(menuitem);
 
474
        }
 
475
 
 
476
        buffer = g_strdup_printf("%d", g_list_length(settings.presets) - 1);
 
477
        path = gtk_tree_path_new_from_string(buffer);
 
478
        g_free(buffer);
 
479
        gtk_tree_view_set_cursor(GTK_TREE_VIEW(list_view), path, NULL, FALSE);
 
480
        gtk_tree_path_free(path);
 
481
 
 
482
        gtk_widget_set_sensitive(save_button, TRUE);
 
483
}
 
484
 
 
485
static void remove_button_clicked_cb(GtkWidget *widget, gpointer data)
 
486
{
 
487
        GtkTreePath *path = NULL;
 
488
        GtkTreeViewColumn *focus_column = NULL;
 
489
        GtkTreeIter iter;
 
490
        preset *ps;
 
491
        int *row;
 
492
        GList* menuitems;
 
493
        GtkWidget *menuitem;
 
494
        
 
495
        gtk_tree_view_get_cursor(GTK_TREE_VIEW(list_view), &path, &focus_column);
 
496
        
 
497
        if (!path) return;
 
498
 
 
499
        row = gtk_tree_path_get_indices(path);
 
500
        g_assert(row);
 
501
        g_assert(*row < g_list_length(settings.presets));
 
502
 
 
503
        ps = g_list_nth_data(settings.presets, *row);
 
504
        g_assert(ps);   
 
505
        settings.presets = g_list_remove(settings.presets, (gpointer)ps);
 
506
        g_free(ps->title);
 
507
        g_free(ps);
 
508
        
 
509
        gtk_tree_model_get_iter(GTK_TREE_MODEL(list_store), &iter, path);
 
510
        gtk_list_store_remove(list_store, &iter);
 
511
 
 
512
        if (main_visible) {
 
513
                gtk_combo_box_text_remove(GTK_COMBO_BOX_TEXT(preset_combo), *row + 1);
 
514
                if (--mom_ps < 0) mom_ps = 0;
 
515
                if (settings.presets == NULL) mom_ps = -1;
 
516
                preset_combo_set_item(mom_ps);
 
517
 
 
518
                menuitems = gtk_container_get_children(GTK_CONTAINER(tray_menu));
 
519
                g_assert(*row < g_list_length(menuitems));
 
520
                menuitem = g_list_nth_data(menuitems, *row);
 
521
                gtk_widget_destroy(menuitem);
 
522
        }
 
523
        
 
524
        gtk_tree_path_prev(path);
 
525
        gtk_tree_view_set_cursor(GTK_TREE_VIEW(list_view), path, NULL, FALSE);
 
526
        gtk_tree_path_free(path);
 
527
 
 
528
        if (settings.presets == NULL) {
 
529
                gtk_widget_set_sensitive(save_button, FALSE);
 
530
        } else {
 
531
                gtk_widget_set_sensitive(save_button, TRUE);
 
532
        }
 
533
}
 
534
 
 
535
static void move_up_button_clicked_cb(GtkWidget * widget, gpointer data)
 
536
{
 
537
        GtkTreeIter iter, iter2;
 
538
        GtkTreePath *path, *path2;
 
539
        gint pos;
 
540
        preset *ps;
 
541
        int *row;
 
542
        GList* menuitems;
 
543
        GtkWidget *menuitem;
 
544
 
 
545
        selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(list_view));
 
546
        gtk_tree_selection_get_selected(selection, NULL, &iter);
 
547
        path = gtk_tree_model_get_path(GTK_TREE_MODEL(list_store), &iter);
 
548
 
 
549
        path2 = path;
 
550
        gtk_tree_path_prev(path2);
 
551
 
 
552
        if (gtk_tree_model_get_iter(GTK_TREE_MODEL(list_store), &iter2, path2)) {
 
553
                // we have a previous entry...
 
554
                gtk_list_store_swap(GTK_LIST_STORE(GTK_TREE_MODEL(list_store)), &iter, &iter2);
 
555
        }
 
556
 
 
557
        row = gtk_tree_path_get_indices(path);
 
558
        g_assert(row);
 
559
        g_assert(*row < g_list_length(settings.presets));
 
560
 
 
561
        ps = g_list_nth_data(settings.presets, *row);
 
562
        g_assert(ps);
 
563
        pos = g_list_index(settings.presets, (gpointer)ps);
 
564
        pos++;
 
565
 
 
566
        settings.presets = g_list_remove(settings.presets, (gpointer)ps);
 
567
        settings.presets = g_list_insert(settings.presets, (gpointer)ps, pos);
 
568
 
 
569
        if (main_visible) {
 
570
                gtk_combo_box_text_remove(GTK_COMBO_BOX_TEXT(preset_combo), *row + 1);
 
571
                gtk_combo_box_text_insert_text(GTK_COMBO_BOX_TEXT(preset_combo), *row + 2, ps->title);
 
572
                mom_ps = *row;
 
573
                preset_combo_set_item(mom_ps);
 
574
 
 
575
                menuitems = gtk_container_get_children(GTK_CONTAINER(tray_menu));
 
576
                g_assert(mom_ps < g_list_length(menuitems));
 
577
                menuitem = g_list_nth_data(menuitems, mom_ps);
 
578
                gtk_widget_destroy(menuitem);
 
579
                menuitem = gtk_menu_item_new_with_label(ps->title);
 
580
 
 
581
                gtk_menu_shell_insert(GTK_MENU_SHELL(tray_menu), menuitem, *row + 1);
 
582
                g_signal_connect(G_OBJECT(menuitem), "activate", (GCallback)preset_menuitem_activate_cb, GINT_TO_POINTER (mom_ps));
 
583
                gtk_widget_show(menuitem);
 
584
        }
 
585
 
 
586
        gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(list_view), path, NULL, FALSE, 0, 0);
 
587
        gtk_tree_path_free(path);
 
588
 
 
589
        if (pos - 1 <= 0) {
 
590
                gtk_widget_set_sensitive(move_up_button, FALSE);
 
591
        } else {
 
592
                gtk_widget_set_sensitive(move_up_button, TRUE);
 
593
        }
 
594
        gtk_widget_set_sensitive(move_down_button, TRUE);
 
595
}
 
596
 
 
597
static void move_down_button_clicked_cb(GtkWidget * widget, gpointer data)
 
598
{
 
599
        GtkTreeIter iter, iter2;
 
600
        GtkTreePath *path, *path2;
 
601
        gint pos, count;
 
602
        preset *ps;
 
603
        int *row;
 
604
        GList* menuitems;
 
605
        GtkWidget *menuitem;
 
606
 
 
607
        selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(list_view));
 
608
        gtk_tree_selection_get_selected(selection, NULL, &iter);
 
609
        path = gtk_tree_model_get_path(GTK_TREE_MODEL(list_store), &iter);
 
610
 
 
611
        path2 = path;
 
612
        gtk_tree_path_next(path2);
 
613
 
 
614
        if (gtk_tree_model_get_iter(GTK_TREE_MODEL(list_store), &iter2, path2)) {
 
615
                // we have a next entry...
 
616
                gtk_list_store_swap(GTK_LIST_STORE(GTK_TREE_MODEL(list_store)), &iter, &iter2);
 
617
        }
 
618
 
 
619
        row = gtk_tree_path_get_indices(path);
 
620
        g_assert(row);
 
621
        g_assert(*row < g_list_length(settings.presets));
 
622
 
 
623
        ps = g_list_nth_data(settings.presets, *row);
 
624
        g_assert(ps);
 
625
 
 
626
        count = g_list_length(settings.presets);
 
627
        pos = g_list_index(settings.presets, (gpointer)ps);
 
628
        pos--;
 
629
        if (pos == count)
 
630
                pos = 0;
 
631
 
 
632
        settings.presets = g_list_remove(settings.presets, (gpointer)ps);
 
633
        settings.presets = g_list_insert(settings.presets, (gpointer)ps, pos);
 
634
 
 
635
        if (main_visible) {
 
636
                gtk_combo_box_text_remove(GTK_COMBO_BOX_TEXT(preset_combo), *row + 1);
 
637
                gtk_combo_box_text_insert_text(GTK_COMBO_BOX_TEXT(preset_combo), *row, ps->title);
 
638
                mom_ps = *row;
 
639
                preset_combo_set_item(mom_ps);
 
640
 
 
641
                menuitems = gtk_container_get_children(GTK_CONTAINER(tray_menu));
 
642
                g_assert(mom_ps < g_list_length(menuitems));
 
643
                menuitem = g_list_nth_data(menuitems, mom_ps);
 
644
                gtk_widget_destroy(menuitem);
 
645
                menuitem = gtk_menu_item_new_with_label(ps->title);
 
646
 
 
647
                gtk_menu_shell_insert(GTK_MENU_SHELL(tray_menu), menuitem, *row - 1);
 
648
                g_signal_connect(G_OBJECT(menuitem), "activate", (GCallback)preset_menuitem_activate_cb, GINT_TO_POINTER (mom_ps));
 
649
                gtk_widget_show(menuitem);
 
650
        }
 
651
 
 
652
        gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(list_view), path, NULL, FALSE, 0, 0);
 
653
        gtk_tree_path_free(path);
 
654
 
 
655
        if (pos + 2 == gtk_tree_model_iter_n_children(GTK_TREE_MODEL(list_store), NULL)) {
 
656
                gtk_widget_set_sensitive(move_down_button, FALSE);
 
657
        } else {
 
658
                gtk_widget_set_sensitive(move_down_button, TRUE);
 
659
        }
 
660
        gtk_widget_set_sensitive(move_up_button, TRUE);
 
661
}
 
662
 
 
663
static void destination_button_clicked_cb(GtkWidget *button, gpointer data)
 
664
{
 
665
        if (rec_settings.destination)
 
666
        {
 
667
                g_free(rec_settings.destination);
 
668
        }
 
669
        rec_settings.destination = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(button));
 
670
}
 
671
 
 
672
static gboolean list_view_key_press_event_cb(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
 
673
{
 
674
        if (event->keyval == GDK_KEY_Delete)
 
675
                remove_button_clicked_cb(widget, user_data);
 
676
        if (event->keyval == GDK_KEY_Insert)
 
677
                add_button_clicked_cb(widget, user_data);
 
678
        
 
679
        return FALSE;
 
680
}               
 
681
 
 
682
static gboolean button_release_cb(GtkWidget *widget, GdkEvent *event, gpointer data)
 
683
{
 
684
        GtkTreePath *path;
 
685
        gint pos;
 
686
        GdkEventButton *event_button;
 
687
        gchar *buffer;
 
688
 
 
689
        event_button = (GdkEventButton *) event;
 
690
 
 
691
        gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(list_view), event_button->x, event_button->y, &path, NULL, NULL, NULL);
 
692
        if (path != NULL) {
 
693
                buffer = gtk_tree_path_to_string(path);
 
694
                pos = (gint) g_strtod(buffer, NULL);
 
695
                g_free(buffer);
 
696
                gtk_tree_path_free(path);
 
697
 
 
698
                if (pos == 0) {
 
699
                        gtk_widget_set_sensitive(move_up_button, FALSE);
 
700
                } else {
 
701
                        gtk_widget_set_sensitive(move_up_button, TRUE);
 
702
                }
 
703
 
 
704
                if (pos + 1 == gtk_tree_model_iter_n_children(GTK_TREE_MODEL(list_store), NULL)) {
 
705
                        gtk_widget_set_sensitive(move_down_button, FALSE);
 
706
                } else {
 
707
                        gtk_widget_set_sensitive(move_down_button, TRUE);
 
708
                }
 
709
        }
 
710
        return FALSE;
 
711
}
 
712
 
 
713
static void name_cell_edited_cb(GtkCellRendererText *cellrenderertext, gchar *path_str, gchar *new_val, gpointer user_data)
 
714
{
 
715
        GtkTreePath *path = NULL;
 
716
        GtkTreeIter iter;
 
717
        preset *ps;
 
718
        int *row;
 
719
        GList* menuitems;
 
720
        GtkWidget *menuitem;
 
721
        
 
722
        path = gtk_tree_path_new_from_string(path_str);
 
723
 
 
724
        row = gtk_tree_path_get_indices(path);
 
725
        g_assert(row);
 
726
        g_assert(*row < g_list_length(settings.presets));
 
727
 
 
728
        ps = g_list_nth_data(settings.presets, *row);
 
729
        g_assert(ps);   
 
730
        if (ps->title) g_free(ps->title);
 
731
        ps->title = g_strdup(new_val);
 
732
 
 
733
        if (main_visible) {
 
734
                gtk_combo_box_text_remove(GTK_COMBO_BOX_TEXT(preset_combo), *row + 1);
 
735
                gtk_combo_box_text_insert_text(GTK_COMBO_BOX_TEXT(preset_combo), *row + 1, ps->title);
 
736
                mom_ps = *row;
 
737
                preset_combo_set_item(mom_ps);
 
738
 
 
739
                menuitems = gtk_container_get_children(GTK_CONTAINER(tray_menu));
 
740
                g_assert(mom_ps < g_list_length(menuitems));
 
741
                menuitem = g_list_nth_data(menuitems, mom_ps);
 
742
                gtk_widget_destroy(menuitem);
 
743
                menuitem = gtk_menu_item_new_with_label(ps->title); 
 
744
                        
 
745
                gtk_menu_shell_insert(GTK_MENU_SHELL(tray_menu), menuitem, *row);               
 
746
                g_signal_connect(G_OBJECT(menuitem), "activate", (GCallback)preset_menuitem_activate_cb, GINT_TO_POINTER (mom_ps));
 
747
                gtk_widget_show(menuitem);
 
748
        }
 
749
        
 
750
        gtk_tree_model_get_iter(GTK_TREE_MODEL(list_store), &iter, path);
 
751
        gtk_list_store_set(GTK_LIST_STORE(list_store), &iter, 0, new_val, -1);
 
752
        gtk_tree_path_free(path);       
 
753
}       
 
754
 
 
755
static void freq_cell_edited_cb(GtkCellRendererText *cellrenderertext, gchar *path_str, gchar *new_val, gpointer user_data)
 
756
{
 
757
        GtkTreePath *path = NULL;
 
758
        GtkTreeIter iter;
 
759
        preset *ps;
 
760
        int *row;
 
761
        double value;
 
762
        gchar *freq_str;
 
763
        
 
764
        if (sscanf(new_val, "%lf", &value) != 1) return;
 
765
        
 
766
        if (value < FREQ_MIN) value = FREQ_MIN;
 
767
        if (value > FREQ_MAX) value = FREQ_MAX;
 
768
        value = rint(value * STEPS) / STEPS;
 
769
        
 
770
        freq_str = g_strdup_printf("%.2f", value);
 
771
        
 
772
        path = gtk_tree_path_new_from_string(path_str);
 
773
        
 
774
        row = gtk_tree_path_get_indices(path);
 
775
        g_assert(row);
 
776
        g_assert(*row < g_list_length(settings.presets));
 
777
 
 
778
        ps = g_list_nth_data(settings.presets, *row);
 
779
        g_assert(ps);   
 
780
        ps->freq = value;
 
781
 
 
782
        gtk_adjustment_set_value(adj, value * STEPS);
 
783
        mom_ps = *row;
 
784
        preset_combo_set_item(mom_ps);
 
785
        
 
786
        gtk_tree_model_get_iter(GTK_TREE_MODEL(list_store), &iter, path);
 
787
        gtk_list_store_set(GTK_LIST_STORE(list_store), &iter, 1, freq_str, -1);
 
788
        g_free(freq_str);
 
789
        gtk_tree_path_free(path);       
 
790
}       
 
791
 
 
792
static void list_view_cursor_changed_cb(GtkWidget *widget, gpointer data)
 
793
{
 
794
        int *row;
 
795
        preset *ps;
 
796
        gint pos;
 
797
        GtkTreePath *path = NULL;
 
798
        GtkTreeViewColumn *focus_column = NULL;
 
799
        
 
800
        if (settings.presets == NULL)
 
801
                return;
 
802
 
 
803
        gtk_tree_view_get_cursor(GTK_TREE_VIEW(list_view), &path, &focus_column);
 
804
        
 
805
        if (!path)
 
806
                return;
 
807
 
 
808
        row = gtk_tree_path_get_indices(path);
 
809
        g_assert(row);
 
810
 
 
811
        mom_ps = *row;
 
812
        preset_combo_set_item(mom_ps);
 
813
 
 
814
        ps = g_list_nth_data(settings.presets, *row);
 
815
        g_assert(ps);
 
816
 
 
817
        pos = g_list_index(settings.presets, (gpointer)ps);
 
818
 
 
819
        if (pos == 0) {
 
820
                gtk_widget_set_sensitive(move_up_button, FALSE);
 
821
        } else {
 
822
                gtk_widget_set_sensitive(move_up_button, TRUE);
 
823
        }
 
824
 
 
825
        if (pos + 1 == gtk_tree_model_iter_n_children(GTK_TREE_MODEL(list_store), NULL)) {
 
826
                        gtk_widget_set_sensitive(move_down_button, FALSE);
 
827
        } else {
 
828
                        gtk_widget_set_sensitive(move_down_button, TRUE);
 
829
        }
 
830
        gtk_tree_path_free(path);
 
831
        return;
 
832
}
 
833
 
 
834
static void list_view_selection_changed_cb(GtkWidget *widget, gpointer data)
 
835
{
 
836
        gboolean sel;
 
837
 
 
838
        sel = gtk_tree_selection_get_selected(selection, NULL, NULL);
 
839
 
 
840
        gtk_widget_set_sensitive(remove_button, sel);
 
841
        gtk_widget_set_sensitive(save_button, sel);
 
842
}
 
843
 
 
844
static void list_view_scroll_to_active_preset_cb(GtkWidget *widget, gpointer data)
 
845
{
 
846
        GtkTreePath *path = NULL;
 
847
        GtkTreeIter iter;
 
848
        gint active;
 
849
 
 
850
        if (settings.presets == NULL) {
 
851
                gtk_widget_grab_focus(add_button);
 
852
                return;
 
853
        }
 
854
 
 
855
        active = gtk_combo_box_get_active(GTK_COMBO_BOX(preset_combo)) - 1;
 
856
 
 
857
        if (active < 0) {
 
858
                gtk_widget_grab_focus(add_button);
 
859
                return;
 
860
        }
 
861
 
 
862
        if (!gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(list_store), &iter, NULL, active))
 
863
                return;
 
864
 
 
865
        path = gtk_tree_model_get_path(GTK_TREE_MODEL(list_store), &iter);
 
866
 
 
867
        gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW (list_view), path, NULL, FALSE, 0, 0);
 
868
        gtk_tree_view_set_cursor(GTK_TREE_VIEW (list_view), path, NULL, FALSE );
 
869
        gtk_tree_path_free(path);
 
870
 
 
871
        gtk_widget_grab_focus(list_view);
 
872
}
 
873
 
 
874
static void free_presets_list (gpointer data)
 
875
{
 
876
        preset *ps = (preset *) data;
 
877
        g_free (ps->title);
 
878
        g_free (ps);
 
879
}
 
880
 
 
881
/* Go through each row and add its data to the xmlDocPtr */
 
882
static gboolean save_to_file_foreach(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, xmlNodePtr root, gpointer user_data)
 
883
{
 
884
        gchar *title, *freq, *position;
 
885
        xmlNodePtr current;
 
886
 
 
887
        /* get the data stored in the model... */
 
888
        gtk_tree_model_get(model, iter, 0, &title, 1, &freq, -1);
 
889
        /* ...and get the path of the current row */
 
890
        position = gtk_tree_path_to_string(path);
 
891
        /* create a new child of the root node... */
 
892
        /* (note that I'm using a (guchar*) cast; this is because it's the same thing as
 
893
         * an (xmlChar*) cast, but easier to type) */
 
894
        current = xmlNewChild(root, NULL, (guchar*)"station", NULL);
 
895
        /* ...and set some properties */
 
896
        xmlSetProp(current, (guchar*)"name", (guchar*)title);
 
897
        xmlSetProp(current, (guchar*)"freq", (guchar*)freq);
 
898
        xmlSetProp(current, (guchar*)"position", (guchar*)position);
 
899
        /* free our data we retrieved from the model */
 
900
        g_free(title);
 
901
        g_free(freq);
 
902
        g_free(position);
 
903
 
 
904
        /* return FALSE to keep iterating */
 
905
        return FALSE;
 
906
}
 
907
 
 
908
/* Function handle saving an xml file; calls save_to_file_foreach */
 
909
static void save_to_file(gchar *filename)
 
910
{
 
911
        GtkTreeModel *model;
 
912
        xmlDocPtr doc;
 
913
        xmlNodePtr root;
 
914
 
 
915
        /* create a new doc node */
 
916
        doc = xmlNewDoc((guchar*)"1.0");
 
917
        /* create a new root element. */
 
918
        root = xmlNewDocNode(doc, NULL, (guchar*)"gnomeradio", NULL);
 
919
        /* set it as the root element */
 
920
        xmlDocSetRootElement(doc, root);
 
921
        /* get the tree view's model... */
 
922
        model = gtk_tree_view_get_model(GTK_TREE_VIEW(list_view));
 
923
        /* ...and go through it with a foreach */
 
924
        gtk_tree_model_foreach(model, (GtkTreeModelForeachFunc)save_to_file_foreach, (gpointer)root);
 
925
        /* save the actual file */
 
926
        xmlSaveFile(filename, doc);
 
927
        /* free the doc node */
 
928
        xmlFreeDoc(doc);
 
929
}
 
930
 
 
931
/* Callback for the "Save to file" button; calls save_to_file */
 
932
static void save_to_file_cb(GtkWidget *button, gpointer data)
 
933
{
 
934
        GtkWidget *dialog;
 
935
        GtkFileFilter *file_filter_all;
 
936
        GtkFileFilter *file_filter_xml;
 
937
        gchar *filename;
 
938
 
 
939
        dialog = gtk_file_chooser_dialog_new (_("Select file name\xE2\x80\xA6"), NULL,
 
940
                                              GTK_FILE_CHOOSER_ACTION_SAVE,
 
941
                                              _("_Save"), GTK_RESPONSE_ACCEPT,
 
942
                                              _("_Cancel"), GTK_RESPONSE_CANCEL,
 
943
                                              NULL);
 
944
 
 
945
        file_filter_all = gtk_file_filter_new();
 
946
        gtk_file_filter_set_name(file_filter_all, _("All Files"));
 
947
        gtk_file_filter_add_pattern(file_filter_all, "*");
 
948
        gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), file_filter_all);
 
949
 
 
950
        file_filter_xml = gtk_file_filter_new();
 
951
        gtk_file_filter_set_name(file_filter_xml, _("XML Files (*.xml)"));
 
952
        gtk_file_filter_add_pattern(file_filter_xml, "*.xml");
 
953
        gtk_file_filter_add_pattern(file_filter_xml, "*.XML");
 
954
        gtk_file_filter_add_mime_type(file_filter_xml, "text/xml");
 
955
        gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), file_filter_xml);
 
956
 
 
957
        gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), TRUE);
 
958
        gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(dialog), file_filter_xml);
 
959
        gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), "gnomeradio.xml");
 
960
 
 
961
        if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
 
962
                filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
 
963
                /* Check if .xml extension is added, if not add */
 
964
                if (!g_str_has_suffix(filename, ".xml")) {
 
965
                        char *tmp_file;
 
966
                        /* create copy of filename to release it and create a new one, using old name */
 
967
                        tmp_file = g_strdup(filename);
 
968
                        g_free(filename);
 
969
                        filename = g_strdup_printf("%s.xml", tmp_file);
 
970
                        g_free(tmp_file);
 
971
                }
 
972
                save_to_file(filename);
 
973
                g_free(filename);
 
974
        }
 
975
        gtk_widget_destroy(dialog);
 
976
}
 
977
 
 
978
/* Gets the parent of a path string.
 
979
* passing "0:1:2" would return "0:1",
 
980
* passing "0:1" would return "0",
 
981
* passing "0" would return NULL */
 
982
gchar *gtk_tree_path_string_get_parent(gchar *path)
 
983
{
 
984
        gchar *colon;
 
985
 
 
986
        g_return_val_if_fail(path != NULL, NULL);
 
987
 
 
988
        colon = g_strrstr(path, ":");
 
989
        if (colon == NULL)
 
990
                  return NULL;
 
991
 
 
992
        return g_strndup(path, colon - path);
 
993
}
 
994
 
 
995
/* Make sure that path exists within model */
 
996
static void gtk_tree_model_generate_path(GtkTreeModel *model, gchar *path)
 
997
{
 
998
        GtkTreeIter iter, parent;
 
999
        gchar *temp;
 
1000
 
 
1001
        while (TRUE) {
 
1002
                /* if this returns TRUE, then this path exists and we're fine */
 
1003
                if (gtk_tree_model_get_iter_from_string(model, &iter, path))
 
1004
                        break;
 
1005
 
 
1006
                temp = path;
 
1007
                path = gtk_tree_path_string_get_parent(path);
 
1008
                /* if there's no parent, then it's toplevel */
 
1009
                if (path == NULL) {
 
1010
                        if (GTK_IS_TREE_STORE(model))
 
1011
                                gtk_tree_store_append(GTK_TREE_STORE(model), &parent, NULL);
 
1012
                        else
 
1013
                                gtk_list_store_append(GTK_LIST_STORE(model), &parent);
 
1014
                                gtk_tree_model_generate_path(model, temp);
 
1015
                                break;
 
1016
                }
 
1017
                if (GTK_IS_TREE_STORE(model)) {
 
1018
                        gtk_tree_model_generate_path(model, path);
 
1019
                        gtk_tree_model_get_iter_from_string(model, &parent, path);
 
1020
                        gtk_tree_store_append(GTK_TREE_STORE(model), &iter, &parent);
 
1021
                }
 
1022
        }
 
1023
}
 
1024
 
 
1025
/* Function to load from an xml file */
 
1026
static void load_from_file(gchar *filename)
 
1027
{
 
1028
        xmlDocPtr doc;
 
1029
        xmlNodePtr current;
 
1030
        xmlChar *title, *freq, *position;
 
1031
        GtkTreeModel *model;
 
1032
        GtkTreePath *path = NULL;
 
1033
        GtkTreeIter iter;
 
1034
        GtkAdjustment* v_scb;
 
1035
        GList* menuitems;
 
1036
        GtkWidget *menuitem;
 
1037
 
 
1038
        /* load the file */
 
1039
        doc = xmlParseFile(filename);
 
1040
        /* get the root item */
 
1041
        if (doc == NULL)
 
1042
                return;
 
1043
 
 
1044
        current = xmlDocGetRootElement(doc);
 
1045
        if (current == NULL) {
 
1046
                xmlFreeDoc(doc);
 
1047
                return;
 
1048
        }
 
1049
 
 
1050
        if (xmlStrcmp(current->name, (guchar*)"gnomeradio")) {
 
1051
                xmlFreeDoc(doc);
 
1052
                return;
 
1053
        }
 
1054
 
 
1055
        /* remove previous presets */
 
1056
        if (settings.presets != NULL) {
 
1057
                if (main_visible) {
 
1058
                        gint i, count;
 
1059
 
 
1060
                        count = g_list_length (settings.presets);
 
1061
                        for (i = 0; i < count; i++)
 
1062
                                gtk_combo_box_text_remove(GTK_COMBO_BOX_TEXT(preset_combo), 1);
 
1063
 
 
1064
                        menuitems = gtk_container_get_children (GTK_CONTAINER (tray_menu));
 
1065
 
 
1066
                        count = g_list_length (menuitems);
 
1067
                        for (i = 0; i < count - 6; i++) {
 
1068
                                menuitem = g_list_nth_data (menuitems, i);
 
1069
                                gtk_widget_destroy (menuitem);
 
1070
                        }
 
1071
                }
 
1072
 
 
1073
                gtk_list_store_clear(GTK_LIST_STORE(list_store));
 
1074
 
 
1075
                g_list_free_full (settings.presets, free_presets_list);
 
1076
                settings.presets = NULL;
 
1077
        }
 
1078
 
 
1079
        /* get the tree view's model */
 
1080
        model = gtk_tree_view_get_model(GTK_TREE_VIEW(list_view));
 
1081
 
 
1082
        /* iterate through the root's children items */
 
1083
        current = current->xmlChildrenNode;
 
1084
        while (current) {
 
1085
                if(!xmlIsBlankNode(current)) {
 
1086
                        /* check for the proper element name */
 
1087
                        if (!xmlStrcmp(current->name, (guchar*)"station")) {
 
1088
                                /* get the saved properties */
 
1089
                                title = xmlGetProp(current, (guchar*)"name");
 
1090
                                freq = xmlGetProp(current, (guchar*)"freq");
 
1091
                                position = xmlGetProp(current, (guchar*)"position");
 
1092
 
 
1093
                                if( title && freq && position ) {
 
1094
                                        preset *ps = g_malloc0(sizeof(preset));
 
1095
                                        ps->title = g_strdup((gchar*)title);
 
1096
                                        ps->freq = atof((gchar*)freq);
 
1097
 
 
1098
                                        settings.presets = g_list_append(settings.presets, ps);
 
1099
 
 
1100
                                        /* make sure that the path exists */
 
1101
                                        gtk_tree_model_generate_path(model, (gchar*)position);
 
1102
                                        /* get an iter to the path */
 
1103
                                        gtk_tree_model_get_iter_from_string(model, &iter, (gchar*)position);
 
1104
                                        /* set the data */
 
1105
                                        gtk_list_store_set(GTK_LIST_STORE(list_store), &iter, 0, title, 1, freq, -1);
 
1106
 
 
1107
                                        gtk_tree_selection_unselect_all(selection);
 
1108
 
 
1109
                                        v_scb = gtk_scrollable_get_vadjustment(GTK_SCROLLABLE(list_view));
 
1110
                                        gtk_adjustment_set_value(v_scb, gtk_adjustment_get_upper(v_scb));
 
1111
 
 
1112
                                        if (main_visible) {
 
1113
                                                gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(preset_combo), title);
 
1114
                                                mom_ps = g_list_length(settings.presets) - 1;
 
1115
                                                preset_combo_set_item(mom_ps);
 
1116
 
 
1117
                                                menuitem = gtk_menu_item_new_with_label(title);
 
1118
 
 
1119
                                                gtk_menu_shell_insert(GTK_MENU_SHELL(tray_menu), menuitem, mom_ps);
 
1120
                                                g_signal_connect(G_OBJECT(menuitem), "activate",
 
1121
                                                                 (GCallback)preset_menuitem_activate_cb,
 
1122
                                                                 GINT_TO_POINTER (mom_ps));
 
1123
                                                gtk_widget_show(menuitem);
 
1124
                                        }
 
1125
                                }
 
1126
                                /* free the data */
 
1127
                                xmlFree(title);
 
1128
                                xmlFree(freq);
 
1129
                                xmlFree(position);
 
1130
                        }
 
1131
                        current = current->next;
 
1132
                }
 
1133
        }
 
1134
        /* free the doc node */
 
1135
        xmlFreeDoc(doc);
 
1136
 
 
1137
        if (settings.presets == NULL)
 
1138
                return;
 
1139
 
 
1140
        path = gtk_tree_model_get_path(GTK_TREE_MODEL(list_store), &iter);
 
1141
 
 
1142
        gtk_tree_view_set_cursor(GTK_TREE_VIEW (list_view), path, NULL, FALSE );
 
1143
        gtk_tree_path_free(path);
 
1144
 
 
1145
        gtk_widget_grab_focus(list_view);
 
1146
 
 
1147
        list_view_cursor_changed_cb(list_view, NULL);
 
1148
        gtk_widget_set_sensitive(save_button, TRUE);
 
1149
        gtk_widget_set_sensitive(remove_button, TRUE);
 
1150
}
 
1151
 
 
1152
/* Callback for the "Load from file" button; calls load_from_file */
 
1153
static void load_from_file_cb(GtkWidget *button, gpointer data)
 
1154
{
 
1155
        GtkWidget *dialog;
 
1156
        GtkFileFilter *file_filter_all;
 
1157
        GtkFileFilter *file_filter_xml;
 
1158
        gchar *filename;
 
1159
 
 
1160
        dialog = gtk_file_chooser_dialog_new (_("Select file name\xE2\x80\xA6"), NULL,
 
1161
                                              GTK_FILE_CHOOSER_ACTION_OPEN,
 
1162
                                              _("_Open"), GTK_RESPONSE_ACCEPT,
 
1163
                                              _("_Cancel"), GTK_RESPONSE_CANCEL,
 
1164
                                              NULL);
 
1165
 
 
1166
        file_filter_all = gtk_file_filter_new();
 
1167
        gtk_file_filter_set_name(file_filter_all, _("All Files"));
 
1168
        gtk_file_filter_add_pattern(file_filter_all, "*");
 
1169
        gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), file_filter_all);
 
1170
 
 
1171
        file_filter_xml = gtk_file_filter_new();
 
1172
        gtk_file_filter_set_name(file_filter_xml, _("XML Files"));
 
1173
        gtk_file_filter_add_pattern(file_filter_xml, "*.xml");
 
1174
        gtk_file_filter_add_pattern(file_filter_xml, "*.XML");
 
1175
        gtk_file_filter_add_mime_type(file_filter_xml, "text/xml");
 
1176
        gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(dialog), file_filter_xml);
 
1177
 
 
1178
        gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(dialog), file_filter_xml);
 
1179
 
 
1180
        if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
 
1181
                filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
 
1182
                load_from_file(filename);
 
1183
                g_free(filename);
 
1184
        }
 
1185
        gtk_widget_destroy(dialog);
 
1186
}
 
1187
 
 
1188
gboolean action_mode (gint mode)
 
1189
{
 
1190
        switch (mode) {
 
1191
                case RADIO_DEVICE:
 
1192
                        gtk_widget_grab_focus (device_entry);
 
1193
                        break;
 
1194
                case MIXER_DEVICE:
 
1195
                        gtk_widget_grab_focus (mixer_entry);
 
1196
                        break;
 
1197
                case PRESETS:
 
1198
                        list_view_scroll_to_active_preset_cb(list_view, NULL);
 
1199
                        break;
 
1200
                default:
 
1201
                        break;
 
1202
        }
 
1203
 
 
1204
        return TRUE;
 
1205
}
 
1206
 
 
1207
GtkWidget* prefs_window(GtkWidget *app)
 
1208
{
 
1209
        GtkWidget *dialog;
 
1210
        GtkWidget *content_area;
 
1211
        GtkWidget *box;
 
1212
        GtkWidget *grid;
 
1213
        GtkWidget *label;
 
1214
        GtkWidget *scrolled_window;
 
1215
        GtkCellRenderer *cellrenderer;
 
1216
        GtkTreeViewColumn *list_column;
 
1217
        GtkWidget *button_box;
 
1218
        GtkWidget *open_button;
 
1219
        GtkWidget *destination_button;
 
1220
        GtkWidget *image;
 
1221
 
 
1222
        GstEncodingProfile *profile;
 
1223
 
 
1224
        gint i;
 
1225
        gchar *markup;
 
1226
        preset* ps;
 
1227
        GList *l;
 
1228
        
 
1229
        dialog = gtk_dialog_new_with_buttons (_("Gnomeradio Settings"), GTK_WINDOW (app),
 
1230
                                              GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
 
1231
                                              _("_Close"), GTK_RESPONSE_CLOSE,
 
1232
                                              _("_Help"), GTK_RESPONSE_HELP,
 
1233
                                              NULL);
 
1234
        
 
1235
        gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE);
 
1236
        gtk_dialog_set_default_response(GTK_DIALOG(dialog), GTK_RESPONSE_CLOSE);
 
1237
 
 
1238
        content_area = gtk_dialog_get_content_area (GTK_DIALOG(dialog));
 
1239
 
 
1240
        box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 15);
 
1241
        gtk_container_set_border_width(GTK_CONTAINER(box), 10);
 
1242
        gtk_box_pack_start (GTK_BOX (content_area), box, TRUE, TRUE, 0);
 
1243
        
 
1244
        grid = gtk_grid_new();
 
1245
        gtk_grid_set_row_spacing(GTK_GRID(grid), 5);
 
1246
        gtk_grid_set_column_spacing(GTK_GRID(grid), 20);
 
1247
        gtk_box_pack_start(GTK_BOX(box), grid, TRUE, TRUE, 0);
 
1248
 
 
1249
        /* The general settings part */
 
1250
        label = gtk_label_new (NULL);
 
1251
        gtk_widget_set_halign (label, GTK_ALIGN_START);
 
1252
        markup = g_strdup_printf ("<span weight=\"bold\">%s</span>", _("General Settings"));
 
1253
        gtk_label_set_markup (GTK_LABEL (label), markup);
 
1254
        g_free (markup);
 
1255
        gtk_grid_attach(GTK_GRID(grid), label, 0, 0, 2, 1);
 
1256
 
 
1257
        label = gtk_label_new ("");
 
1258
        gtk_grid_attach (GTK_GRID (grid), label, 0, 1, 1, 3);
 
1259
 
 
1260
        label = gtk_label_new (_("Radio Device:"));
 
1261
        gtk_widget_set_halign (label, GTK_ALIGN_START);
 
1262
        gtk_grid_attach (GTK_GRID (grid), label, 1, 1, 1, 1);
 
1263
 
 
1264
        device_entry = gtk_entry_new();
 
1265
        if (autodetect)
 
1266
                gtk_entry_set_placeholder_text(GTK_ENTRY(device_entry), "auto");
 
1267
        else
 
1268
                gtk_entry_set_text(GTK_ENTRY(device_entry), settings.device);
 
1269
        gtk_grid_attach(GTK_GRID(grid), device_entry, 2, 1, 1, 1);
 
1270
 
 
1271
        label = gtk_label_new (_("Mixer Source:"));
 
1272
        gtk_widget_set_halign (label, GTK_ALIGN_START);
 
1273
        gtk_grid_attach (GTK_GRID (grid), label, 1, 2, 1, 1);
 
1274
 
 
1275
        mixer_entry = gtk_entry_new();
 
1276
        gtk_entry_set_text(GTK_ENTRY(mixer_entry), settings.mixer);
 
1277
        gtk_grid_attach(GTK_GRID(grid), mixer_entry, 2, 2, 1, 1);
 
1278
 
 
1279
        mute_on_exit_cb = gtk_check_button_new_with_label(_("Mute on exit"));
 
1280
        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(mute_on_exit_cb), settings.mute_on_exit);
 
1281
 
 
1282
        gtk_grid_attach(GTK_GRID(grid), mute_on_exit_cb, 1, 3, 1, 1);
 
1283
 
 
1284
        g_signal_connect(G_OBJECT(device_entry), "hide", G_CALLBACK(device_entry_activate_cb), app);
 
1285
        g_signal_connect(G_OBJECT(device_entry), "activate", G_CALLBACK(device_entry_activate_cb), NULL);
 
1286
        g_signal_connect(G_OBJECT(device_entry), "changed", G_CALLBACK(device_entry_auto_activate_cb), NULL);
 
1287
        g_signal_connect(G_OBJECT(mixer_entry), "hide", G_CALLBACK(mixer_entry_activate_cb), app);
 
1288
        g_signal_connect(G_OBJECT(mixer_entry), "activate", G_CALLBACK(mixer_entry_activate_cb), NULL);
 
1289
        g_signal_connect(G_OBJECT(mute_on_exit_cb), "toggled", G_CALLBACK(mute_on_exit_toggled_cb), NULL);
 
1290
 
 
1291
        gtk_widget_set_tooltip_text(device_entry, _("The radio device to use (e.g. /dev/radio0)"));
 
1292
        gtk_widget_set_tooltip_text(mixer_entry, _("The mixer device and channel to use (e.g. hw:0/Line)"));
 
1293
        gtk_widget_set_tooltip_text(mute_on_exit_cb, _("Mute mixer device on exit"));
 
1294
 
 
1295
        /* The presets part */
 
1296
        label = gtk_label_new (NULL);
 
1297
        gtk_widget_set_halign (label, GTK_ALIGN_START);
 
1298
        markup = g_strdup_printf ("<span weight=\"bold\">%s</span>", _("Presets"));
 
1299
        gtk_label_set_markup (GTK_LABEL (label), markup);
 
1300
        g_free (markup);
 
1301
        gtk_grid_attach(GTK_GRID(grid), label, 0, 4, 2, 1);
 
1302
 
 
1303
        label = gtk_label_new ("");
 
1304
        gtk_grid_attach (GTK_GRID (grid), label, 0, 5, 1, 2);
 
1305
 
 
1306
        scrolled_window = gtk_scrolled_window_new(NULL, NULL);
 
1307
        gtk_scrolled_window_set_min_content_height(GTK_SCROLLED_WINDOW(scrolled_window), 75);
 
1308
        gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled_window), GTK_SHADOW_IN);
 
1309
        gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
 
1310
 
 
1311
        list_store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING);
 
1312
        list_view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(list_store));
 
1313
        gtk_tree_view_set_rules_hint (GTK_TREE_VIEW(list_view), TRUE);
 
1314
        gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(list_view), FALSE);
 
1315
 
 
1316
        selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(list_view));
 
1317
        gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
 
1318
        gtk_container_add(GTK_CONTAINER(scrolled_window), list_view);
 
1319
 
 
1320
        g_signal_connect(G_OBJECT(list_view), "button-release-event", G_CALLBACK(button_release_cb), NULL);
 
1321
        g_signal_connect(G_OBJECT(list_view), "key-press-event", G_CALLBACK(list_view_key_press_event_cb), NULL);
 
1322
        g_signal_connect(G_OBJECT(list_view), "cursor-changed", G_CALLBACK(list_view_cursor_changed_cb), NULL);
 
1323
 
 
1324
        g_signal_connect(G_OBJECT(selection), "changed", G_CALLBACK(list_view_selection_changed_cb), list_view);
 
1325
 
 
1326
        /*gtk_tree_selection_select_path(selection, gtk_tree_path_new_from_string("0"));
 
1327
        gtk_tree_selection_set_select_function(selection, (GtkTreeSelectionFunc)list_view_select_cb, NULL, NULL);*/
 
1328
        
 
1329
        cellrenderer = gtk_cell_renderer_text_new();
 
1330
        g_object_set(G_OBJECT(cellrenderer), "mode", GTK_CELL_RENDERER_MODE_EDITABLE, NULL);
 
1331
        g_object_set(G_OBJECT(GTK_CELL_RENDERER_TEXT(cellrenderer)), "editable", TRUE, NULL);
 
1332
        list_column = gtk_tree_view_column_new_with_attributes(NULL, cellrenderer, "text", 0, NULL);
 
1333
        gtk_tree_view_column_set_reorderable(list_column, TRUE);
 
1334
        gtk_tree_view_column_set_expand(list_column, TRUE);
 
1335
        gtk_tree_view_append_column(GTK_TREE_VIEW(list_view), list_column);
 
1336
 
 
1337
        g_signal_connect(G_OBJECT(cellrenderer), "edited", G_CALLBACK(name_cell_edited_cb), NULL);
 
1338
 
 
1339
        cellrenderer = gtk_cell_renderer_text_new();
 
1340
        g_object_set(G_OBJECT(cellrenderer), "mode", GTK_CELL_RENDERER_MODE_EDITABLE, NULL);
 
1341
        g_object_set(G_OBJECT(cellrenderer), "xalign", 1.0, NULL);
 
1342
        g_object_set(G_OBJECT(GTK_CELL_RENDERER_TEXT(cellrenderer)), "editable", TRUE, NULL);
 
1343
        list_column = gtk_tree_view_column_new_with_attributes(NULL, cellrenderer, "text", 1, NULL);
 
1344
        gtk_tree_view_column_set_reorderable(list_column, TRUE);
 
1345
        gtk_tree_view_column_set_expand(list_column, FALSE);
 
1346
        gtk_tree_view_append_column(GTK_TREE_VIEW(list_view), list_column);
 
1347
 
 
1348
        g_signal_connect(G_OBJECT(cellrenderer), "edited", G_CALLBACK(freq_cell_edited_cb), NULL);
 
1349
 
 
1350
        i = 0;
 
1351
        for (l = settings.presets; l != NULL; l = l->next) {
 
1352
                GtkTreeIter iter = {0};
 
1353
                char *buffer;
 
1354
                ps = l->data;
 
1355
                buffer = g_strdup_printf("%0.2f", ps->freq);
 
1356
                gtk_list_store_append(list_store, &iter);
 
1357
                gtk_list_store_set(GTK_LIST_STORE(list_store), &iter, 0, ps->title, 1, buffer, -1);
 
1358
                g_free(buffer);
 
1359
                i++;
 
1360
        }
 
1361
 
 
1362
        gtk_grid_attach(GTK_GRID(grid), scrolled_window, 1, 5, 2, 2);
 
1363
 
 
1364
        button_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
 
1365
 
 
1366
        move_up_button = gtk_button_new();
 
1367
        image = gtk_image_new_from_icon_name ("go-up", GTK_ICON_SIZE_MENU);
 
1368
        gtk_button_set_image (GTK_BUTTON (move_up_button), image);
 
1369
        gtk_button_set_relief (GTK_BUTTON (move_up_button), GTK_RELIEF_NONE);
 
1370
        gtk_widget_set_sensitive(move_up_button, FALSE);
 
1371
        gtk_widget_set_tooltip_text(move_up_button, _("Move preset up"));
 
1372
 
 
1373
        g_signal_connect(G_OBJECT(move_up_button), "clicked", G_CALLBACK(move_up_button_clicked_cb), NULL);
 
1374
 
 
1375
        move_down_button = gtk_button_new();
 
1376
        image = gtk_image_new_from_icon_name ("go-down", GTK_ICON_SIZE_MENU);
 
1377
        gtk_button_set_image (GTK_BUTTON (move_down_button), image);
 
1378
        gtk_button_set_relief (GTK_BUTTON (move_down_button), GTK_RELIEF_NONE);
 
1379
        gtk_widget_set_sensitive(move_down_button, FALSE);
 
1380
        gtk_widget_set_tooltip_text(move_down_button, _("Move preset down"));
 
1381
 
 
1382
        g_signal_connect(G_OBJECT(move_down_button), "clicked", G_CALLBACK(move_down_button_clicked_cb), NULL);
 
1383
 
 
1384
        add_button = gtk_button_new();
 
1385
        image = gtk_image_new_from_icon_name ("list-add", GTK_ICON_SIZE_MENU);
 
1386
        gtk_button_set_image (GTK_BUTTON(add_button), image);
 
1387
        gtk_button_set_relief (GTK_BUTTON (add_button), GTK_RELIEF_NONE);
 
1388
        gtk_widget_set_tooltip_text(add_button, _("Add preset"));
 
1389
 
 
1390
        g_signal_connect(G_OBJECT(add_button), "clicked", G_CALLBACK(add_button_clicked_cb), NULL);
 
1391
 
 
1392
        remove_button = gtk_button_new();
 
1393
        image = gtk_image_new_from_icon_name ("list-remove", GTK_ICON_SIZE_MENU);
 
1394
        gtk_button_set_image (GTK_BUTTON (remove_button), image);
 
1395
        gtk_button_set_relief (GTK_BUTTON (remove_button), GTK_RELIEF_NONE);
 
1396
        gtk_widget_set_tooltip_text(remove_button, _("Remove preset"));
 
1397
        gtk_widget_set_sensitive(remove_button, FALSE);
 
1398
 
 
1399
        g_signal_connect(G_OBJECT(remove_button), "clicked", G_CALLBACK(remove_button_clicked_cb), NULL);
 
1400
 
 
1401
        save_button = gtk_button_new();
 
1402
        image = gtk_image_new_from_icon_name ("document-save", GTK_ICON_SIZE_MENU);
 
1403
        gtk_button_set_image (GTK_BUTTON (save_button), image);
 
1404
        gtk_button_set_relief (GTK_BUTTON (save_button), GTK_RELIEF_NONE);
 
1405
        gtk_widget_set_tooltip_text(save_button, _("Save to file\xE2\x80\xA6"));
 
1406
 
 
1407
        if (settings.presets == NULL)
 
1408
                gtk_widget_set_sensitive (save_button, FALSE);
 
1409
        else
 
1410
                gtk_widget_set_sensitive (save_button, TRUE);
 
1411
 
 
1412
        g_signal_connect(G_OBJECT(save_button), "clicked", G_CALLBACK(save_to_file_cb), NULL);
 
1413
 
 
1414
        open_button = gtk_button_new();
 
1415
        image = gtk_image_new_from_icon_name ("document-open", GTK_ICON_SIZE_MENU);
 
1416
        gtk_button_set_image (GTK_BUTTON(open_button), image);
 
1417
        gtk_button_set_relief (GTK_BUTTON (open_button), GTK_RELIEF_NONE);
 
1418
        gtk_widget_set_tooltip_text(open_button, _("Load from file\xE2\x80\xA6"));
 
1419
        gtk_widget_set_sensitive(open_button, TRUE);
 
1420
 
 
1421
        g_signal_connect(G_OBJECT(open_button), "clicked", G_CALLBACK(load_from_file_cb), NULL);
 
1422
 
 
1423
        gtk_box_pack_end(GTK_BOX(button_box), move_down_button, FALSE, FALSE, 0);
 
1424
        gtk_box_pack_end(GTK_BOX(button_box), move_up_button, FALSE, FALSE, 0);
 
1425
        gtk_box_pack_end(GTK_BOX(button_box), remove_button, FALSE, FALSE, 0);
 
1426
        gtk_box_pack_end(GTK_BOX(button_box), add_button, FALSE, FALSE, 0);
 
1427
        gtk_box_pack_end(GTK_BOX(button_box), save_button, FALSE, FALSE, 0);
 
1428
        gtk_box_pack_end(GTK_BOX(button_box), open_button, FALSE, FALSE, 0);
 
1429
 
 
1430
        gtk_grid_attach(GTK_GRID(grid), button_box, 2, 7, 1, 1);
 
1431
 
 
1432
        /* The record settings part */
 
1433
        label = gtk_label_new (NULL);
 
1434
        markup = g_strdup_printf ("<span weight=\"bold\">%s</span>", _("Record Settings"));
 
1435
        gtk_widget_set_halign (label, GTK_ALIGN_START);
 
1436
        gtk_label_set_markup (GTK_LABEL (label), markup);
 
1437
        g_free (markup);
 
1438
        gtk_grid_attach (GTK_GRID (grid), label, 0, 8, 2, 1);
 
1439
 
 
1440
        label = gtk_label_new ("");
 
1441
        gtk_grid_attach (GTK_GRID (grid), label, 0, 9, 1, 2);
 
1442
 
 
1443
        label = gtk_label_new (_("Destination:"));
 
1444
        gtk_widget_set_halign (label, GTK_ALIGN_START);
 
1445
        gtk_grid_attach(GTK_GRID(grid), label, 1, 9, 1, 1);
 
1446
 
 
1447
        destination_button = gtk_file_chooser_button_new (_("Select a folder"), GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
 
1448
        gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(destination_button), rec_settings.destination);
 
1449
        gtk_grid_attach(GTK_GRID(grid), destination_button, 2, 9, 1, 1);
 
1450
 
 
1451
        label = gtk_label_new (_("Format:"));
 
1452
        gtk_widget_set_halign (label, GTK_ALIGN_START);
 
1453
        gtk_grid_attach (GTK_GRID (grid), label, 1, 10, 1, 1);
 
1454
 
 
1455
        audio_profile_combo = audio_profile_choose_new();
 
1456
        audio_profile_chooser_set_active(audio_profile_combo, rec_settings.profile);
 
1457
        gtk_grid_attach (GTK_GRID (grid), audio_profile_combo, 2, 10, 1, 1);
 
1458
 
 
1459
        install_button = gtk_button_new_with_label(_("Install additional software required to use this format"));
 
1460
        gtk_widget_set_no_show_all (install_button, TRUE);
 
1461
        gtk_grid_attach (GTK_GRID (grid), install_button, 2, 11, 1, 1);
 
1462
 
 
1463
        profile = rb_gst_get_encoding_profile (rec_settings.profile);
 
1464
        if (rb_gst_check_missing_plugins (profile, NULL, NULL)) {
 
1465
                gtk_widget_set_visible (install_button, TRUE);
 
1466
                gtk_widget_set_sensitive (install_button,
 
1467
                                        gst_install_plugins_supported ());
 
1468
        } else {
 
1469
                gtk_widget_set_visible (install_button, FALSE);
 
1470
        }
 
1471
 
 
1472
        g_signal_connect(GTK_FILE_CHOOSER(destination_button), "selection-changed", G_CALLBACK(destination_button_clicked_cb), NULL);
 
1473
        g_signal_connect(G_OBJECT(audio_profile_combo), "changed", G_CALLBACK(audio_profile_combo_change_cb), NULL);
 
1474
        g_signal_connect(G_OBJECT(install_button), "clicked", G_CALLBACK(audio_profile_install_plugins_cb), NULL);
 
1475
 
 
1476
        gtk_widget_set_tooltip_text(destination_button, _("Select a location where to save recorded file."));
 
1477
        gtk_widget_set_tooltip_text(audio_profile_combo, _("Choose the format that should be used for recording."));
 
1478
 
 
1479
        gtk_widget_show_all(dialog);
 
1480
 
 
1481
        return dialog;
 
1482
}