mp3splt-gtk
preferences_manager.c
Go to the documentation of this file.
1 /**********************************************************
2  *
3  * mp3splt-gtk -- utility based on mp3splt,
4  * for mp3/ogg splitting without decoding
5  *
6  * Copyright: (C) 2005-2012 Alexandru Munteanu
7  * Contact: io_fx@yahoo.fr
8  *
9  * http://mp3splt.sourceforge.net/
10  *
11  *********************************************************/
12 
13 /**********************************************************
14  *
15  * This program is free software; you can redistribute it and/or
16  * modify it under the terms of the GNU General Public License
17  * as published by the Free Software Foundation; either version 2
18  * of the License, or (at your option) any later version.
19  *
20  * This program is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23  * GNU General Public License for more details.
24  *
25  * You should have received a copy of the GNU General Public License
26  * along with this program; if not, write to the Free Software
27  * USA.
28  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
29  *
30  *********************************************************/
31 
32 /*!********************************************************
33  * \file
34  * Save and read preferences
35  *
36  * This file contains the functions to save the preferences
37  * on the hard disk and to read them again at the next
38  * start of the program.
39  ********************************************************/
40 
41 #include "preferences_manager.h"
42 
43 #include "all_includes.h"
44 
45 static void check_pref_file_and_write_default(ui_state *ui);
46 static void pm_free_spinner_int_preferences(GArray *spinner_int_preferences);
47 static void pm_free_range_preferences(GArray *range_preferences);
48 static void pm_load_spinner_int_preferences(GKeyFile *key_file, preferences_state *pm);
49 static void pm_save_spinner_int_preferences(GKeyFile *key_file, preferences_state *pm);
50 static void pm_write_default_spinner_int_preferences(GKeyFile *key_file, preferences_state *pm);
51 static void pm_load_range_preferences(GKeyFile *key_file, preferences_state *pm);
52 static void pm_save_range_preferences(GKeyFile *key_file, preferences_state *pm);
53 static void pm_write_default_range_preferences(GKeyFile *key_file, preferences_state *pm);
54 
55 void pm_register_spinner_int_preference(gchar *main_key, gchar *second_key,
56  gint default_value, GtkWidget *spinner,
57  void (*update_spinner_value_cb)(GtkWidget *spinner, gpointer data),
58  gpointer user_data_for_cb, preferences_state *pm)
59 {
60  spinner_int_preference preference;
61 
62  preference.main_key = strdup(main_key);
63  preference.second_key = strdup(second_key);
64  preference.default_value = default_value;
65  preference.spinner = spinner;
66  preference.update_spinner_value_cb = update_spinner_value_cb;
67  preference.user_data_for_cb = user_data_for_cb;
68 
69  g_array_append_val(pm->spinner_int_preferences, preference);
70 }
71 
72 void pm_register_range_preference(gchar *main_key, gchar *second_key,
73  gint default_value, GtkWidget *range,
74  void (*update_adjustment_value)(GtkAdjustment *adjustment, gpointer data),
75  gpointer user_data_for_cb, preferences_state *pm)
76 {
77  range_preference preference;
78 
79  preference.main_key = strdup(main_key);
80  preference.second_key = strdup(second_key);
81  preference.default_value = default_value;
82  preference.range = range;
83  preference.update_adjustment_value = update_adjustment_value;
84  preference.user_data_for_cb = user_data_for_cb;
85 
86  g_array_append_val(pm->range_preferences, preference);
87 }
88 
89 preferences_state *pm_state_new()
90 {
91  preferences_state *pm = g_malloc0(sizeof(preferences_state));
92 
93  pm->spinner_int_preferences = g_array_new(TRUE, TRUE, sizeof(spinner_int_preference));
94  pm->range_preferences = g_array_new(TRUE, TRUE, sizeof(range_preference));
95 
96  return pm;
97 }
98 
99 void pm_free(preferences_state **pm)
100 {
101  if (!pm || !*pm)
102  {
103  return;
104  }
105 
106  pm_free_spinner_int_preferences((*pm)->spinner_int_preferences);
107  pm_free_range_preferences((*pm)->range_preferences);
108 
109  g_free(*pm);
110  *pm = NULL;
111 }
112 
113 static void pm_load(GKeyFile *key_file, preferences_state *pm)
114 {
115  pm_load_spinner_int_preferences(key_file, pm);
116  pm_load_range_preferences(key_file, pm);
117 }
118 
119 static void pm_save(GKeyFile *key_file, preferences_state *pm)
120 {
121  pm_save_spinner_int_preferences(key_file, pm);
122  pm_save_range_preferences(key_file, pm);
123 }
124 
125 static void pm_write_default(GKeyFile *key_file, preferences_state *pm)
126 {
127  pm_write_default_spinner_int_preferences(key_file, pm);
128  pm_write_default_range_preferences(key_file, pm);
129 }
130 
140 {
141  gchar mp3splt_dir[14] = ".mp3splt-gtk";
142 
143  gchar *home_dir = g_strdup(g_get_home_dir());
144 
145 #ifdef __WIN32__
146  //manage c:\ because the gtk dir returns us "c:\"
147  //and the normal directories without the "\"
148  if (home_dir[strlen(home_dir)-1] == '\\')
149  {
150  home_dir[strlen(home_dir)-1] = '\0';
151  }
152 #endif
153 
154  gint malloc_number = strlen(home_dir) + strlen(mp3splt_dir) + 2;
155  gchar *mp3splt_dir_with_path = malloc(malloc_number * sizeof(gchar));
156  g_snprintf(mp3splt_dir_with_path, malloc_number,
157  "%s%s%s", home_dir, G_DIR_SEPARATOR_S, mp3splt_dir);
158 
159  if (home_dir)
160  {
161  g_free(home_dir);
162  home_dir = NULL;
163  }
164 
165  gint fname_malloc_number = strlen(mp3splt_dir_with_path) + 30;
166  gchar *filename = malloc(fname_malloc_number * sizeof(gchar));
167 
168  struct stat buffer;
169  gint status = g_stat(mp3splt_dir_with_path, &buffer);
170  //if it is not a directory
171  if ((status != 0) || (S_ISDIR(buffer.st_mode) == 0))
172  {
173  //if its a file
174  if ((status == 0) && (S_ISREG(buffer.st_mode) != 0))
175  {
176  gint malloc_number = strlen(mp3splt_dir_with_path) + 5;
177  gchar *backup_file = malloc(malloc_number * sizeof(gchar));
178  snprintf(backup_file, malloc_number, "%s%s", mp3splt_dir_with_path,".bak");
179  g_rename(mp3splt_dir_with_path, backup_file);
180  g_free(backup_file);
181  }
182 
183  //if it is not a directory and not a file, we suppose we can
184  //create the directory
185 #ifdef __WIN32__
186  g_mkdir(mp3splt_dir_with_path, 0775);
187 #else
188  g_mkdir(mp3splt_dir_with_path, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
189 #endif
190  }
191 
192  g_snprintf(filename,fname_malloc_number, "%s%smp3splt-gtk_prefs",
193  mp3splt_dir_with_path, G_DIR_SEPARATOR_S);
194 
195  if (mp3splt_dir_with_path)
196  {
197  g_free(mp3splt_dir_with_path);
198  mp3splt_dir_with_path = NULL;
199  }
200 
201  return filename;
202 }
203 
207 {
208  check_pref_file_and_write_default(ui);
209 
210  GKeyFile *key_file = g_key_file_new();
211 
212  gchar *filename = get_preferences_filename();
213  g_key_file_load_from_file(key_file, filename, G_KEY_FILE_KEEP_COMMENTS, NULL);
214  if (filename)
215  {
216  g_free(filename);
217  }
218 
219 #ifdef __WIN32__
220  //language
221  gchar *file_string = g_key_file_get_string(key_file, "general", "language", NULL);
222  GString *lang = g_string_new(file_string);
223 
224  //0 = german, 1 = french, 2 = english
225  gint list_number = 2;
226  if (g_string_equal(lang,g_string_new("de")) || g_string_equal(lang,g_string_new("de_DE")))
227  {
228  list_number = 0;
229  }
230  else if (g_string_equal(lang, g_string_new("fr")) || g_string_equal(lang, g_string_new("fr_FR")))
231  {
232  list_number = 1;
233  }
234 
235  GSList *radio_button_list = gtk_radio_button_get_group(GTK_RADIO_BUTTON(ui->gui->radio_button));
236  GtkWidget *our_button = GTK_WIDGET(g_slist_nth_data(radio_button_list, list_number));
237  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(our_button), TRUE);
238 
239  g_free(file_string);
240  g_string_free(lang, TRUE);
241  file_string = NULL;
242  lang = NULL;
243 #endif
244 
245  // If get_output_directory()!=NULL the path where to output the split file
246  // to has been set from command line
247  if (get_output_directory(ui) == NULL)
248  {
249  // No output_path from command-line => get the path from the preferences
250  gchar *save_path = g_key_file_get_string(key_file, "split", "save_path", NULL);
251  if (save_path != NULL)
252  {
253  set_output_directory(save_path, ui);
254  }
255  g_free(save_path);
256  save_path = NULL;
257  }
258 
259  //player
260  gint item = g_key_file_get_integer(key_file, "player", "default_player",NULL);
261  ch_set_active_value(GTK_COMBO_BOX(ui->gui->player_combo_box), item);
262 
263  pm_load(key_file, ui->preferences);
264 
265  //frame mode
266  item = g_key_file_get_boolean(key_file, "split", "frame_mode", NULL);
267  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ui->gui->frame_mode), item);
268 
269  //adjust mode
270  item = g_key_file_get_boolean(key_file, "split", "adjust_mode", NULL);
271  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ui->gui->adjust_mode), item);
272 
273  item = g_key_file_get_boolean(key_file, "output", "splitpoint_names_from_filename", NULL);
274  if (item)
275  {
276  gtk_toggle_button_set_active(ui->gui->names_from_filename, TRUE);
277  }
278  else
279  {
280  gtk_toggle_button_set_active(ui->gui->names_from_filename, FALSE);
281  }
282 
283  //adjust threshold
284  gfloat item2;
285  item = g_key_file_get_integer(key_file, "split", "adjust_threshold", NULL);
286  item2 = item/100 + (item%100)/100.;
287  gtk_spin_button_set_value(GTK_SPIN_BUTTON(ui->gui->spinner_adjust_threshold), item2);
288  //adjust offset
289  item = g_key_file_get_integer(key_file, "split", "adjust_offset", NULL);
290  item2 = item/100 + (item%100)/100.;
291  gtk_spin_button_set_value(GTK_SPIN_BUTTON(ui->gui->spinner_adjust_offset), item2);
292  //adjust gap
293  item = g_key_file_get_integer(key_file, "split", "adjust_gap", NULL);
294  gtk_spin_button_set_value(GTK_SPIN_BUTTON(ui->gui->spinner_adjust_gap), item);
295 
296  //tags options
297  gint tag_pref_file = g_key_file_get_integer(key_file, "split", "tags", NULL);
298  GtkWidget *radio = rh_get_radio_from_value(ui->gui->tags_radio, tag_pref_file);
299  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio), TRUE);
300 
301  //replace underscores by spaces
302  item = g_key_file_get_boolean(key_file, "split", "replace_underscore_by_space", NULL);
303  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ui->gui->replace_underscore_by_space_check_box),
304  item);
305 
306  //artist text properties
307  item = g_key_file_get_integer(key_file, "split", "artist_text_properties",NULL);
308  if (item)
309  {
310  ch_set_active_value(ui->gui->artist_text_properties_combo, item);
311  }
312  else
313  {
314  ch_set_active_value(ui->gui->artist_text_properties_combo, SPLT_NO_CONVERSION);
315  }
316  //album text properties
317  item = g_key_file_get_integer(key_file, "split", "album_text_properties",NULL);
318  if (item)
319  {
320  ch_set_active_value(ui->gui->album_text_properties_combo, item);
321  }
322  else
323  {
324  ch_set_active_value(ui->gui->album_text_properties_combo, SPLT_NO_CONVERSION);
325  }
326  //title text properties
327  item = g_key_file_get_integer(key_file, "split", "title_text_properties",NULL);
328  if (item)
329  {
330  ch_set_active_value(ui->gui->title_text_properties_combo, item);
331  }
332  else
333  {
334  ch_set_active_value(ui->gui->title_text_properties_combo, SPLT_NO_CONVERSION);
335  }
336  //comment text properties
337  item = g_key_file_get_integer(key_file, "split", "comment_text_properties",NULL);
338  if (item)
339  {
340  ch_set_active_value(ui->gui->comment_text_properties_combo, item);
341  }
342  else
343  {
344  ch_set_active_value(ui->gui->comment_text_properties_combo, SPLT_NO_CONVERSION);
345  }
346 
347  //genre
348  gchar *default_genre = g_key_file_get_string(key_file, "split", "genre", NULL);
349  if (default_genre)
350  {
351  ch_set_active_str_value(ui->gui->genre_combo, default_genre);
352  g_free(default_genre);
353  default_genre = NULL;
354  }
355  else
356  {
357  ch_set_active_str_value(ui->gui->genre_combo, SPLT_UNDEFINED_GENRE);
358  }
359 
360  //default comment tag
361  gchar *default_comment_tag = g_key_file_get_string(key_file, "split", "default_comment_tag", NULL);
362  if (default_comment_tag)
363  {
364  gtk_entry_set_text(GTK_ENTRY(ui->gui->comment_tag_entry), default_comment_tag);
365  g_free(default_comment_tag);
366  default_comment_tag = NULL;
367  }
368 
369  //regexp to parse filename into tags
370  gchar *tags_from_fname_regex =
371  g_key_file_get_string(key_file, "split", "tags_from_filename_regex", NULL);
372  if (tags_from_fname_regex)
373  {
374  gtk_entry_set_text(GTK_ENTRY(ui->gui->regex_entry), tags_from_fname_regex);
375  g_free(tags_from_fname_regex);
376  tags_from_fname_regex = NULL;
377  }
378 
379  gchar *test_regex_fname =
380  g_key_file_get_string(key_file, "split", "test_regex_fname", NULL);
381  if (test_regex_fname)
382  {
383  gtk_entry_set_text(GTK_ENTRY(ui->gui->test_regex_fname_entry), test_regex_fname);
384  g_free(test_regex_fname);
385  test_regex_fname = NULL;
386  }
387 
388  //tags version
389  tag_pref_file = g_key_file_get_integer(key_file, "split", "tags_version", NULL);
390 
391  GSList *tags_version_radio_button_list =
392  gtk_radio_button_get_group(GTK_RADIO_BUTTON(ui->gui->tags_version_radio));
393  GtkWidget *the_selection =
394  GTK_WIDGET(g_slist_nth_data(tags_version_radio_button_list, tag_pref_file));
395  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(the_selection), TRUE);
396 
397  //default output format or not
398  gint default_output_format =
399  g_key_file_get_boolean(key_file, "output", "default_output_format", NULL);
400  GSList *output_radio_button_list =
401  gtk_radio_button_get_group(GTK_RADIO_BUTTON(ui->gui->radio_output));
402  GtkWidget *our_selection =
403  GTK_WIDGET(g_slist_nth_data(output_radio_button_list, default_output_format));
404  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(our_selection), TRUE);
405  if (default_output_format)
406  {
407  gtk_widget_set_sensitive(ui->gui->output_entry, FALSE);
408  gtk_widget_set_sensitive(ui->gui->output_label, FALSE);
409  }
410  else
411  {
412  gtk_widget_set_sensitive(ui->gui->output_default_label, FALSE);
413  }
414 
415  //output format
416  gchar *output_format = g_key_file_get_string(key_file, "output", "output_format", NULL);
417  if (output_format)
418  {
419  gtk_entry_set_text(GTK_ENTRY(ui->gui->output_entry), output_format);
420  g_free(output_format);
421  output_format = NULL;
422  }
423 
424  //create directories if needed
425  item = g_key_file_get_boolean(key_file, "output", "create_dirs_if_needed", NULL);
426  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ui->gui->create_dirs_from_output_files), item);
427 
428  //type of split: split mode
429  gint split_mode = g_key_file_get_integer(key_file, "split", "split_mode", NULL);
430  select_split_mode(split_mode, ui);
431 
432  //time value
433  gint time_value = g_key_file_get_integer(key_file, "split", "split_mode_time_value", NULL);
434  gtk_spin_button_set_value(GTK_SPIN_BUTTON(ui->gui->spinner_time), time_value);
435 
436  //equal time tracks value
437  gint equal_tracks = g_key_file_get_integer(key_file, "split",
438  "split_mode_equal_time_tracks", NULL);
439  gtk_spin_button_set_value(GTK_SPIN_BUTTON(ui->gui->spinner_equal_tracks), equal_tracks);
440 
441  gint root_x = g_key_file_get_integer(key_file, "gui", "root_x_position", NULL);
442  gint root_y = g_key_file_get_integer(key_file, "gui", "root_y_position", NULL);
443  if (root_x && root_y)
444  {
445  ui_set_main_win_position(ui, root_x, root_y);
446  }
447 
448  gint width = g_key_file_get_integer(key_file, "gui", "width", NULL);
449  gint height = g_key_file_get_integer(key_file, "gui", "height", NULL);
450  if (width && height)
451  {
452  ui_set_main_win_size(ui, width, height);
453  }
454 
455  gchar *browser_directory = g_key_file_get_string(key_file, "gui", "browser_directory", NULL);
456  if (browser_directory)
457  {
458  ui_set_browser_directory(ui, browser_directory);
459  g_free(browser_directory);
460  }
461 
462  g_key_file_free(key_file);
463  key_file = NULL;
464 }
465 
466 void save_preferences(ui_state *ui)
467 {
468  gchar *filename = get_preferences_filename();
469 
470  GKeyFile *my_key_file = g_key_file_new();
471  g_key_file_load_from_file(my_key_file, filename, G_KEY_FILE_KEEP_COMMENTS, NULL);
472 
473  //save_path
474  g_key_file_set_string(my_key_file, "split", "save_path", get_output_directory(ui));
475 
476  //player
477  g_key_file_set_integer(my_key_file, "player", "default_player", ui->infos->selected_player);
478 
479  pm_save(my_key_file, ui->preferences);
480 
481 #ifdef __WIN32__
482  GString *selected_lang = get_checked_language(ui);
483  g_key_file_set_string(my_key_file, "general", "language", selected_lang->str);
484  g_string_free(selected_lang, TRUE);
485  selected_lang = NULL;
486 #endif
487 
488  //frame mode
489  g_key_file_set_boolean(my_key_file, "split", "frame_mode",
490  gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ui->gui->frame_mode)));
491 
492  //adjust mode
493  g_key_file_set_boolean(my_key_file, "split", "adjust_mode",
494  gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ui->gui->adjust_mode)));
495 
496  //adjust threshold
497  g_key_file_set_integer(my_key_file, "split", "adjust_threshold",
498  gtk_spin_button_get_value(GTK_SPIN_BUTTON(ui->gui->spinner_adjust_threshold)) * 100);
499  //adjust offset
500  g_key_file_set_integer(my_key_file, "split", "adjust_offset",
501  gtk_spin_button_get_value(GTK_SPIN_BUTTON(ui->gui->spinner_adjust_offset)) * 100);
502  //adjust gap
503  g_key_file_set_integer(my_key_file, "split", "adjust_gap",
504  gtk_spin_button_get_value(GTK_SPIN_BUTTON(ui->gui->spinner_adjust_gap)));
505 
506  g_key_file_set_boolean(my_key_file, "output", "splitpoint_names_from_filename",
507  gtk_toggle_button_get_active(ui->gui->names_from_filename));
508 
509  //output format
510  g_key_file_set_string(my_key_file, "output", "output_format",
511  gtk_entry_get_text(GTK_ENTRY(ui->gui->output_entry)));
512  //default output format
513  g_key_file_set_boolean(my_key_file, "output", "default_output_format",
515  g_key_file_set_boolean(my_key_file, "output", "create_dirs_if_needed",
516  gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ui->gui->create_dirs_from_output_files)));
517 
518  //tags
519  g_key_file_set_integer(my_key_file, "split", "tags", rh_get_active_value(ui->gui->tags_radio));
520 
521  //replace underscores by space
522  g_key_file_set_boolean(my_key_file, "split", "replace_underscore_by_space",
523  gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ui->gui->replace_underscore_by_space_check_box)));
524 
525  //artist text properties
526  g_key_file_set_integer(my_key_file, "split", "artist_text_properties",
527  ch_get_active_value(ui->gui->artist_text_properties_combo));
528  //album text properties
529  g_key_file_set_integer(my_key_file, "split", "album_text_properties",
530  ch_get_active_value(ui->gui->album_text_properties_combo));
531  //title text properties
532  g_key_file_set_integer(my_key_file, "split", "title_text_properties",
533  ch_get_active_value(ui->gui->title_text_properties_combo));
534  //comment text properties
535  g_key_file_set_integer(my_key_file, "split", "comment_text_properties",
536  ch_get_active_value(ui->gui->comment_text_properties_combo));
537 
538  //genre
539  gchar *genre_value = ch_get_active_str_value(ui->gui->genre_combo);
540  if (genre_value != NULL)
541  {
542  g_key_file_set_string(my_key_file, "split", "genre", genre_value);
543  g_free(genre_value);
544  }
545 
546  const gchar *comment = gtk_entry_get_text(GTK_ENTRY(ui->gui->comment_tag_entry));
547  if (comment != NULL)
548  {
549  g_key_file_set_string(my_key_file, "split", "default_comment_tag", comment);
550  }
551 
552  const gchar *regex_text = gtk_entry_get_text(GTK_ENTRY(ui->gui->regex_entry));
553  if (regex_text != NULL)
554  {
555  g_key_file_set_string(my_key_file, "split", "tags_from_filename_regex", regex_text);
556  }
557 
558  const gchar *test_regex_fname = gtk_entry_get_text(GTK_ENTRY(ui->gui->test_regex_fname_entry));
559  if (test_regex_fname != NULL)
560  {
561  g_key_file_set_string(my_key_file, "split", "test_regex_fname", test_regex_fname);
562  }
563 
564  //tags version
565  g_key_file_set_integer(my_key_file, "split", "tags_version",
567 
568  //type of split: split mode
569  g_key_file_set_integer(my_key_file, "split", "split_mode", get_selected_split_mode_safe(ui));
570  //time value
571  g_key_file_set_integer(my_key_file, "split", "split_mode_time_value",
572  gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(ui->gui->spinner_time)));
573  //equal time tracks value
574  g_key_file_set_integer(my_key_file, "split", "split_mode_equal_time_tracks",
575  gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(ui->gui->spinner_equal_tracks)));
576 
577  const ui_main_window *main_win = ui_get_main_window_infos(ui);
578  g_key_file_set_integer(my_key_file, "gui", "root_x_position", main_win->root_x_pos);
579  g_key_file_set_integer(my_key_file, "gui", "root_y_position", main_win->root_y_pos);
580  g_key_file_set_integer(my_key_file, "gui", "width", main_win->width);
581  g_key_file_set_integer(my_key_file, "gui", "height", main_win->height);
582 
583  const char *browser_directory = ui_get_browser_directory(ui);
584  if (browser_directory != NULL)
585  {
586  g_key_file_set_string(my_key_file, "gui", "browser_directory", browser_directory);
587  }
588 
589  gchar *key_data = g_key_file_to_data(my_key_file, NULL, NULL);
590 
591  //we write to the preference file
592  FILE *preferences_file;
593  preferences_file = (FILE *)g_fopen(filename,"w");
594  g_fprintf(preferences_file,"%s", key_data);
595  fclose(preferences_file);
596  preferences_file = NULL;
597 
598  //we free memory
599  g_free(key_data);
600  g_key_file_free(my_key_file);
601 
602  if (filename)
603  {
604  g_free(filename);
605  filename = NULL;
606  }
607 }
608 
609 /* \brief writes a default configuration file
610 
611 Also is used to write good values on a bad existing configuration file
612 */
613 static void write_default_preferences_file(ui_state *ui)
614 {
615  gchar *filename = get_preferences_filename();
616 
617  GKeyFile *my_key_file = g_key_file_new();
618  g_key_file_load_from_file(my_key_file, filename, G_KEY_FILE_KEEP_COMMENTS, NULL);
619 
620 #ifdef __WIN32__
621  //default language
622  if (!g_key_file_has_key(my_key_file, "general", "language",NULL))
623  {
624  g_key_file_set_string(my_key_file, "general", "language", "en");
625  g_key_file_set_comment(my_key_file, "general", "language",
626  "\n language of the gui: en = english, fr = french, de = german", NULL);
627  }
628  //if we have the key, but we have ugly values
629  else
630  {
631  gchar *file_string = g_key_file_get_string(my_key_file, "general", "language", NULL);
632  GString * lang_char = g_string_new(file_string);
633 
634  if((!g_string_equal(lang_char,g_string_new("en")))
635  &&(!g_string_equal(lang_char, g_string_new("fr")))
636  &&(!g_string_equal(lang_char, g_string_new("fr_FR")))
637  &&(!g_string_equal(lang_char, g_string_new("de")))
638  &&(!g_string_equal(lang_char, g_string_new("de_DE")))
639  )
640  {
641  g_key_file_set_string(my_key_file, "general", "language", "en");
642  g_key_file_set_comment(my_key_file, "general", "language",
643  "\n language of the gui: en = english, fr_FR = french, de_DE = german", NULL);
644  }
645 
646  g_free(file_string);
647  g_string_free(lang_char, TRUE);
648  file_string = NULL;
649  lang_char = NULL;
650  }
651 #endif
652 
653  //frame mode
654  if (!g_key_file_has_key(my_key_file, "split", "frame_mode",NULL))
655  {
656  g_key_file_set_boolean(my_key_file, "split", "frame_mode", FALSE);
657  }
658 
659  //adjust mode
660  if (!g_key_file_has_key(my_key_file, "split", "adjust_mode",NULL))
661  {
662  g_key_file_set_boolean(my_key_file, "split", "adjust_mode", FALSE);
663  }
664 
665  gint item;
666  gfloat item2;
667  //adjust threshold
668  if (!g_key_file_has_key(my_key_file, "split", "adjust_threshold",NULL))
669  {
670  g_key_file_set_integer(my_key_file, "split", "adjust_threshold",
671  (int)(SPLT_DEFAULT_PARAM_THRESHOLD * 100));
672  }
673  //if we have the key but we have ugly values
674  else
675  {
676  item = g_key_file_get_integer(my_key_file, "split", "adjust_threshold", NULL);
677  //convert to float
678  item2 = item/100 + (item%100)/100.;
679 
680  if ((item2 < -96) || (item2 > 0))
681  {
682  g_key_file_set_integer(my_key_file, "split", "adjust_threshold",
683  (int)(SPLT_DEFAULT_PARAM_THRESHOLD * 100));
684  }
685  }
686 
687  //adjust offset
688  if (!g_key_file_has_key(my_key_file, "split", "adjust_offset",NULL))
689  {
690  g_key_file_set_integer(my_key_file, "split", "adjust_offset",
691  (int)(SPLT_DEFAULT_PARAM_OFFSET * 100));
692  }
693  //if we have the key but we have ugly values
694  else
695  {
696  item = g_key_file_get_integer(my_key_file, "split", "adjust_offset", NULL);
697  //convert to float
698  item2 = item/100 + (item%100)/100.;
699 
700  //if ugly values
701  if ((item2 < -2) || (item2 > 2))
702  {
703  g_key_file_set_integer(my_key_file, "split", "adjust_offset",
704  (int)(SPLT_DEFAULT_PARAM_OFFSET * 100));
705  }
706  }
707 
708  //adjust gap
709  if (!g_key_file_has_key(my_key_file, "split", "adjust_gap",NULL))
710  {
711  g_key_file_set_integer(my_key_file, "split", "adjust_gap", SPLT_DEFAULT_PARAM_GAP);
712  }
713  //if we have the key but we have ugly values
714  else
715  {
716  item = g_key_file_get_integer(my_key_file, "split", "adjust_gap", NULL);
717  if ((item < 0) || (item > 2000))
718  {
719  g_key_file_set_integer(my_key_file, "split", "adjust_gap", SPLT_DEFAULT_PARAM_GAP);
720  }
721  }
722 
723  //tags options
724  if (!g_key_file_has_key(my_key_file, "split", "tags",NULL))
725  {
726  g_key_file_set_integer(my_key_file, "split", "tags", 1);
727  g_key_file_set_comment(my_key_file, "split", "tags",
728  "\n 0 - No tags, 1 - Default tags, 2 - Original tags, 3 - Tags from filename", NULL);
729  }
730 
731  //tags version
732  if (!g_key_file_has_key(my_key_file, "split", "tags_version",NULL))
733  {
734  g_key_file_set_integer(my_key_file, "split", "tags_version", 0);
735  g_key_file_set_comment(my_key_file, "split", "tags_version",
736  "\n 0 - same tags version as the input file, 1 - ID3v1 tags,"
737  " 2 - ID3v2 tags, 3 - ID3v1 & ID3v2 tags",
738  NULL);
739  }
740 
741  //default player
742  if (!g_key_file_has_key(my_key_file, "player", "default_player",NULL))
743  {
744  g_key_file_set_integer(my_key_file, "player", "default_player",
745  PLAYER_GSTREAMER);
746  g_key_file_set_comment (my_key_file, "player", "default_player",
747  "\n 1 = PLAYER_AUDACIOUS, 2 = PLAYER_SNACKAMP, 3 = PLAYER_GSTREAMER",
748  NULL);
749  }
750  else
751  {
752  //check if we support selected player
753  gint the_player =
754  g_key_file_get_integer(my_key_file, "player", "default_player", NULL);
755  if (the_player == PLAYER_AUDACIOUS)
756  {
757 #ifdef NO_AUDACIOUS
758  g_key_file_set_integer(my_key_file, "player", "default_player", PLAYER_SNACKAMP);
759 #endif
760  }
761  //if the value do not make sense
762  else if ((the_player > PLAYER_GSTREAMER) || (the_player < 0))
763  {
764  g_key_file_set_integer(my_key_file, "player", "default_player",
765  PLAYER_GSTREAMER);
766  }
767  }
768 
769  pm_write_default(my_key_file, ui->preferences);
770 
771  //output format
772  if (!g_key_file_has_key(my_key_file, "output", "output_format",NULL))
773  {
774  g_key_file_set_string(my_key_file, "output", "output_format", SPLT_DEFAULT_OUTPUT);
775  g_key_file_set_comment (my_key_file, "output", "output_format",
776  "\n the output format, contains @a,"
777  "@b, @g, @p, @t and @n, see the program for"
778  " more details", NULL);
779  }
780 
781  //default output path boolean
782  if (!g_key_file_has_key(my_key_file, "output", "default_output_format",NULL))
783  {
784  g_key_file_set_boolean(my_key_file, "output", "default_output_format", TRUE);
785  g_key_file_set_comment(my_key_file, "output", "default_output_format",
786  "\n can be true or false"
787  " - if we use the default output or"
788  " not for cddb, cue and freedb search", NULL);
789  }
790 
791  //frame mode
792  if (!g_key_file_has_key(my_key_file, "output", "create_dirs_if_needed", NULL))
793  {
794  g_key_file_set_boolean(my_key_file, "output", "create_dirs_if_needed", TRUE);
795  }
796 
797  //split save path (output dir)
798  if (!g_key_file_has_key(my_key_file, "split", "save_path",NULL))
799  {
800 #ifdef __WIN32__
801  const gchar *home_dir = g_get_home_dir();
802  gint dir_malloc_number = strlen(home_dir)+ 10;
803  gchar *default_dir = malloc(dir_malloc_number*sizeof(gchar *));
804  g_snprintf(default_dir, dir_malloc_number, "%s\\Desktop",home_dir);
805 
806  //see if the directory exists
807  struct stat buffer;
808  gint status = g_stat(default_dir, &buffer);
809  if ((status == 0) && (S_ISDIR(buffer.st_mode) == 0))
810  {
811  g_snprintf(default_dir,dir_malloc_number, "%s",home_dir);
812  }
813 #else
814  const gchar *default_dir = g_get_home_dir();
815 #endif
816 
817  g_key_file_set_string(my_key_file, "split", "save_path", default_dir);
818  g_key_file_set_comment(my_key_file, "split", "save_path",
819  "\n this is the path where you will find your split files ",
820  NULL);
821 
822 #ifdef __WIN32__
823  g_free(default_dir);
824 #endif
825  }
826 
827  //type of split: split mode
828  if (!g_key_file_has_key(my_key_file, "split", "split_mode",NULL))
829  {
830  g_key_file_set_integer(my_key_file, "split", "split_mode", 3);
831  g_key_file_set_comment(my_key_file, "split", "split_mode",
832  "\n 0 - error mode, 1 - wrap mode, 2 - time mode, 3 - normal mode, 4 - equal time tracks",
833  NULL);
834  }
835 
836  //type of split: time value
837  if (!g_key_file_has_key(my_key_file, "split", "split_mode_time_value",NULL))
838  {
839  g_key_file_set_integer(my_key_file, "split", "split_mode_time_value", 60);
840  g_key_file_set_comment(my_key_file, "split", "split_mode_time_value",
841  "\n value in seconds to split every X seconds (for the time split)", NULL);
842  }
843 
844  //equal time tracks
845  if (!g_key_file_has_key(my_key_file, "split", "split_mode_equal_time_tracks",NULL))
846  {
847  g_key_file_set_integer(my_key_file, "split", "split_mode_equal_time_tracks", 10);
848  g_key_file_set_comment(my_key_file, "split", "split_mode_equal_time_tracks",
849  "\n number of tracks when to split in X tracks (for the equal time tracks split)", NULL);
850  }
851 
852  gchar *key_data = g_key_file_to_data(my_key_file, NULL, NULL);
853 
854  FILE *preferences_file = (FILE *)fopen(filename,"w");
855  g_fprintf(preferences_file,"%s", key_data);
856  fclose(preferences_file);
857 
858  if (filename)
859  {
860  g_free(filename);
861  }
862 
863  g_free(key_data);
864  g_key_file_free(my_key_file);
865 }
866 
871 static void check_pref_file_and_write_default(ui_state *ui)
872 {
873  gchar *pref_file = get_preferences_filename();
874 
875  struct stat buffer;
876  gint status = stat(pref_file, &buffer);
877  if ((status == 0) &&
878  (S_ISREG(buffer.st_mode) == 0) &&
879  (S_ISDIR(buffer.st_mode) != 0))
880  {
881  gint malloc_number = strlen(pref_file)+5;
882  gchar *backup_dir = malloc(malloc_number * sizeof(gchar *));
883  snprintf(backup_dir,malloc_number, "%s%s", pref_file, ".bak");
884  g_rename(pref_file, backup_dir);
885  g_free(backup_dir);
886  backup_dir = NULL;
887  }
888 
889  if (pref_file)
890  {
891  g_free(pref_file);
892  pref_file = NULL;
893  }
894 
895  write_default_preferences_file(ui);
896 }
897 
898 static void pm_free_spinner_int_preferences(GArray *spinner_int_preferences)
899 {
900  gint i = 0;
901  for (i = 0; i < spinner_int_preferences->len; i++)
902  {
903  spinner_int_preference preference =
904  g_array_index(spinner_int_preferences, spinner_int_preference, i);
905 
906  g_free(preference.main_key);
907  preference.main_key = NULL;
908 
909  g_free(preference.second_key);
910  preference.second_key = NULL;
911  }
912 
913  g_array_free(spinner_int_preferences, TRUE);
914 }
915 
916 static void pm_free_range_preferences(GArray *range_preferences)
917 {
918  gint i = 0;
919  for (i = 0; i < range_preferences->len; i++)
920  {
921  spinner_int_preference preference =
922  g_array_index(range_preferences, spinner_int_preference, i);
923 
924  g_free(preference.main_key);
925  preference.main_key = NULL;
926 
927  g_free(preference.second_key);
928  preference.second_key = NULL;
929  }
930 
931  g_array_free(range_preferences, TRUE);
932 }
933 
934 static void pm_load_spinner_int_preferences(GKeyFile *key_file, preferences_state *pm)
935 {
936  GArray *spinner_int_preferences = pm->spinner_int_preferences;
937 
938  gint i = 0;
939  for (i = 0; i < spinner_int_preferences->len; i++)
940  {
941  spinner_int_preference preference =
942  g_array_index(spinner_int_preferences, spinner_int_preference, i);
943 
944  gint value =
945  g_key_file_get_integer(key_file, preference.main_key, preference.second_key, NULL);
946  gtk_spin_button_set_value(GTK_SPIN_BUTTON(preference.spinner), value);
947  preference.update_spinner_value_cb(preference.spinner, preference.user_data_for_cb);
948  }
949 }
950 
951 static void pm_save_spinner_int_preferences(GKeyFile *key_file, preferences_state *pm)
952 {
953  GArray *spinner_int_preferences = pm->spinner_int_preferences;
954 
955  gint i = 0;
956  for (i = 0; i < spinner_int_preferences->len; i++)
957  {
958  spinner_int_preference preference =
959  g_array_index(spinner_int_preferences, spinner_int_preference, i);
960 
961  g_key_file_set_integer(key_file, preference.main_key, preference.second_key,
962  gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(preference.spinner)));
963  }
964 }
965 
966 static void pm_write_default_spinner_int_preferences(GKeyFile *key_file, preferences_state *pm)
967 {
968  GArray *spinner_int_preferences = pm->spinner_int_preferences;
969 
970  gint i = 0;
971  for (i = 0; i < spinner_int_preferences->len; i++)
972  {
973  spinner_int_preference preference =
974  g_array_index(spinner_int_preferences, spinner_int_preference, i);
975 
976  if (!g_key_file_has_key(key_file, preference.main_key, preference.second_key, NULL))
977  {
978  g_key_file_set_integer(key_file, preference.main_key, preference.second_key,
979  preference.default_value);
980  }
981  }
982 }
983 
984 static void pm_load_range_preferences(GKeyFile *key_file, preferences_state *pm)
985 {
986  GArray *range_preferences = pm->range_preferences;
987 
988  gint i = 0;
989  for (i = 0; i < range_preferences->len; i++)
990  {
991  range_preference preference = g_array_index(range_preferences, range_preference, i);
992 
993  gint value =
994  g_key_file_get_integer(key_file, preference.main_key, preference.second_key, NULL);
995 
996  gtk_range_set_value(GTK_RANGE(preference.range), value);
997  GtkAdjustment *adj = gtk_range_get_adjustment(GTK_RANGE(preference.range));
998  preference.update_adjustment_value(adj, preference.user_data_for_cb);
999  }
1000 }
1001 
1002 static void pm_save_range_preferences(GKeyFile *key_file, preferences_state *pm)
1003 {
1004  GArray *range_preferences = pm->range_preferences;
1005 
1006  gint i = 0;
1007  for (i = 0; i < range_preferences->len; i++)
1008  {
1009  range_preference preference = g_array_index(range_preferences, range_preference, i);
1010 
1011  GtkAdjustment *adj = gtk_range_get_adjustment(GTK_RANGE(preference.range));
1012  g_key_file_set_integer(key_file, preference.main_key, preference.second_key,
1013  (gint)gtk_adjustment_get_value(adj));
1014  }
1015 }
1016 
1017 static void pm_write_default_range_preferences(GKeyFile *key_file, preferences_state *pm)
1018 {
1019  GArray *range_preferences = pm->range_preferences;
1020 
1021  gint i = 0;
1022  for (i = 0; i < range_preferences->len; i++)
1023  {
1024  range_preference preference = g_array_index(range_preferences, range_preference, i);
1025 
1026  if (!g_key_file_has_key(key_file, preference.main_key, preference.second_key, NULL))
1027  {
1028  g_key_file_set_integer(key_file, preference.main_key, preference.second_key,
1029  preference.default_value);
1030  }
1031  }
1032 }
1033