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>
20 #include "audiohandler.h"
21 #include "hb-backend.h"
23 #include "resources.h"
27 static GValue *presetsPlist = NULL;
28 static GValue *internalPlist = NULL;
29 static GValue *prefsPlist = NULL;
31 static const GValue* preset_dict_get_value(GValue *dict, const gchar *key);
34 plist_get_dict(GValue *presets, const gchar *name)
36 if (presets == NULL || name == NULL) return NULL;
37 return ghb_dict_lookup(presets, name);
41 preset_get_name(GValue *dict)
43 return g_value_get_string(ghb_dict_lookup(dict, "preset_name"));
47 presets_get_first_dict(GValue *presets)
50 gint count, ii, ptype;
52 if (presets == NULL) return NULL;
53 count = ghb_array_len(presets);
54 for (ii = 0; ii < count; ii++)
56 dict = ghb_array_get_nth(presets, ii);
57 ptype = ghb_value_int(preset_dict_get_value(dict, "preset_type"));
65 presets_get_dict(GValue *presets, const gchar *name)
70 if (presets == NULL || name == NULL) return NULL;
71 count = ghb_array_len(presets);
72 for (ii = 0; ii < count; ii++)
75 dict = ghb_array_get_nth(presets, ii);
76 str = preset_get_name(dict);
77 if (strcmp(str, name) == 0)
84 presets_remove(GValue *presets, const gchar *name)
89 if (presets == NULL || name == NULL) return -1;
90 count = ghb_array_len(presets);
91 for (ii = 0; ii < count; ii++)
94 dict = ghb_array_get_nth(presets, ii);
95 str = preset_get_name(dict);
96 if (strcmp(str, name) == 0)
98 ghb_array_remove(presets, ii);
106 presets_find_pos(GValue *presets, const gchar *name, gint type)
109 gint count, ii, ptype, last;
111 if (presets == NULL || name == NULL) return -1;
112 last = count = ghb_array_len(presets);
113 for (ii = 0; ii < count; ii++)
116 dict = ghb_array_get_nth(presets, ii);
117 str = preset_get_name(dict);
118 ptype = ghb_value_int(preset_dict_get_value(dict, "preset_type"));
119 if (strcasecmp(name, str) < 0 && ptype == type)
130 ghb_set_preset_default(GValue *settings)
134 preset = ghb_settings_get_string (settings, "preset");
135 ghb_settings_set_string(settings, "default_preset", preset);
136 ghb_prefs_save(settings);
140 // Used for sorting dictionaries.
142 key_cmp(gconstpointer a, gconstpointer b)
144 gchar *stra = (gchar*)a;
145 gchar *strb = (gchar*)b;
147 return strcmp(stra, strb);
151 ghb_presets_get_description(GValue *pdict)
153 if (pdict == NULL) return g_strdup("");
154 return g_value_get_string(ghb_dict_lookup(pdict, "preset_description"));
158 preset_dict_get_value(GValue *dict, const gchar *key)
160 const GValue *gval = NULL;
164 gval = ghb_dict_lookup(dict, key);
166 if (internalPlist == NULL) return NULL;
169 dict = plist_get_dict(internalPlist, "Presets");
170 if (dict == NULL) return NULL;
171 gval = ghb_dict_lookup(dict, key);
177 preset_get_value(const gchar *name, const gchar *key)
181 dict = presets_get_dict(presetsPlist, name);
182 return preset_dict_get_value(dict, key);
186 ghb_preset_flags(GValue *dict)
192 gval = preset_dict_get_value(dict, "preset_type");
195 ptype = ghb_value_int(gval);
196 ret = (ptype != 0 ? PRESET_CUSTOM : 0);
201 static void init_settings_from_dict(
202 GValue *dest, GValue *internal, GValue *dict);
205 init_settings_from_array(
213 count = ghb_array_len(array);
214 // The first element of the internal version is always the
215 // template for the allowed values
216 gval = ghb_array_get_nth(internal, 0);
217 for (ii = 0; ii < count; ii++)
220 val = ghb_array_get_nth(array, ii);
223 if (G_VALUE_TYPE(gval) == ghb_dict_get_type())
226 new_dict = ghb_dict_value_new();
227 ghb_array_append(dest, new_dict);
228 if (G_VALUE_TYPE(val) == ghb_dict_get_type())
229 init_settings_from_dict(new_dict, gval, val);
231 init_settings_from_dict(new_dict, gval, gval);
233 else if (G_VALUE_TYPE(gval) == ghb_array_get_type())
236 new_array = ghb_array_value_new(8);
237 ghb_array_append(dest, new_array);
238 if (G_VALUE_TYPE(val) == ghb_array_get_type())
239 init_settings_from_array(new_array, gval, val);
241 init_settings_from_array(new_array, gval, gval);
245 ghb_array_append(dest, val);
251 init_settings_from_dict(
260 ghb_dict_iter_init(&iter, internal);
261 // middle (void*) cast prevents gcc warning "defreferencing type-punned
262 // pointer will break strict-aliasing rules"
263 while (g_hash_table_iter_next(
264 &iter, (gpointer*)(void*)&key, (gpointer*)(void*)&gval))
268 val = ghb_dict_lookup(dict, key);
271 if (G_VALUE_TYPE(gval) == ghb_dict_get_type())
274 new_dict = ghb_dict_value_new();
275 ghb_settings_take_value(dest, key, new_dict);
276 if (G_VALUE_TYPE(val) == ghb_dict_get_type())
277 init_settings_from_dict(new_dict, gval, val);
279 init_settings_from_dict(new_dict, gval, gval);
281 else if (G_VALUE_TYPE(gval) == ghb_array_get_type())
284 new_array = ghb_array_value_new(8);
285 ghb_settings_take_value(dest, key, new_array);
286 if (G_VALUE_TYPE(val) == ghb_array_get_type())
287 init_settings_from_array(new_array, gval, val);
289 init_settings_from_array(new_array, gval, gval);
294 ghb_settings_set_value(dest, key, val);
301 signal_user_data_t *ud,
309 ghb_dict_iter_init(&iter, internal);
310 // middle (void*) cast prevents gcc warning "defreferencing type-punned
311 // pointer will break strict-aliasing rules"
312 while (g_hash_table_iter_next(
313 &iter, (gpointer*)(void*)&key, (gpointer*)(void*)&gval))
317 val = ghb_dict_lookup(dict, key);
320 ghb_ui_update(ud, key, val);
325 preset_to_ui(signal_user_data_t *ud, GValue *dict)
327 g_debug("preset_to_ui()\n");
328 // Initialize the ui from presets file.
331 // Get key list from internal default presets. This way we do not
332 // load any unknown keys.
333 if (internalPlist == NULL) return;
334 internal = plist_get_dict(internalPlist, "Presets");
335 // Setting a ui widget will cause the corresponding setting
336 // to be set, but it also triggers a callback that can
337 // have the side effect of using other settings values
338 // that have not yet been set. So set *all* settings first
339 // then update the ui.
340 init_settings_from_dict(ud->settings, internal, dict);
341 init_ui_from_dict(ud, internal, dict);
343 if (ghb_settings_get_boolean(ud->settings, "allow_tweaks"))
346 gval = preset_dict_get_value(dict, "deinterlace");
349 ghb_ui_update(ud, "tweak_deinterlace", gval);
351 gval = preset_dict_get_value(dict, "denoise");
354 ghb_ui_update(ud, "tweak_denoise", gval);
360 ghb_settings_to_ui(signal_user_data_t *ud, GValue *dict)
362 init_ui_from_dict(ud, dict, dict);
366 ghb_set_preset(signal_user_data_t *ud, const gchar *name)
370 g_debug("ghb_set_preset() %s\n", name);
373 dict = presets_get_first_dict(presetsPlist);
374 name = preset_get_name(dict);
378 dict = presets_get_dict(presetsPlist, name);
380 if (dict == NULL || name == NULL)
382 preset_to_ui(ud, NULL);
386 preset_to_ui(ud, dict);
387 ghb_settings_set_string(ud->settings, "preset", name);
392 ghb_update_from_preset(
393 signal_user_data_t *ud,
399 g_debug("ghb_update_from_preset() %s %s", name, key);
400 if (name == NULL) return;
401 gval = preset_get_value(name, key);
404 ghb_ui_update(ud, key, gval);
409 ghb_get_user_config_dir()
414 dir = g_get_user_config_dir();
415 if (!g_file_test(dir, G_FILE_TEST_IS_DIR))
417 dir = g_get_home_dir();
418 config = g_strdup_printf ("%s/.ghb", dir);
419 if (!g_file_test(config, G_FILE_TEST_IS_DIR))
420 g_mkdir (config, 0755);
424 config = g_strdup_printf ("%s/ghb", dir);
425 if (!g_file_test(config, G_FILE_TEST_IS_DIR))
426 g_mkdir (config, 0755);
432 store_plist(GValue *plist, const gchar *name)
434 gchar *config, *path;
437 config = ghb_get_user_config_dir();
438 path = g_strdup_printf ("%s/%s", config, name);
439 file = g_fopen(path, "w");
442 ghb_plist_write(file, plist);
447 load_plist(const gchar *name)
449 gchar *config, *path;
450 GValue *plist = NULL;
452 config = ghb_get_user_config_dir();
453 path = g_strdup_printf ("%s/%s", config, name);
454 if (g_file_test(path, G_FILE_TEST_IS_REGULAR))
456 plist = ghb_plist_parse_file(path);
464 remove_plist(const gchar *name)
466 gchar *config, *path;
468 config = ghb_get_user_config_dir();
469 path = g_strdup_printf ("%s/%s", config, name);
470 if (g_file_test(path, G_FILE_TEST_IS_REGULAR))
478 static gboolean prefs_initializing = FALSE;
481 ghb_prefs_to_ui(signal_user_data_t *ud)
486 GValue *internal, *dict;
490 prefs_initializing = TRUE;
492 // Setting a ui widget will cause the corresponding setting
493 // to be set, but it also triggers a callback that can
494 // have the side effect of using other settings values
495 // that have not yet been set. So set *all* settings first
496 // then update the ui.
497 internal = plist_get_dict(internalPlist, "Initialization");
498 ghb_dict_iter_init(&iter, internal);
499 // middle (void*) cast prevents gcc warning "defreferencing type-punned
500 // pointer will break strict-aliasing rules"
501 while (g_hash_table_iter_next(
502 &iter, (gpointer*)(void*)&key, (gpointer*)(void*)&gval))
504 ghb_ui_update(ud, key, gval);
507 dict = plist_get_dict(prefsPlist, "Preferences");
508 internal = plist_get_dict(internalPlist, "Preferences");
509 ghb_dict_iter_init(&iter, internal);
510 // middle (void*) cast prevents gcc warning "defreferencing type-punned
511 // pointer will break strict-aliasing rules"
512 while (g_hash_table_iter_next(
513 &iter, (gpointer*)(void*)&key, (gpointer*)(void*)&gval))
515 const GValue *value = NULL;
517 value = ghb_dict_lookup(dict, key);
520 ghb_settings_set_value(ud->settings, key, value);
522 internal = plist_get_dict(internalPlist, "Preferences");
523 ghb_dict_iter_init(&iter, internal);
524 // middle (void*) cast prevents gcc warning "defreferencing type-punned
525 // pointer will break strict-aliasing rules"
526 while (g_hash_table_iter_next(
527 &iter, (gpointer*)(void*)&key, (gpointer*)(void*)&gval))
529 const GValue *value = NULL;
531 value = ghb_dict_lookup(dict, key);
534 ghb_ui_update(ud, key, value);
537 val = ghb_settings_get_value(ud->settings, "show_presets");
538 ghb_ui_update(ud, "show_presets", val);
539 if (ghb_settings_get_boolean(ud->settings, "hbfd_feature"))
542 val = ghb_settings_get_value(ud->settings, "hbfd");
543 ghb_ui_update(ud, "hbfd", val);
544 action = GHB_ACTION (ud->builder, "hbfd");
545 gtk_action_set_visible(action, TRUE);
549 ghb_ui_update(ud, "hbfd", ghb_int64_value(0));
551 gval = ghb_settings_get_value(ud->settings, "default_source");
552 ghb_settings_set_value (ud->settings, "source", gval);
553 str = ghb_settings_get_string(ud->settings, "destination_dir");
555 gchar *path = g_strdup_printf ("%s/new_video.mp4", str);
556 ghb_ui_update(ud, "destination", ghb_string_value(path));
560 prefs_initializing = FALSE;
564 ghb_prefs_save(GValue *settings)
572 if (prefs_initializing) return;
573 dict = plist_get_dict(internalPlist, "Preferences");
574 if (dict == NULL) return;
575 pref_dict = plist_get_dict(prefsPlist, "Preferences");
576 if (pref_dict == NULL) return;
577 ghb_dict_iter_init(&iter, dict);
578 // middle (void*) cast prevents gcc warning "defreferencing type-punned
579 // pointer will break strict-aliasing rules"
580 while (g_hash_table_iter_next(
581 &iter, (gpointer*)(void*)&key, (gpointer*)(void*)&value))
583 value = ghb_settings_get_value(settings, key);
586 ghb_dict_insert(pref_dict, g_strdup(key), ghb_value_dup(value));
589 store_plist(prefsPlist, "preferences");
593 ghb_pref_save(GValue *settings, const gchar *key)
597 if (prefs_initializing) return;
598 value = ghb_settings_get_value(settings, key);
602 dict = plist_get_dict(prefsPlist, "Preferences");
603 if (dict == NULL) return;
604 ghb_dict_insert(dict, g_strdup(key), ghb_value_dup(value));
605 store_plist(prefsPlist, "preferences");
610 ghb_settings_init(signal_user_data_t *ud)
618 g_debug("ghb_settings_init");
619 prefs_initializing = TRUE;
621 internalPlist = ghb_resource_get("internal-defaults");
622 // Setting a ui widget will cause the corresponding setting
623 // to be set, but it also triggers a callback that can
624 // have the side effect of using other settings values
625 // that have not yet been set. So set *all* settings first
626 // then update the ui.
627 internal = plist_get_dict(internalPlist, "Initialization");
628 ghb_dict_iter_init(&iter, internal);
629 // middle (void*) cast prevents gcc warning "defreferencing type-punned
630 // pointer will break strict-aliasing rules"
631 while (g_hash_table_iter_next(
632 &iter, (gpointer*)(void*)&key, (gpointer*)(void*)&gval))
634 ghb_settings_set_value(ud->settings, key, gval);
637 internal = plist_get_dict(internalPlist, "Presets");
638 ghb_dict_iter_init(&iter, internal);
639 // middle (void*) cast prevents gcc warning "defreferencing type-punned
640 // pointer will break strict-aliasing rules"
641 while (g_hash_table_iter_next(
642 &iter, (gpointer*)(void*)&key, (gpointer*)(void*)&gval))
644 ghb_settings_set_value(ud->settings, key, gval);
647 internal = plist_get_dict(internalPlist, "Preferences");
648 ghb_dict_iter_init(&iter, internal);
649 // middle (void*) cast prevents gcc warning "defreferencing type-punned
650 // pointer will break strict-aliasing rules"
651 while (g_hash_table_iter_next(
652 &iter, (gpointer*)(void*)&key, (gpointer*)(void*)&gval))
654 ghb_settings_set_value(ud->settings, key, gval);
656 prefs_initializing = FALSE;
663 ghb_value_free(internalPlist);
665 ghb_value_free(presetsPlist);
667 ghb_value_free(prefsPlist);
671 ghb_prefs_load(signal_user_data_t *ud)
673 GValue *dict, *internal;
678 g_debug("ghb_prefs_load");
679 prefsPlist = load_plist("preferences");
680 if (prefsPlist == NULL)
681 prefsPlist = ghb_dict_value_new();
682 dict = plist_get_dict(prefsPlist, "Preferences");
683 internal = plist_get_dict(internalPlist, "Preferences");
684 if (dict == NULL && internal)
686 dict = ghb_dict_value_new();
687 ghb_dict_insert(prefsPlist, g_strdup("Preferences"), dict);
689 // Get defaults from internal defaults
690 ghb_dict_iter_init(&iter, internal);
691 // middle (void*) cast prevents gcc warning "defreferencing type-punned
692 // pointer will break strict-aliasing rules"
693 while (g_hash_table_iter_next(
694 &iter, (gpointer*)(void*)&key, (gpointer*)(void*)&gval))
696 ghb_dict_insert(dict, g_strdup(key), ghb_value_dup(gval));
698 const gchar *dir = g_get_user_special_dir (G_USER_DIRECTORY_VIDEOS);
703 ghb_dict_insert(dict,
704 g_strdup("destination_dir"), ghb_value_dup(ghb_string_value(dir)));
705 store_plist(prefsPlist, "preferences");
710 ghb_presets_reload(signal_user_data_t *ud)
715 g_debug("ghb_presets_reload()\n");
716 std_presets = ghb_resource_get("standard-presets");
717 if (std_presets == NULL) return;
719 // Merge the keyfile contents into our presets
720 count = ghb_array_len(std_presets);
721 for (ii = 0; ii < count; ii++)
731 std_dict = ghb_array_get_nth(std_presets, ii);
732 name = preset_get_name(std_dict);
733 presets_remove(presetsPlist, name);
735 copy_dict = ghb_dict_value_new();
736 pos = presets_find_pos(presetsPlist, name, 0);
737 ghb_array_insert(presetsPlist, pos, copy_dict);
738 ghb_dict_iter_init(&iter, std_dict);
739 // middle (void*) cast prevents gcc warning "defreferencing type-punned
740 // pointer will break strict-aliasing rules"
741 while (g_hash_table_iter_next(
742 &iter, (gpointer*)(void*)&key, (gpointer*)(void*)&value))
744 ghb_dict_insert(copy_dict, g_strdup(key), ghb_value_dup(value));
747 store_plist(presetsPlist, "presets");
753 g_debug("presets_store ()\n");
754 store_plist(presetsPlist, "presets");
758 ghb_save_queue(GValue *queue)
760 store_plist(queue, "queue");
766 return load_plist("queue");
770 ghb_remove_queue_file()
772 remove_plist("queue");
778 presetsPlist = load_plist("presets");
779 if (presetsPlist == NULL)
781 presetsPlist = ghb_value_dup(ghb_resource_get("standard-presets"));
784 if (G_VALUE_TYPE(presetsPlist) == ghb_dict_get_type())
785 { // Presets is older dictionary format. Convert to array
786 GHashTableIter old_iter;
791 presets = ghb_array_value_new(32);
792 ghb_dict_iter_init(&old_iter, presetsPlist);
793 // middle (void*) cast prevents gcc warning "defreferencing type-punned
794 // pointer will break strict-aliasing rules"
795 while (g_hash_table_iter_next(
796 &old_iter, (gpointer*)(void*)&name, (gpointer*)(void*)&orig_dict))
800 GValue *value, *dict;
802 dict = ghb_dict_value_new();
803 ghb_dict_insert(dict, g_strdup("preset_name"),
804 ghb_string_value_new(name));
805 ghb_array_append(presets, dict);
806 ghb_dict_iter_init(&iter, orig_dict);
807 // middle (void*) cast prevents gcc warning "defreferencing
808 // type-punned pointer will break strict-aliasing rules"
809 while (g_hash_table_iter_next(
810 &iter, (gpointer*)(void*)&key, (gpointer*)(void*)&value))
812 ghb_dict_insert(dict, g_strdup(key), ghb_value_dup(value));
815 ghb_value_free(presetsPlist);
816 presetsPlist = presets;
822 ghb_settings_save(signal_user_data_t *ud, const gchar *name)
824 GValue *dict, *internal;
830 if (internalPlist == NULL) return;
831 if (ghb_settings_get_boolean(ud->settings, "allow_tweaks"))
834 str = ghb_settings_get_string(ud->settings, "tweak_deinterlace");
837 ghb_settings_set_string(ud->settings, "deinterlace", str);
840 str = ghb_settings_get_string(ud->settings, "tweak_denoise");
843 ghb_settings_set_string(ud->settings, "denoise", str);
847 autoscale = ghb_settings_get_boolean(ud->settings, "autoscale");
848 ghb_settings_set_int64(ud->settings, "preset_type", 1);
850 dict = ghb_dict_value_new();
851 ghb_dict_insert(dict, g_strdup("preset_name"), ghb_string_value_new(name));
852 gint pos = presets_find_pos(presetsPlist, name, 1);
853 ghb_array_insert(presetsPlist, pos, dict);
854 internal = plist_get_dict(internalPlist, "Presets");
856 ghb_dict_iter_init(&iter, internal);
857 // middle (void*) cast prevents gcc warning "defreferencing type-punned
858 // pointer will break strict-aliasing rules"
859 while (g_hash_table_iter_next(
860 &iter, (gpointer*)(void*)&key, (gpointer*)(void*)&value))
868 if (strcmp(key, "max_width") == 0)
870 key2 = "scale_width";
872 else if (strcmp(key, "max_height") == 0)
874 key2 = "scale_height";
877 gval = ghb_settings_get_value(ud->settings, key2);
880 g_debug("Setting (%s) is not in defaults\n", (gchar*)key);
883 if (ghb_value_cmp(gval, value) != 0)
885 // Differs from default value. Store it.
886 ghb_dict_insert(dict, g_strdup(key), ghb_value_dup(gval));
890 ud->dont_clear_presets = TRUE;
891 ghb_set_preset (ud, name);
892 ud->dont_clear_presets = FALSE;
896 ghb_presets_remove(const gchar *name)
898 if (presets_get_dict(presetsPlist, name))
900 presets_remove(presetsPlist, name);
906 ghb_presets_list_update(signal_user_data_t *ud)
908 GtkTreeView *treeview;
914 const gchar *description;
915 gint flags, custom, def;
919 g_debug("ghb_presets_list_update ()");
920 def_preset = ghb_settings_get_string(ud->settings, "default_preset");
921 count = ghb_array_len(presetsPlist);
922 treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "presets_list"));
923 store = GTK_TREE_STORE(gtk_tree_view_get_model(treeview));
925 if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter))
931 // Update row with settings data
932 g_debug("Updating row");
933 dict = ghb_array_get_nth(presetsPlist, ii);
934 preset = preset_get_name(dict);
936 if (strcmp(preset, def_preset) == 0)
937 def = PRESET_DEFAULT;
939 description = ghb_presets_get_description(dict);
940 flags = ghb_preset_flags(dict);
941 custom = flags & PRESET_CUSTOM;
942 gtk_tree_store_set(store, &iter,
946 3, custom ? "black" : "blue",
950 done = !gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter);
954 // No more settings data, remove row
955 g_debug("Removing row");
956 done = !gtk_tree_store_remove(store, &iter);
962 // Additional settings, add row
963 g_debug("Adding rows");
964 dict = ghb_array_get_nth(presetsPlist, ii);
965 preset = preset_get_name(dict);
967 if (strcmp(preset, def_preset) == 0)
968 def = PRESET_DEFAULT;
970 description = ghb_presets_get_description(dict);
971 gtk_tree_store_append(store, &iter, NULL);
972 flags = ghb_preset_flags(dict);
973 custom = flags & PRESET_CUSTOM;
974 gtk_tree_store_set(store, &iter, 0, preset,
977 3, custom ? "black" : "blue",
986 ghb_select_preset(GtkBuilder *builder, const gchar *preset)
988 GtkTreeView *treeview;
989 GtkTreeSelection *selection;
994 gboolean foundit = FALSE;
996 g_debug("select_preset()");
997 if (preset == NULL) return;
998 treeview = GTK_TREE_VIEW(GHB_WIDGET(builder, "presets_list"));
999 selection = gtk_tree_view_get_selection (treeview);
1000 store = gtk_tree_view_get_model (treeview);
1001 if (gtk_tree_model_get_iter_first(store, &iter))
1005 gtk_tree_model_get(store, &iter, 0, &tpreset, -1);
1006 if (strcmp(preset, tpreset) == 0)
1008 gtk_tree_selection_select_iter (selection, &iter);
1014 done = !gtk_tree_model_iter_next(store, &iter);
1019 gtk_tree_model_get_iter_first(store, &iter);
1020 gtk_tree_selection_select_iter (selection, &iter);
1025 update_audio_presets(signal_user_data_t *ud)
1027 g_debug("update_audio_presets");
1028 const GValue *audio_list;
1030 audio_list = ghb_settings_get_value(ud->settings, "audio_list");
1031 ghb_settings_set_value(ud->settings, "pref_audio_list", audio_list);
1035 presets_save_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
1040 GtkResponseType response;
1043 g_debug("presets_save_clicked_cb ()");
1044 preset = ghb_settings_get_string (ud->settings, "preset");
1045 // Clear the description
1046 desc = GTK_TEXT_VIEW(GHB_WIDGET(ud->builder, "preset_description"));
1047 dialog = GHB_WIDGET(ud->builder, "preset_save_dialog");
1048 entry = GTK_ENTRY(GHB_WIDGET(ud->builder, "preset_name"));
1049 gtk_entry_set_text(entry, preset);
1051 response = gtk_dialog_run(GTK_DIALOG(dialog));
1052 gtk_widget_hide(dialog);
1053 if (response == GTK_RESPONSE_OK)
1056 const gchar *name = gtk_entry_get_text(entry);
1057 g_debug("description to settings");
1058 ghb_widget_to_setting(ud->settings, GTK_WIDGET(desc));
1059 // Construct the audio settings presets from the current audio list
1060 update_audio_presets(ud);
1061 ghb_settings_save(ud, name);
1062 ghb_presets_list_update(ud);
1063 // Make the new preset the selected item
1064 ghb_select_preset(ud->builder, name);
1069 presets_restore_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
1071 g_debug("presets_restore_clicked_cb ()");
1072 // Reload only the standard presets
1073 ghb_presets_reload(ud);
1074 ghb_presets_list_update(ud);
1075 // Updating the presets list shuffles things around
1076 // need to make sure the proper preset is selected
1077 gchar *preset = ghb_settings_get_string (ud->settings, "preset");
1078 ghb_select_preset(ud->builder, preset);
1083 presets_remove_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
1085 GtkTreeView *treeview;
1086 GtkTreeSelection *selection;
1087 GtkTreeModel *store;
1090 GtkResponseType response;
1092 g_debug("presets_remove_clicked_cb ()");
1093 treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "presets_list"));
1094 selection = gtk_tree_view_get_selection (treeview);
1095 if (gtk_tree_selection_get_selected(selection, &store, &iter))
1099 gtk_tree_model_get(store, &iter, 0, &preset, -1);
1100 dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL,
1101 GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO,
1102 "Confirm deletion of preset %s.", preset);
1103 response = gtk_dialog_run(GTK_DIALOG(dialog));
1104 gtk_widget_destroy (dialog);
1105 if (response == GTK_RESPONSE_YES)
1107 GtkTreeIter nextIter = iter;
1108 gchar *nextPreset = NULL;
1109 if (!gtk_tree_model_iter_next(store, &nextIter))
1111 if (gtk_tree_model_get_iter_first(store, &nextIter))
1113 gtk_tree_model_get(store, &nextIter, 0, &nextPreset, -1);
1118 gtk_tree_model_get(store, &nextIter, 0, &nextPreset, -1);
1120 // Remove the selected item
1121 // First unselect it so that selecting the new item works properly
1122 gtk_tree_selection_unselect_iter (selection, &iter);
1123 ghb_presets_remove(preset);
1124 ghb_presets_list_update(ud);
1125 ghb_select_preset(ud->builder, nextPreset);
1131 preset_update_title_deps(signal_user_data_t *ud, ghb_title_info_t *tinfo)
1135 ghb_ui_update(ud, "scale_width",
1136 ghb_int64_value(tinfo->width - tinfo->crop[2] - tinfo->crop[3]));
1137 // If anamorphic or keep_aspect, the hight will be automatically calculated
1138 gboolean keep_aspect, anamorphic;
1139 keep_aspect = ghb_settings_get_boolean(ud->settings, "keep_aspect");
1140 anamorphic = ghb_settings_get_boolean(ud->settings, "anamorphic");
1141 if (!(keep_aspect || anamorphic))
1143 ghb_ui_update(ud, "scale_height",
1144 ghb_int64_value(tinfo->height - tinfo->crop[0] - tinfo->crop[1]));
1147 // Set the limits of cropping. hb_set_anamorphic_size crashes if
1148 // you pass it a cropped width or height == 0.
1150 bound = tinfo->height / 2 - 2;
1151 widget = GHB_WIDGET (ud->builder, "crop_top");
1152 gtk_spin_button_set_range (GTK_SPIN_BUTTON(widget), 0, bound);
1153 widget = GHB_WIDGET (ud->builder, "crop_bottom");
1154 gtk_spin_button_set_range (GTK_SPIN_BUTTON(widget), 0, bound);
1155 bound = tinfo->width / 2 - 2;
1156 widget = GHB_WIDGET (ud->builder, "crop_left");
1157 gtk_spin_button_set_range (GTK_SPIN_BUTTON(widget), 0, bound);
1158 widget = GHB_WIDGET (ud->builder, "crop_right");
1159 gtk_spin_button_set_range (GTK_SPIN_BUTTON(widget), 0, bound);
1160 if (ghb_settings_get_boolean(ud->settings, "autocrop"))
1162 ghb_ui_update(ud, "crop_top", ghb_int64_value(tinfo->crop[0]));
1163 ghb_ui_update(ud, "crop_bottom", ghb_int64_value(tinfo->crop[1]));
1164 ghb_ui_update(ud, "crop_left", ghb_int64_value(tinfo->crop[2]));
1165 ghb_ui_update(ud, "crop_right", ghb_int64_value(tinfo->crop[3]));
1170 presets_list_selection_changed_cb(GtkTreeSelection *selection, signal_user_data_t *ud)
1172 GtkTreeModel *store;
1175 ghb_title_info_t tinfo;
1178 g_debug("presets_list_selection_changed_cb ()");
1179 widget = GHB_WIDGET (ud->builder, "presets_remove");
1180 if (gtk_tree_selection_get_selected(selection, &store, &iter))
1182 gtk_tree_model_get(store, &iter, 0, &preset, -1);
1183 ud->dont_clear_presets = TRUE;
1184 // Temporarily set the video_quality range to (0,100)
1185 // This is needed so the video_quality value does not get
1186 // truncated when set. The range will be readjusted below
1187 GtkWidget *qp = GHB_WIDGET(ud->builder, "video_quality");
1188 gtk_range_set_range (GTK_RANGE(qp), 0, 100);
1189 // Clear the audio list prior to changing the preset. Existing audio
1190 // can cause the container extension to be automatically changed when
1192 ghb_clear_audio_list(ud);
1193 ghb_set_preset(ud, preset);
1195 titleindex = ghb_settings_combo_int(ud->settings, "title");
1196 ghb_set_pref_audio(titleindex, ud);
1197 ghb_settings_set_boolean(ud->settings, "preset_modified", FALSE);
1198 ud->dont_clear_presets = FALSE;
1199 if (ghb_get_title_info (&tinfo, titleindex))
1201 preset_update_title_deps(ud, &tinfo);
1203 ghb_set_scale (ud, GHB_SCALE_KEEP_NONE);
1206 ghb_vquality_range(ud, &vqmin, &vqmax);
1207 gtk_range_set_range (GTK_RANGE(qp), vqmin, vqmax);
1208 gtk_widget_set_sensitive(widget, TRUE);
1212 g_debug("No selection??? Perhaps unselected.");
1213 gtk_widget_set_sensitive(widget, FALSE);
1218 ghb_clear_presets_selection(signal_user_data_t *ud)
1220 GtkTreeView *treeview;
1221 GtkTreeSelection *selection;
1223 if (ud->dont_clear_presets) return;
1224 g_debug("ghb_clear_presets_selection()");
1225 treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "presets_list"));
1226 selection = gtk_tree_view_get_selection (treeview);
1227 gtk_tree_selection_unselect_all (selection);
1228 ghb_settings_set_boolean(ud->settings, "preset_modified", TRUE);
1232 presets_frame_size_allocate_cb(GtkWidget *widget, GtkAllocation *allocation, signal_user_data_t *ud)
1234 GtkTreeView *treeview;
1235 GtkTreeSelection *selection;
1236 GtkTreeModel *store;
1239 treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "presets_list"));
1240 selection = gtk_tree_view_get_selection(treeview);
1241 if (gtk_tree_selection_get_selected(selection, &store, &iter))
1244 path = gtk_tree_model_get_path (store, &iter);
1245 // Make the parent visible in scroll window if it is not.
1246 gtk_tree_view_scroll_to_cell (treeview, path, NULL, FALSE, 0, 0);
1247 gtk_tree_path_free(path);
1252 presets_default_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
1254 ghb_set_preset_default(ud->settings);
1255 ghb_presets_list_update(ud);