1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
4 * Copyright (C) John Stebbins 2008 <stebbins@stebbins>
6 * presets.c is free software.
8 * You may redistribute it and/or modify it under the terms of the
9 * GNU General Public License, as published by the Free Software
10 * Foundation; either version 2 of the License, or (at your option)
15 #include <glib-object.h>
16 #include <glib/gstdio.h>
25 // Internal defaults stored in character arrays and parsed
26 // the same as external settings files.
27 const gchar defaultSettings[] =
28 #include "internal_defaults.h"
30 const gchar standardPresets[] =
31 #include "standard_presets.h"
34 static GValue *presetsPlist = NULL;
35 static GValue *internalPlist = NULL;
36 static GValue *prefsPlist = NULL;
39 plist_get_dict(GValue *presets, const gchar *name)
41 if (presets == NULL || name == NULL) return NULL;
42 return ghb_dict_lookup(presets, name);
46 ghb_set_preset_default(GValue *settings)
50 preset = ghb_settings_get_string (settings, "preset");
51 ghb_settings_set_string(settings, "default_preset", preset);
52 ghb_prefs_save(settings);
56 // Used for sorting dictionaries.
58 key_cmp(gconstpointer a, gconstpointer b)
60 gchar *stra = (gchar*)a;
61 gchar *strb = (gchar*)b;
63 return strcmp(stra, strb);
67 ghb_presets_get_description(const gchar *name)
70 pdict = plist_get_dict(presetsPlist, name);
71 if (pdict == NULL) return g_strdup("");
72 return ghb_value_string(ghb_dict_lookup(pdict, "preset_description"));
76 preset_dict_get_value(
80 const GValue *gval = NULL;
84 gval = ghb_dict_lookup(dict, key);
86 if (internalPlist == NULL) return NULL;
89 dict = plist_get_dict(internalPlist, "Presets");
90 if (dict == NULL) return NULL;
91 gval = ghb_dict_lookup(dict, key);
103 dict = plist_get_dict(presetsPlist, name);
104 return preset_dict_get_value(dict, key);
108 ghb_presets_get_names()
112 GList *standard = NULL;
113 GList *custom = NULL;
115 if (presetsPlist == NULL) return NULL;
116 dict = g_value_get_boxed(presetsPlist);
117 link = names = g_hash_table_get_keys(dict);
123 name = (gchar*)link->data;
124 ptype = ghb_value_int(preset_get_value(name, "preset_type"));
126 custom = g_list_append(custom, name);
128 standard = g_list_append(standard, name);
131 custom = g_list_sort(custom, key_cmp);
132 standard = g_list_sort(standard, key_cmp);
134 names = g_list_concat(standard, custom);
139 ghb_preset_flags(const gchar *name)
146 dict = plist_get_dict(presetsPlist, name);
147 gval = preset_dict_get_value(dict, "preset_type");
150 ptype = ghb_value_int(gval);
151 ret = (ptype != 0 ? PRESET_CUSTOM : 0);
156 static void init_settings_from_dict(
157 GValue *dest, GValue *internal, GValue *dict);
160 init_settings_from_array(
168 count = ghb_array_len(array);
169 // The first element of the internal version is always the
170 // template for the allowed values
171 gval = ghb_array_get_nth(internal, 0);
172 for (ii = 0; ii < count; ii++)
175 val = ghb_array_get_nth(array, ii);
178 if (G_VALUE_TYPE(gval) == ghb_dict_get_type())
181 new_dict = ghb_dict_value_new();
182 ghb_array_append(dest, new_dict);
183 if (G_VALUE_TYPE(val) == ghb_dict_get_type())
184 init_settings_from_dict(new_dict, gval, val);
186 init_settings_from_dict(new_dict, gval, gval);
188 else if (G_VALUE_TYPE(gval) == ghb_array_get_type())
191 new_array = ghb_array_value_new(8);
192 ghb_array_append(dest, new_array);
193 if (G_VALUE_TYPE(val) == ghb_array_get_type())
194 init_settings_from_array(new_array, gval, val);
196 init_settings_from_array(new_array, gval, gval);
200 ghb_array_append(dest, val);
206 init_settings_from_dict(
215 ghb_dict_iter_init(&iter, internal);
216 // middle (void*) cast prevents gcc warning "defreferencing type-punned
217 // pointer will break strict-aliasing rules"
218 while (g_hash_table_iter_next(
219 &iter, (gpointer*)(void*)&key, (gpointer*)(void*)&gval))
223 val = ghb_dict_lookup(dict, key);
226 if (G_VALUE_TYPE(gval) == ghb_dict_get_type())
229 new_dict = ghb_dict_value_new();
230 ghb_settings_take_value(dest, key, new_dict);
231 if (G_VALUE_TYPE(val) == ghb_dict_get_type())
232 init_settings_from_dict(new_dict, gval, val);
234 init_settings_from_dict(new_dict, gval, gval);
236 else if (G_VALUE_TYPE(gval) == ghb_array_get_type())
239 new_array = ghb_array_value_new(8);
240 ghb_settings_take_value(dest, key, new_array);
241 if (G_VALUE_TYPE(val) == ghb_array_get_type())
242 init_settings_from_array(new_array, gval, val);
244 init_settings_from_array(new_array, gval, gval);
249 ghb_settings_set_value(dest, key, val);
256 signal_user_data_t *ud,
264 ghb_dict_iter_init(&iter, internal);
265 // middle (void*) cast prevents gcc warning "defreferencing type-punned
266 // pointer will break strict-aliasing rules"
267 while (g_hash_table_iter_next(
268 &iter, (gpointer*)(void*)&key, (gpointer*)(void*)&gval))
272 val = ghb_dict_lookup(dict, key);
275 ghb_ui_update(ud, key, val);
280 preset_to_ui(signal_user_data_t *ud, GValue *dict)
282 g_debug("preset_to_ui()\n");
283 // Initialize the ui from presets file.
286 // Get key list from internal default presets. This way we do not
287 // load any unknown keys.
288 if (internalPlist == NULL) return;
289 internal = plist_get_dict(internalPlist, "Presets");
290 // Setting a ui widget will cause the corresponding setting
291 // to be set, but it also triggers a callback that can
292 // have the side effect of using other settings values
293 // that have not yet been set. So set *all* settings first
294 // then update the ui.
295 init_settings_from_dict(ud->settings, internal, dict);
296 init_ui_from_dict(ud, internal, dict);
298 if (ghb_settings_get_boolean(ud->settings, "allow_tweaks"))
301 gval = preset_dict_get_value(dict, "deinterlace");
304 ghb_ui_update(ud, "tweak_deinterlace", gval);
306 gval = preset_dict_get_value(dict, "denoise");
309 ghb_ui_update(ud, "tweak_denoise", gval);
315 ghb_set_preset(signal_user_data_t *ud, const gchar *name)
319 g_debug("ghb_set_preset() %s\n", name);
323 // Try to get the first preset
324 presets = ghb_presets_get_names();
327 name = (const gchar*)presets->data;
328 g_list_free(presets);
331 dict = plist_get_dict(presetsPlist, name);
332 if (dict == NULL || name == NULL)
334 preset_to_ui(ud, NULL);
338 preset_to_ui(ud, dict);
339 ghb_settings_set_string(ud->settings, "preset", name);
344 ghb_update_from_preset(
345 signal_user_data_t *ud,
351 g_debug("ghb_update_from_preset() %s %s", name, key);
352 if (name == NULL) return;
353 gval = preset_get_value(name, key);
356 ghb_ui_update(ud, key, gval);
361 store_plist(GValue *plist, const gchar *name)
367 dir = g_get_user_config_dir();
368 config = g_strdup_printf ("%s/ghb", dir);
369 if (!g_file_test(config, G_FILE_TEST_IS_DIR))
371 g_mkdir (config, 0755);
374 config = g_strdup_printf ("%s/ghb/%s", dir, name);
375 file = g_fopen(config, "w");
377 ghb_plist_write(file, plist);
382 load_plist(const gchar *name)
387 GValue *plist = NULL;
389 dir = g_get_user_config_dir();
390 config = g_strdup_printf ("%s/ghb/%s", dir, name);
391 if (g_file_test(config, G_FILE_TEST_IS_REGULAR))
393 file = g_fopen(config, "r");
394 plist = ghb_plist_parse_file(file);
401 remove_plist(const gchar *name)
406 dir = g_get_user_config_dir();
407 config = g_strdup_printf ("%s/ghb/%s", dir, name);
408 if (g_file_test(config, G_FILE_TEST_IS_REGULAR))
415 static gboolean prefs_initializing = FALSE;
418 ghb_prefs_to_ui(signal_user_data_t *ud)
423 GValue *internal, *dict;
427 prefs_initializing = TRUE;
429 // Setting a ui widget will cause the corresponding setting
430 // to be set, but it also triggers a callback that can
431 // have the side effect of using other settings values
432 // that have not yet been set. So set *all* settings first
433 // then update the ui.
434 internal = plist_get_dict(internalPlist, "Initialization");
435 ghb_dict_iter_init(&iter, internal);
436 // middle (void*) cast prevents gcc warning "defreferencing type-punned
437 // pointer will break strict-aliasing rules"
438 while (g_hash_table_iter_next(
439 &iter, (gpointer*)(void*)&key, (gpointer*)(void*)&gval))
441 ghb_ui_update(ud, key, gval);
444 dict = plist_get_dict(prefsPlist, "Preferences");
445 internal = plist_get_dict(internalPlist, "Preferences");
446 ghb_dict_iter_init(&iter, internal);
447 // middle (void*) cast prevents gcc warning "defreferencing type-punned
448 // pointer will break strict-aliasing rules"
449 while (g_hash_table_iter_next(
450 &iter, (gpointer*)(void*)&key, (gpointer*)(void*)&gval))
452 const GValue *value = NULL;
454 value = ghb_dict_lookup(dict, key);
457 ghb_settings_set_value(ud->settings, key, value);
459 internal = plist_get_dict(internalPlist, "Preferences");
460 ghb_dict_iter_init(&iter, internal);
461 // middle (void*) cast prevents gcc warning "defreferencing type-punned
462 // pointer will break strict-aliasing rules"
463 while (g_hash_table_iter_next(
464 &iter, (gpointer*)(void*)&key, (gpointer*)(void*)&gval))
466 const GValue *value = NULL;
468 value = ghb_dict_lookup(dict, key);
471 ghb_ui_update(ud, key, value);
474 val = ghb_settings_get_value(ud->settings, "show_presets");
475 ghb_ui_update(ud, "show_presets", val);
476 if (ghb_settings_get_boolean(ud->settings, "hbfd_feature"))
479 val = ghb_settings_get_value(ud->settings, "hbfd");
480 ghb_ui_update(ud, "hbfd", val);
481 action = GHB_ACTION (ud->builder, "hbfd");
482 gtk_action_set_visible(action, TRUE);
486 ghb_ui_update(ud, "hbfd", ghb_int64_value(0));
488 gval = ghb_settings_get_value(ud->settings, "default_source");
489 ghb_settings_set_value (ud->settings, "source", gval);
490 str = ghb_settings_get_string(ud->settings, "destination_dir");
492 gchar *path = g_strdup_printf ("%s/new_video.mp4", str);
493 ghb_ui_update(ud, "destination", ghb_string_value(path));
497 prefs_initializing = FALSE;
501 ghb_prefs_save(GValue *settings)
509 if (prefs_initializing) return;
510 dict = plist_get_dict(internalPlist, "Preferences");
511 if (dict == NULL) return;
512 pref_dict = plist_get_dict(prefsPlist, "Preferences");
513 if (pref_dict == NULL) return;
514 ghb_dict_iter_init(&iter, dict);
515 // middle (void*) cast prevents gcc warning "defreferencing type-punned
516 // pointer will break strict-aliasing rules"
517 while (g_hash_table_iter_next(
518 &iter, (gpointer*)(void*)&key, (gpointer*)(void*)&value))
520 value = ghb_settings_get_value(settings, key);
523 ghb_dict_insert(pref_dict, g_strdup(key), ghb_value_dup(value));
526 store_plist(prefsPlist, "preferences");
530 ghb_pref_save(GValue *settings, const gchar *key)
534 if (prefs_initializing) return;
535 value = ghb_settings_get_value(settings, key);
539 dict = plist_get_dict(prefsPlist, "Preferences");
540 if (dict == NULL) return;
541 ghb_dict_insert(dict, g_strdup(key), ghb_value_dup(value));
542 store_plist(prefsPlist, "preferences");
547 ghb_settings_init(signal_user_data_t *ud)
555 g_debug("ghb_settings_init");
556 prefs_initializing = TRUE;
558 internalPlist = ghb_plist_parse(defaultSettings, sizeof(defaultSettings)-1);
559 // Setting a ui widget will cause the corresponding setting
560 // to be set, but it also triggers a callback that can
561 // have the side effect of using other settings values
562 // that have not yet been set. So set *all* settings first
563 // then update the ui.
564 internal = plist_get_dict(internalPlist, "Initialization");
565 ghb_dict_iter_init(&iter, internal);
566 // middle (void*) cast prevents gcc warning "defreferencing type-punned
567 // pointer will break strict-aliasing rules"
568 while (g_hash_table_iter_next(
569 &iter, (gpointer*)(void*)&key, (gpointer*)(void*)&gval))
571 ghb_settings_set_value(ud->settings, key, gval);
574 internal = plist_get_dict(internalPlist, "Presets");
575 ghb_dict_iter_init(&iter, internal);
576 // middle (void*) cast prevents gcc warning "defreferencing type-punned
577 // pointer will break strict-aliasing rules"
578 while (g_hash_table_iter_next(
579 &iter, (gpointer*)(void*)&key, (gpointer*)(void*)&gval))
581 ghb_settings_set_value(ud->settings, key, gval);
584 internal = plist_get_dict(internalPlist, "Preferences");
585 ghb_dict_iter_init(&iter, internal);
586 // middle (void*) cast prevents gcc warning "defreferencing type-punned
587 // pointer will break strict-aliasing rules"
588 while (g_hash_table_iter_next(
589 &iter, (gpointer*)(void*)&key, (gpointer*)(void*)&gval))
591 ghb_settings_set_value(ud->settings, key, gval);
593 prefs_initializing = FALSE;
597 ghb_prefs_load(signal_user_data_t *ud)
599 GValue *dict, *internal;
604 g_debug("ghb_prefs_load");
605 prefsPlist = load_plist("preferences");
606 if (prefsPlist == NULL)
607 prefsPlist = ghb_dict_value_new();
608 dict = plist_get_dict(prefsPlist, "Preferences");
609 internal = plist_get_dict(internalPlist, "Preferences");
610 if (dict == NULL && internal)
612 dict = ghb_dict_value_new();
613 ghb_dict_insert(prefsPlist, g_strdup("Preferences"), dict);
615 // Get defaults from internal defaults
616 ghb_dict_iter_init(&iter, internal);
617 // middle (void*) cast prevents gcc warning "defreferencing type-punned
618 // pointer will break strict-aliasing rules"
619 while (g_hash_table_iter_next(
620 &iter, (gpointer*)(void*)&key, (gpointer*)(void*)&gval))
622 ghb_dict_insert(dict, g_strdup(key), ghb_value_dup(gval));
624 const gchar *dir = g_get_user_special_dir (G_USER_DIRECTORY_VIDEOS);
629 ghb_dict_insert(dict,
630 g_strdup("destination_dir"), ghb_value_dup(ghb_string_value(dir)));
631 store_plist(prefsPlist, "preferences");
636 ghb_presets_reload(signal_user_data_t *ud)
638 GValue *std_dict, *dict;
639 GHashTableIter std_iter;
641 g_debug("ghb_presets_reload()\n");
642 std_dict = ghb_plist_parse(standardPresets, sizeof(standardPresets)-1);
643 if (std_dict == NULL) return;
645 // Merge the keyfile contents into our presets
649 ghb_dict_iter_init(&std_iter, std_dict);
650 // middle (void*) cast prevents gcc warning "defreferencing type-punned
651 // pointer will break strict-aliasing rules"
652 while (g_hash_table_iter_next(
653 &std_iter, (gpointer*)(void*)&name, (gpointer*)(void*)&orig_dict))
659 dict = ghb_dict_value_new();
660 ghb_dict_insert(presetsPlist, g_strdup(name), dict);
661 ghb_dict_iter_init(&iter, orig_dict);
662 // middle (void*) cast prevents gcc warning "defreferencing type-punned
663 // pointer will break strict-aliasing rules"
664 while (g_hash_table_iter_next(
665 &iter, (gpointer*)(void*)&key, (gpointer*)(void*)&value))
667 ghb_dict_insert(dict, g_strdup(key), ghb_value_dup(value));
670 ghb_value_free(std_dict);
671 store_plist(presetsPlist, "presets");
677 g_debug("presets_store ()\n");
678 store_plist(presetsPlist, "presets");
682 ghb_save_queue(GValue *queue)
684 store_plist(queue, "queue");
690 return load_plist("queue");
694 ghb_remove_queue_file()
696 remove_plist("queue");
702 presetsPlist = load_plist("presets");
703 if (presetsPlist == NULL)
705 presetsPlist = ghb_plist_parse(
706 standardPresets, sizeof(standardPresets)-1);
712 ghb_settings_save(signal_user_data_t *ud, const gchar *name)
714 GValue *dict, *internal;
720 if (internalPlist == NULL) return;
721 if (ghb_settings_get_boolean(ud->settings, "allow_tweaks"))
724 str = ghb_settings_get_string(ud->settings, "tweak_deinterlace");
727 ghb_settings_set_string(ud->settings, "deinterlace", str);
730 str = ghb_settings_get_string(ud->settings, "tweak_denoise");
733 ghb_settings_set_string(ud->settings, "denoise", str);
737 autoscale = ghb_settings_get_boolean(ud->settings, "autoscale");
738 ghb_settings_set_int64(ud->settings, "preset_type", 1);
740 dict = ghb_dict_value_new();
741 ghb_dict_insert(presetsPlist, g_strdup(name), dict);
742 internal = plist_get_dict(internalPlist, "Presets");
744 ghb_dict_iter_init(&iter, internal);
745 // middle (void*) cast prevents gcc warning "defreferencing type-punned
746 // pointer will break strict-aliasing rules"
747 while (g_hash_table_iter_next(
748 &iter, (gpointer*)(void*)&key, (gpointer*)(void*)&value))
752 if (strcmp(key, "scale_width"))
756 if (strcmp(key, "scale_height"))
762 gval = ghb_settings_get_value(ud->settings, key);
765 g_debug("Setting (%s) is not in defaults\n", (gchar*)key);
768 if (ghb_value_cmp(gval, value) != 0)
770 // Differs from default value. Store it.
771 ghb_dict_insert(dict, g_strdup(key), ghb_value_dup(gval));
775 ud->dont_clear_presets = TRUE;
776 ghb_set_preset (ud, name);
777 ud->dont_clear_presets = FALSE;
781 ghb_presets_remove(const gchar *name)
783 if (ghb_dict_lookup(presetsPlist, name))
785 ghb_dict_remove(presetsPlist, name);