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