1 /* wavbreaker - A tool to split a wave file up into multiple waves.
2 * Copyright (C) 2002-2004 Timothy Robinson
3 * Copyright (C) 2007 Thomas Perl
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20 #include <config.h>
21
22 #include "appconfig.h"
23 #include "sample.h"
24 #include "popupmessage.h"
25
26 #include "gettext.h"
27
28 #include "aoaudio.h"
29
30 #include <gtk/gtk.h>
31 #include <glib.h>
32
33 #include <stdlib.h>
34 #include <unistd.h>
35 #include <string.h>
36
37 static GtkWidget *window;
38
39 static gboolean loading_ui = FALSE;
40
41 static int config_file_version = 2;
42
43 /* Function pointers to the currently selected audio driver. */
44 static AudioFunctionPointers audio_function_pointers;
45
46 /* Output directory for wave files. */
47 static int use_outputdir = 0;
48 static GtkWidget *use_outputdir_toggle = NULL;
49 static char *outputdir = NULL;
50 static GtkWidget *outputdir_entry = NULL;
51 static GtkWidget *browse_button = NULL;
52
53 /* Etree filename suffix */
54 /* Filename suffix (not extension) for wave files. */
55 static int use_etree_filename_suffix = 0;
56
57 static char *etree_filename_suffix = NULL;
58 static GtkWidget *etree_filename_suffix_label = NULL;
59 static GtkWidget *etree_filename_suffix_entry = NULL;
60
61 /* Radio buttons */
62 static GtkWidget *radio1 = NULL;
63 static GtkWidget *radio2 = NULL;
64
65 /* Prepend File Number for wave files. */
66 static int prepend_file_number = 0;
67 static GtkWidget *prepend_file_number_toggle = NULL;
68
69 /* CD Length disc cutoff. */
70 static char *etree_cd_length = NULL;
71 static GtkWidget *etree_cd_length_label = NULL;
72 static GtkWidget *etree_cd_length_entry = NULL;
73
74 /* Config Filename */
75 static char *config_filename = NULL;
76
77 /* Window and pane sizes. */
78 static int main_window_xpos = -1;
79 static int main_window_ypos = -1;
80 static int main_window_width = -1;
81 static int main_window_height = -1;
82 static int vpane1_position = -1;
83 static int vpane2_position = -1;
84
85 /* Percentage for silence detection */
86 static int silence_percentage = 2;
87 static GtkWidget *silence_spin_button = NULL;
88
89 /* Draw moodbar in main window */
90 static int show_moodbar = 1;
91
92 /* function prototypes */
93 static int appconfig_read_file();
94 static void default_all_strings();
95 static void open_select_outputdir();
96
appconfig_get_config_file_version()97 int appconfig_get_config_file_version()
98 {
99 return config_file_version;
100 }
101
appconfig_set_config_file_version(int x)102 void appconfig_set_config_file_version(int x)
103 {
104 config_file_version = x;
105 }
106
get_audio_function_pointers()107 AudioFunctionPointers *get_audio_function_pointers()
108 {
109 return &audio_function_pointers;
110 }
111
set_audio_close_device(void (* f))112 void set_audio_close_device(void (*f))
113 {
114 audio_function_pointers.audio_close_device = f;
115 }
116
set_audio_open_device(void (* f))117 void set_audio_open_device(void (*f))
118 {
119 audio_function_pointers.audio_open_device = f;
120 }
121
set_audio_write(void (* f))122 void set_audio_write(void (*f))
123 {
124 audio_function_pointers.audio_write = f;
125 }
126
set_audio_function_pointers()127 void set_audio_function_pointers()
128 {
129 set_audio_close_device(ao_audio_close_device);
130 set_audio_open_device(ao_audio_open_device);
131 set_audio_write(ao_audio_write);
132 }
133
appconfig_get_main_window_xpos()134 int appconfig_get_main_window_xpos()
135 {
136 return main_window_xpos;
137 }
138
appconfig_set_main_window_xpos(int x)139 void appconfig_set_main_window_xpos(int x)
140 {
141 main_window_xpos = x;
142 }
143
appconfig_get_main_window_ypos()144 int appconfig_get_main_window_ypos()
145 {
146 return main_window_ypos;
147 }
148
appconfig_set_main_window_ypos(int x)149 void appconfig_set_main_window_ypos(int x)
150 {
151 main_window_ypos = x;
152 }
153
appconfig_get_main_window_width()154 int appconfig_get_main_window_width()
155 {
156 return main_window_width;
157 }
158
appconfig_set_main_window_width(int x)159 void appconfig_set_main_window_width(int x)
160 {
161 main_window_width = x;
162 }
163
appconfig_get_main_window_height()164 int appconfig_get_main_window_height()
165 {
166 return main_window_height;
167 }
168
appconfig_set_main_window_height(int x)169 void appconfig_set_main_window_height(int x)
170 {
171 main_window_height = x;
172 }
173
appconfig_get_vpane1_position()174 int appconfig_get_vpane1_position()
175 {
176 return vpane1_position;
177 }
178
appconfig_set_vpane1_position(int x)179 void appconfig_set_vpane1_position(int x)
180 {
181 vpane1_position = x;
182 }
183
appconfig_get_vpane2_position()184 int appconfig_get_vpane2_position()
185 {
186 return vpane2_position;
187 }
188
appconfig_set_vpane2_position(int x)189 void appconfig_set_vpane2_position(int x)
190 {
191 vpane2_position = x;
192 }
193
appconfig_get_silence_percentage()194 int appconfig_get_silence_percentage()
195 {
196 return silence_percentage;
197 }
198
appconfig_set_silence_percentage(int x)199 void appconfig_set_silence_percentage(int x)
200 {
201 silence_percentage = x;
202 }
203
appconfig_get_show_moodbar()204 int appconfig_get_show_moodbar() {
205 return show_moodbar;
206 }
207
appconfig_set_show_moodbar(int x)208 void appconfig_set_show_moodbar(int x)
209 {
210 show_moodbar = x;
211 }
212
appconfig_get_use_outputdir()213 int appconfig_get_use_outputdir()
214 {
215 return use_outputdir;
216 }
217
appconfig_set_use_outputdir(int x)218 void appconfig_set_use_outputdir(int x)
219 {
220 use_outputdir = x;
221 }
222
appconfig_get_outputdir()223 char *appconfig_get_outputdir()
224 {
225 return outputdir;
226 }
227
appconfig_set_outputdir(const char * val)228 void appconfig_set_outputdir(const char *val)
229 {
230 if (outputdir != NULL) {
231 g_free(outputdir);
232 }
233 outputdir = g_strdup(val);
234 }
235
appconfig_get_use_etree_filename_suffix()236 int appconfig_get_use_etree_filename_suffix()
237 {
238 return use_etree_filename_suffix;
239 }
240
appconfig_set_use_etree_filename_suffix(int x)241 void appconfig_set_use_etree_filename_suffix(int x)
242 {
243 use_etree_filename_suffix = x;
244 }
245
appconfig_get_etree_filename_suffix()246 char *appconfig_get_etree_filename_suffix()
247 {
248 return etree_filename_suffix;
249 }
250
appconfig_set_etree_filename_suffix(const char * val)251 void appconfig_set_etree_filename_suffix(const char *val)
252 {
253 if (etree_filename_suffix != NULL) {
254 g_free(etree_filename_suffix);
255 }
256 etree_filename_suffix = g_strdup(val);
257 }
258
appconfig_get_prepend_file_number()259 int appconfig_get_prepend_file_number()
260 {
261 return prepend_file_number;
262 }
263
appconfig_set_prepend_file_number(int x)264 void appconfig_set_prepend_file_number(int x)
265 {
266 prepend_file_number = x;
267 }
268
appconfig_get_etree_cd_length()269 char *appconfig_get_etree_cd_length()
270 {
271 return etree_cd_length;
272 }
273
appconfig_set_etree_cd_length(const char * val)274 void appconfig_set_etree_cd_length(const char *val)
275 {
276 if (etree_cd_length != NULL) {
277 g_free(etree_cd_length);
278 }
279 etree_cd_length = g_strdup(val);
280 }
281
get_config_filename()282 char *get_config_filename()
283 {
284 return config_filename;
285 }
286
set_config_filename(const char * val)287 void set_config_filename(const char *val)
288 {
289 if (config_filename != NULL) {
290 g_free(config_filename);
291 }
292 config_filename = g_strdup(val);
293 }
294
use_outputdir_toggled(GtkWidget * widget,gpointer user_data)295 static void use_outputdir_toggled(GtkWidget *widget, gpointer user_data)
296 {
297 if (loading_ui) {
298 return;
299 }
300
301 if (appconfig_get_use_outputdir()) {
302 // disable the output dir widget
303 gtk_widget_set_sensitive(outputdir_entry, FALSE);
304 gtk_widget_set_sensitive(browse_button, FALSE);
305 appconfig_set_use_outputdir(0);
306 } else {
307 // enable the output dir widget
308 gtk_widget_set_sensitive(outputdir_entry, TRUE);
309 gtk_widget_set_sensitive(browse_button, TRUE);
310 appconfig_set_use_outputdir(1);
311 }
312 }
313
use_etree_filename_suffix_toggled(GtkWidget * widget,gpointer user_data)314 static void use_etree_filename_suffix_toggled(GtkWidget *widget, gpointer user_data)
315 {
316 if (appconfig_get_use_etree_filename_suffix()) {
317 appconfig_set_use_etree_filename_suffix(0);
318 } else {
319 appconfig_set_use_etree_filename_suffix(1);
320 }
321 }
322
radio_buttons_toggled(GtkWidget * widget,gpointer user_data)323 static void radio_buttons_toggled(GtkWidget *widget, gpointer user_data)
324 {
325 if (loading_ui) {
326 return;
327 }
328
329 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radio1)) == TRUE) {
330 gtk_widget_set_sensitive( prepend_file_number_toggle, TRUE);
331 gtk_widget_set_sensitive( etree_filename_suffix_entry, TRUE);
332 gtk_widget_set_sensitive( etree_filename_suffix_label, TRUE);
333 gtk_widget_set_sensitive( etree_cd_length_entry, FALSE);
334 gtk_widget_set_sensitive( etree_cd_length_label, FALSE);
335 } else {
336 gtk_widget_set_sensitive( prepend_file_number_toggle, FALSE);
337 gtk_widget_set_sensitive( etree_filename_suffix_entry, FALSE);
338 gtk_widget_set_sensitive( etree_filename_suffix_label, FALSE);
339 gtk_widget_set_sensitive( etree_cd_length_entry, TRUE);
340 gtk_widget_set_sensitive( etree_cd_length_label, TRUE);
341 }
342 }
343
prepend_file_number_toggled(GtkWidget * widget,gpointer user_data)344 static void prepend_file_number_toggled(GtkWidget *widget, gpointer user_data)
345 {
346 if (loading_ui) {
347 return;
348 }
349
350 if (appconfig_get_prepend_file_number()) {
351 appconfig_set_prepend_file_number(0);
352 } else {
353 appconfig_set_prepend_file_number(1);
354 }
355 }
356
appconfig_hide(GtkWidget * main_window)357 static void appconfig_hide(GtkWidget *main_window)
358 {
359 gtk_widget_destroy(main_window);
360 }
361
browse_button_clicked(GtkWidget * widget,gpointer user_data)362 static void browse_button_clicked(GtkWidget *widget, gpointer user_data)
363 {
364 open_select_outputdir();
365 }
366
open_select_outputdir()367 static void open_select_outputdir() {
368 GtkWidget *dialog;
369
370 dialog = gtk_file_chooser_dialog_new(_("Select Output Directory"),
371 GTK_WINDOW(window), GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
372 _("Cancel"), GTK_RESPONSE_CANCEL,
373 _("Open"), GTK_RESPONSE_ACCEPT,
374 NULL);
375 gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(dialog),
376 gtk_entry_get_text(GTK_ENTRY(outputdir_entry)));
377
378 if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
379 char *filename;
380
381 filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
382 gtk_entry_set_text(GTK_ENTRY(outputdir_entry), filename);
383 g_free(filename);
384 }
385
386 gtk_widget_destroy(dialog);
387 }
388
389 static void
on_appconfig_close(GtkWidget * widget,GdkEvent * event,gpointer user_data)390 on_appconfig_close(GtkWidget *widget, GdkEvent *event, gpointer user_data)
391 {
392 appconfig_set_outputdir(gtk_entry_get_text(GTK_ENTRY(outputdir_entry)));
393 appconfig_set_etree_filename_suffix(gtk_entry_get_text(GTK_ENTRY(etree_filename_suffix_entry)));
394 appconfig_set_etree_cd_length(gtk_entry_get_text(GTK_ENTRY(etree_cd_length_entry)));
395 appconfig_set_silence_percentage( gtk_spin_button_get_value_as_int( GTK_SPIN_BUTTON(silence_spin_button)));
396 set_audio_function_pointers();
397
398 track_break_rename( FALSE);
399 appconfig_hide(GTK_WIDGET(user_data));
400 appconfig_write_file();
401 }
402
appconfig_show(GtkWidget * main_window)403 void appconfig_show(GtkWidget *main_window)
404 {
405 GtkWidget *vbox;
406 GtkWidget *grid;
407 GtkWidget *label;
408
409 GtkWidget *stack;
410
411 window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
412 gtk_window_set_modal(GTK_WINDOW(window), TRUE);
413 gtk_window_set_transient_for(GTK_WINDOW(window), GTK_WINDOW(main_window));
414 gtk_window_set_type_hint(GTK_WINDOW(window), GDK_WINDOW_TYPE_HINT_DIALOG);
415 gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER_ON_PARENT);
416
417 GtkWidget *header_bar = gtk_header_bar_new();
418 gtk_header_bar_set_show_close_button(GTK_HEADER_BAR(header_bar), TRUE);
419 gtk_header_bar_set_title(GTK_HEADER_BAR(header_bar), _("Preferences"));
420 gtk_window_set_titlebar(GTK_WINDOW(window), header_bar);
421
422 /* create the vbox for the first tab */
423 vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 10);
424 gtk_container_set_border_width(GTK_CONTAINER(vbox), 10);
425 gtk_container_add( GTK_CONTAINER(window), vbox);
426
427 stack = gtk_stack_new();
428 gtk_container_add(GTK_CONTAINER(vbox), stack);
429
430 GtkWidget *stack_switcher = gtk_stack_switcher_new();
431 gtk_stack_switcher_set_stack(GTK_STACK_SWITCHER(stack_switcher), GTK_STACK(stack));
432 gtk_header_bar_set_custom_title(GTK_HEADER_BAR(header_bar), stack_switcher);
433
434 /* Selectable Output Directory */
435 grid = gtk_grid_new();
436 gtk_container_set_border_width(GTK_CONTAINER(grid), 10);
437 gtk_grid_set_row_spacing(GTK_GRID(grid), 5);
438 gtk_grid_set_column_spacing(GTK_GRID(grid), 5);
439 gtk_stack_add_titled(GTK_STACK(stack), grid, "general", _("General"));
440
441 use_outputdir_toggle = gtk_check_button_new_with_label(_("Save output files in folder:"));
442 gtk_grid_attach(GTK_GRID(grid), use_outputdir_toggle,
443 0, 0, 2, 1);
444 g_signal_connect(G_OBJECT(use_outputdir_toggle), "toggled",
445 G_CALLBACK(use_outputdir_toggled), NULL);
446
447 outputdir_entry = gtk_entry_new();
448 g_object_set(outputdir_entry, "hexpand", TRUE, NULL);
449 gtk_entry_set_text(GTK_ENTRY(outputdir_entry), outputdir);
450 gtk_entry_set_width_chars(GTK_ENTRY(outputdir_entry), 40);
451 gtk_grid_attach(GTK_GRID(grid), outputdir_entry,
452 0, 1, 1, 1);
453
454 browse_button = gtk_button_new_with_label(_("Browse"));
455 gtk_grid_attach(GTK_GRID(grid), browse_button,
456 1, 1, 1, 1);
457 g_signal_connect(G_OBJECT(browse_button), "clicked",
458 (GCallback)browse_button_clicked, window);
459
460 silence_spin_button = (GtkWidget*)gtk_spin_button_new_with_range( 1.0, 100.0, 1.0);
461 gtk_spin_button_set_digits( GTK_SPIN_BUTTON(silence_spin_button), 0);
462 gtk_spin_button_set_value( GTK_SPIN_BUTTON(silence_spin_button), appconfig_get_silence_percentage());
463
464 label = gtk_label_new( _("Maximum volume considered silence (in percent):"));
465 g_object_set(G_OBJECT(label), "xalign", 0.0f, "yalign", 0.5f, NULL);
466
467 gtk_grid_attach(GTK_GRID(grid), label,
468 0, 2, 1, 1);
469 gtk_grid_attach(GTK_GRID(grid), silence_spin_button,
470 1, 2, 1, 1);
471
472 /* Etree Filename Suffix */
473
474 grid = gtk_grid_new();
475 gtk_container_set_border_width(GTK_CONTAINER(grid), 10);
476 gtk_grid_set_row_spacing(GTK_GRID(grid), 5);
477 gtk_grid_set_column_spacing(GTK_GRID(grid), 5);
478 gtk_stack_add_titled(GTK_STACK(stack), grid, "naming", _("File Naming"));
479
480 radio1 = gtk_radio_button_new_with_label(NULL, _("Standard (##)"));
481 gtk_grid_attach(GTK_GRID(grid), radio1, 0, 0, 3, 1);
482 g_signal_connect(G_OBJECT(radio1), "toggled",
483 G_CALLBACK(radio_buttons_toggled), NULL);
484
485 etree_filename_suffix_label = gtk_label_new(_("Separator:"));
486 g_object_set(G_OBJECT(etree_filename_suffix_label), "xalign", 0.0f, "yalign", 0.5f, NULL);
487 gtk_grid_attach(GTK_GRID(grid), etree_filename_suffix_label,
488 1, 1, 1, 1);
489
490 etree_filename_suffix_entry = gtk_entry_new();
491 g_object_set(etree_filename_suffix_entry, "hexpand", TRUE, NULL);
492 gtk_entry_set_text(GTK_ENTRY(etree_filename_suffix_entry), etree_filename_suffix);
493 gtk_entry_set_width_chars(GTK_ENTRY(etree_filename_suffix_entry), 10);
494 gtk_grid_attach(GTK_GRID(grid), etree_filename_suffix_entry,
495 2, 1, 1, 1);
496
497 label = gtk_label_new(" ");
498 g_object_set(G_OBJECT(label), "xalign", 0.0f, "yalign", 0.5f, NULL);
499 gtk_grid_attach(GTK_GRID(grid), label,
500 0, 2, 1, 1);
501
502 prepend_file_number_toggle = gtk_check_button_new_with_label(_("Prepend number before filename"));
503 gtk_grid_attach(GTK_GRID(grid), prepend_file_number_toggle,
504 1, 2, 2, 1);
505 g_signal_connect(G_OBJECT(prepend_file_number_toggle), "toggled",
506 G_CALLBACK(prepend_file_number_toggled), NULL);
507
508 radio2 = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(radio1),
509 _("etree.org (d#t##)"));
510 gtk_grid_attach(GTK_GRID(grid), radio2, 0, 3, 3, 1);
511
512 etree_cd_length_label = gtk_label_new(_("CD Length:"));
513 g_object_set(G_OBJECT(etree_cd_length_label), "xalign", 0.0f, "yalign", 0.5f, NULL);
514 gtk_grid_attach(GTK_GRID(grid), etree_cd_length_label,
515 1, 4, 1, 1);
516
517 etree_cd_length_entry = gtk_entry_new();
518 gtk_entry_set_text(GTK_ENTRY(etree_cd_length_entry), etree_cd_length);
519 gtk_entry_set_width_chars(GTK_ENTRY(etree_cd_length_entry), 10);
520 gtk_grid_attach(GTK_GRID(grid), etree_cd_length_entry,
521 2, 4, 1, 1);
522
523 g_signal_connect(G_OBJECT(window),
524 "delete-event", G_CALLBACK(on_appconfig_close), window);
525
526 g_signal_connect(G_OBJECT(radio2), "toggled",
527 G_CALLBACK(use_etree_filename_suffix_toggled), NULL);
528
529 loading_ui = TRUE;
530
531 gboolean use_output_dir = appconfig_get_use_outputdir() ? TRUE : FALSE;
532 gtk_widget_set_sensitive(outputdir_entry, use_output_dir);
533 gtk_widget_set_sensitive(browse_button, use_output_dir);
534 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(use_outputdir_toggle), use_output_dir);
535
536 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(prepend_file_number_toggle),
537 appconfig_get_prepend_file_number() ? TRUE : FALSE);
538
539 gboolean use_etree = appconfig_get_use_etree_filename_suffix() ? TRUE : FALSE;
540 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio1), !use_etree);
541 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio2), use_etree);
542
543 loading_ui = FALSE;
544
545 gtk_widget_show_all(window);
546 set_audio_function_pointers();
547 radio_buttons_toggled( NULL, NULL);
548 }
549
550 enum ConfigOptionType {
551 INVALID = 0,
552 STRING,
553 INTEGER,
554 BOOLEAN,
555 };
556
557 typedef struct ConfigOption_ ConfigOption;
558
559 struct ConfigOption_ {
560 const char *key;
561 enum ConfigOptionType type;
562 void *setter;
563 void *getter;
564 } config_options[] = {
565 #define OPTION(name, type) { #name, type, appconfig_set_ ## name, appconfig_get_ ## name }
566 OPTION(config_file_version, INTEGER),
567
568 OPTION(use_outputdir, BOOLEAN),
569 OPTION(outputdir, STRING),
570
571 OPTION(use_etree_filename_suffix, BOOLEAN),
572 OPTION(etree_filename_suffix, STRING),
573 OPTION(etree_cd_length, STRING),
574 OPTION(prepend_file_number, BOOLEAN),
575
576 OPTION(main_window_xpos, INTEGER),
577 OPTION(main_window_ypos, INTEGER),
578 OPTION(main_window_width, INTEGER),
579 OPTION(main_window_height, INTEGER),
580
581 OPTION(vpane1_position, INTEGER),
582 OPTION(vpane2_position, INTEGER),
583
584 OPTION(silence_percentage, INTEGER),
585 OPTION(show_moodbar, BOOLEAN),
586 #undef OPTION
587 { NULL, INVALID, NULL, NULL },
588 };
589
590
config_option_set_string(ConfigOption * option,gchar * value)591 void config_option_set_string(ConfigOption *option, gchar *value)
592 {
593 ((void (*)(const char *))(option->setter))(value);
594 g_free(value);
595 }
596
config_option_set_integer(ConfigOption * option,int value)597 void config_option_set_integer(ConfigOption *option, int value)
598 {
599 ((void (*)(int))(option->setter))(value);
600 }
601
config_option_get_string(ConfigOption * option)602 const char *config_option_get_string(ConfigOption *option)
603 {
604 return ((const char *(*)())(option->getter))();
605 }
606
config_option_get_integer(ConfigOption * option)607 int config_option_get_integer(ConfigOption *option)
608 {
609 return ((int (*)())(option->getter))();
610 }
611
appconfig_read_file()612 static int appconfig_read_file() {
613 GKeyFile *keyfile = g_key_file_new();
614
615 if (!g_key_file_load_from_file(keyfile, config_filename, G_KEY_FILE_NONE, NULL)) {
616 g_key_file_free(keyfile);
617 return 0;
618 }
619
620 ConfigOption *option = config_options;
621 for (option=config_options; option->key; option++) {
622 switch (option->type) {
623 case INTEGER:
624 config_option_set_integer(option,
625 g_key_file_get_integer(keyfile, "wavbreaker", option->key, NULL));
626 break;
627 case BOOLEAN:
628 config_option_set_integer(option,
629 g_key_file_get_boolean(keyfile, "wavbreaker", option->key, NULL));
630 break;
631 case STRING:
632 config_option_set_string(option,
633 g_key_file_get_string(keyfile, "wavbreaker", option->key, NULL));
634 break;
635 default:
636 g_warning("Invalid option type: %d\n", option->type);
637 break;
638 }
639 }
640
641 g_key_file_free(keyfile);
642
643 return 1;
644 }
645
646
appconfig_write_file()647 void appconfig_write_file() {
648 GKeyFile *keyfile = g_key_file_new();
649
650 g_key_file_load_from_file(keyfile, config_filename, G_KEY_FILE_KEEP_COMMENTS, NULL);
651
652 ConfigOption *option = config_options;
653 for (option=config_options; option->key; option++) {
654 switch (option->type) {
655 case INTEGER:
656 g_key_file_set_integer(keyfile, "wavbreaker", option->key,
657 config_option_get_integer(option));
658 break;
659 case BOOLEAN:
660 g_key_file_set_boolean(keyfile, "wavbreaker", option->key,
661 config_option_get_integer(option));
662 break;
663 case STRING:
664 g_key_file_set_string(keyfile, "wavbreaker", option->key,
665 config_option_get_string(option));
666 break;
667 default:
668 g_warning("Invalid option type: %d\n", option->type);
669 break;
670 }
671 }
672
673 if (!g_key_file_save_to_file(keyfile, config_filename, NULL)) {
674 g_warning("Could not save settings");
675 }
676
677 g_key_file_free(keyfile);
678 }
679
appconfig_init()680 void appconfig_init()
681 {
682 gchar *config_filename = g_build_path("/", g_get_user_config_dir(),
683 "wavbreaker", "wavbreaker.conf", NULL);
684 set_config_filename(config_filename);
685
686 gchar *config_dir = g_path_get_dirname(config_filename);
687 if (g_mkdir_with_parents(config_dir, 0700) != 0) {
688 g_warning("Could not create configuration directory: %s", config_dir);
689 }
690 g_free(config_dir);
691 g_free(config_filename);
692
693 if (!appconfig_read_file()) {
694 default_all_strings();
695 appconfig_write_file();
696 } else {
697 default_all_strings();
698 }
699 }
700
default_all_strings()701 void default_all_strings() {
702 /* default any values that where not in the config file */
703 if (appconfig_get_outputdir() == NULL) {
704 outputdir = g_strdup(getenv("PWD"));
705 }
706 if (appconfig_get_etree_filename_suffix() == NULL) {
707 etree_filename_suffix = g_strdup("-");
708 }
709 if (appconfig_get_etree_cd_length() == NULL) {
710 etree_cd_length = g_strdup("80");
711 }
712
713 set_audio_function_pointers();
714 }
715