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_set_preset(signal_user_data_t *ud, const gchar *name)
364 g_debug("ghb_set_preset() %s\n", name);
367 dict = presets_get_first_dict(presetsPlist);
368 name = preset_get_name(dict);
372 dict = presets_get_dict(presetsPlist, name);
374 if (dict == NULL || name == NULL)
376 preset_to_ui(ud, NULL);
380 preset_to_ui(ud, dict);
381 ghb_settings_set_string(ud->settings, "preset", name);
386 ghb_update_from_preset(
387 signal_user_data_t *ud,
393 g_debug("ghb_update_from_preset() %s %s", name, key);
394 if (name == NULL) return;
395 gval = preset_get_value(name, key);
398 ghb_ui_update(ud, key, gval);
403 ghb_get_user_config_dir()
408 dir = g_get_user_config_dir();
409 if (!g_file_test(dir, G_FILE_TEST_IS_DIR))
411 dir = g_get_home_dir();
412 config = g_strdup_printf ("%s/.ghb", dir);
413 if (!g_file_test(config, G_FILE_TEST_IS_DIR))
414 g_mkdir (config, 0755);
418 config = g_strdup_printf ("%s/ghb", dir);
419 if (!g_file_test(config, G_FILE_TEST_IS_DIR))
420 g_mkdir (config, 0755);
426 store_plist(GValue *plist, const gchar *name)
428 gchar *config, *path;
431 config = ghb_get_user_config_dir();
432 path = g_strdup_printf ("%s/%s", config, name);
433 file = g_fopen(path, "w");
436 ghb_plist_write(file, plist);
441 load_plist(const gchar *name)
443 gchar *config, *path;
444 GValue *plist = NULL;
446 config = ghb_get_user_config_dir();
447 path = g_strdup_printf ("%s/%s", config, name);
448 if (g_file_test(path, G_FILE_TEST_IS_REGULAR))
450 plist = ghb_plist_parse_file(path);
458 remove_plist(const gchar *name)
460 gchar *config, *path;
462 config = ghb_get_user_config_dir();
463 path = g_strdup_printf ("%s/%s", config, name);
464 if (g_file_test(path, G_FILE_TEST_IS_REGULAR))
472 static gboolean prefs_initializing = FALSE;
475 ghb_prefs_to_ui(signal_user_data_t *ud)
480 GValue *internal, *dict;
484 prefs_initializing = TRUE;
486 // Setting a ui widget will cause the corresponding setting
487 // to be set, but it also triggers a callback that can
488 // have the side effect of using other settings values
489 // that have not yet been set. So set *all* settings first
490 // then update the ui.
491 internal = plist_get_dict(internalPlist, "Initialization");
492 ghb_dict_iter_init(&iter, internal);
493 // middle (void*) cast prevents gcc warning "defreferencing type-punned
494 // pointer will break strict-aliasing rules"
495 while (g_hash_table_iter_next(
496 &iter, (gpointer*)(void*)&key, (gpointer*)(void*)&gval))
498 ghb_ui_update(ud, key, gval);
501 dict = plist_get_dict(prefsPlist, "Preferences");
502 internal = plist_get_dict(internalPlist, "Preferences");
503 ghb_dict_iter_init(&iter, internal);
504 // middle (void*) cast prevents gcc warning "defreferencing type-punned
505 // pointer will break strict-aliasing rules"
506 while (g_hash_table_iter_next(
507 &iter, (gpointer*)(void*)&key, (gpointer*)(void*)&gval))
509 const GValue *value = NULL;
511 value = ghb_dict_lookup(dict, key);
514 ghb_settings_set_value(ud->settings, key, value);
516 internal = plist_get_dict(internalPlist, "Preferences");
517 ghb_dict_iter_init(&iter, internal);
518 // middle (void*) cast prevents gcc warning "defreferencing type-punned
519 // pointer will break strict-aliasing rules"
520 while (g_hash_table_iter_next(
521 &iter, (gpointer*)(void*)&key, (gpointer*)(void*)&gval))
523 const GValue *value = NULL;
525 value = ghb_dict_lookup(dict, key);
528 ghb_ui_update(ud, key, value);
531 val = ghb_settings_get_value(ud->settings, "show_presets");
532 ghb_ui_update(ud, "show_presets", val);
533 if (ghb_settings_get_boolean(ud->settings, "hbfd_feature"))
536 val = ghb_settings_get_value(ud->settings, "hbfd");
537 ghb_ui_update(ud, "hbfd", val);
538 action = GHB_ACTION (ud->builder, "hbfd");
539 gtk_action_set_visible(action, TRUE);
543 ghb_ui_update(ud, "hbfd", ghb_int64_value(0));
545 gval = ghb_settings_get_value(ud->settings, "default_source");
546 ghb_settings_set_value (ud->settings, "source", gval);
547 str = ghb_settings_get_string(ud->settings, "destination_dir");
549 gchar *path = g_strdup_printf ("%s/new_video.mp4", str);
550 ghb_ui_update(ud, "destination", ghb_string_value(path));
554 prefs_initializing = FALSE;
558 ghb_prefs_save(GValue *settings)
566 if (prefs_initializing) return;
567 dict = plist_get_dict(internalPlist, "Preferences");
568 if (dict == NULL) return;
569 pref_dict = plist_get_dict(prefsPlist, "Preferences");
570 if (pref_dict == NULL) return;
571 ghb_dict_iter_init(&iter, dict);
572 // middle (void*) cast prevents gcc warning "defreferencing type-punned
573 // pointer will break strict-aliasing rules"
574 while (g_hash_table_iter_next(
575 &iter, (gpointer*)(void*)&key, (gpointer*)(void*)&value))
577 value = ghb_settings_get_value(settings, key);
580 ghb_dict_insert(pref_dict, g_strdup(key), ghb_value_dup(value));
583 store_plist(prefsPlist, "preferences");
587 ghb_pref_save(GValue *settings, const gchar *key)
591 if (prefs_initializing) return;
592 value = ghb_settings_get_value(settings, key);
596 dict = plist_get_dict(prefsPlist, "Preferences");
597 if (dict == NULL) return;
598 ghb_dict_insert(dict, g_strdup(key), ghb_value_dup(value));
599 store_plist(prefsPlist, "preferences");
604 ghb_settings_init(signal_user_data_t *ud)
612 g_debug("ghb_settings_init");
613 prefs_initializing = TRUE;
615 internalPlist = ghb_resource_get("internal-defaults");
616 // Setting a ui widget will cause the corresponding setting
617 // to be set, but it also triggers a callback that can
618 // have the side effect of using other settings values
619 // that have not yet been set. So set *all* settings first
620 // then update the ui.
621 internal = plist_get_dict(internalPlist, "Initialization");
622 ghb_dict_iter_init(&iter, internal);
623 // middle (void*) cast prevents gcc warning "defreferencing type-punned
624 // pointer will break strict-aliasing rules"
625 while (g_hash_table_iter_next(
626 &iter, (gpointer*)(void*)&key, (gpointer*)(void*)&gval))
628 ghb_settings_set_value(ud->settings, key, gval);
631 internal = plist_get_dict(internalPlist, "Presets");
632 ghb_dict_iter_init(&iter, internal);
633 // middle (void*) cast prevents gcc warning "defreferencing type-punned
634 // pointer will break strict-aliasing rules"
635 while (g_hash_table_iter_next(
636 &iter, (gpointer*)(void*)&key, (gpointer*)(void*)&gval))
638 ghb_settings_set_value(ud->settings, key, gval);
641 internal = plist_get_dict(internalPlist, "Preferences");
642 ghb_dict_iter_init(&iter, internal);
643 // middle (void*) cast prevents gcc warning "defreferencing type-punned
644 // pointer will break strict-aliasing rules"
645 while (g_hash_table_iter_next(
646 &iter, (gpointer*)(void*)&key, (gpointer*)(void*)&gval))
648 ghb_settings_set_value(ud->settings, key, gval);
650 prefs_initializing = FALSE;
657 ghb_value_free(internalPlist);
659 ghb_value_free(presetsPlist);
661 ghb_value_free(prefsPlist);
665 ghb_prefs_load(signal_user_data_t *ud)
667 GValue *dict, *internal;
672 g_debug("ghb_prefs_load");
673 prefsPlist = load_plist("preferences");
674 if (prefsPlist == NULL)
675 prefsPlist = ghb_dict_value_new();
676 dict = plist_get_dict(prefsPlist, "Preferences");
677 internal = plist_get_dict(internalPlist, "Preferences");
678 if (dict == NULL && internal)
680 dict = ghb_dict_value_new();
681 ghb_dict_insert(prefsPlist, g_strdup("Preferences"), dict);
683 // Get defaults from internal defaults
684 ghb_dict_iter_init(&iter, internal);
685 // middle (void*) cast prevents gcc warning "defreferencing type-punned
686 // pointer will break strict-aliasing rules"
687 while (g_hash_table_iter_next(
688 &iter, (gpointer*)(void*)&key, (gpointer*)(void*)&gval))
690 ghb_dict_insert(dict, g_strdup(key), ghb_value_dup(gval));
692 const gchar *dir = g_get_user_special_dir (G_USER_DIRECTORY_VIDEOS);
697 ghb_dict_insert(dict,
698 g_strdup("destination_dir"), ghb_value_dup(ghb_string_value(dir)));
699 store_plist(prefsPlist, "preferences");
704 ghb_presets_reload(signal_user_data_t *ud)
709 g_debug("ghb_presets_reload()\n");
710 std_presets = ghb_resource_get("standard-presets");
711 if (std_presets == NULL) return;
713 // Merge the keyfile contents into our presets
714 count = ghb_array_len(std_presets);
715 for (ii = 0; ii < count; ii++)
725 std_dict = ghb_array_get_nth(std_presets, ii);
726 name = preset_get_name(std_dict);
727 presets_remove(presetsPlist, name);
729 copy_dict = ghb_dict_value_new();
730 pos = presets_find_pos(presetsPlist, name, 0);
731 ghb_array_insert(presetsPlist, pos, copy_dict);
732 ghb_dict_iter_init(&iter, std_dict);
733 // middle (void*) cast prevents gcc warning "defreferencing type-punned
734 // pointer will break strict-aliasing rules"
735 while (g_hash_table_iter_next(
736 &iter, (gpointer*)(void*)&key, (gpointer*)(void*)&value))
738 ghb_dict_insert(copy_dict, g_strdup(key), ghb_value_dup(value));
741 store_plist(presetsPlist, "presets");
747 g_debug("presets_store ()\n");
748 store_plist(presetsPlist, "presets");
752 ghb_save_queue(GValue *queue)
754 store_plist(queue, "queue");
760 return load_plist("queue");
764 ghb_remove_queue_file()
766 remove_plist("queue");
772 presetsPlist = load_plist("presets");
773 if (presetsPlist == NULL)
775 presetsPlist = ghb_value_dup(ghb_resource_get("standard-presets"));
778 if (G_VALUE_TYPE(presetsPlist) == ghb_dict_get_type())
779 { // Presets is older dictionary format. Convert to array
780 GHashTableIter old_iter;
785 presets = ghb_array_value_new(32);
786 ghb_dict_iter_init(&old_iter, presetsPlist);
787 // middle (void*) cast prevents gcc warning "defreferencing type-punned
788 // pointer will break strict-aliasing rules"
789 while (g_hash_table_iter_next(
790 &old_iter, (gpointer*)(void*)&name, (gpointer*)(void*)&orig_dict))
794 GValue *value, *dict;
796 dict = ghb_dict_value_new();
797 ghb_dict_insert(dict, g_strdup("preset_name"),
798 ghb_string_value_new(name));
799 ghb_array_append(presets, dict);
800 ghb_dict_iter_init(&iter, orig_dict);
801 // middle (void*) cast prevents gcc warning "defreferencing
802 // type-punned pointer will break strict-aliasing rules"
803 while (g_hash_table_iter_next(
804 &iter, (gpointer*)(void*)&key, (gpointer*)(void*)&value))
806 ghb_dict_insert(dict, g_strdup(key), ghb_value_dup(value));
809 ghb_value_free(presetsPlist);
810 presetsPlist = presets;
816 ghb_settings_save(signal_user_data_t *ud, const gchar *name)
818 GValue *dict, *internal;
824 if (internalPlist == NULL) return;
825 if (ghb_settings_get_boolean(ud->settings, "allow_tweaks"))
828 str = ghb_settings_get_string(ud->settings, "tweak_deinterlace");
831 ghb_settings_set_string(ud->settings, "deinterlace", str);
834 str = ghb_settings_get_string(ud->settings, "tweak_denoise");
837 ghb_settings_set_string(ud->settings, "denoise", str);
841 autoscale = ghb_settings_get_boolean(ud->settings, "autoscale");
842 ghb_settings_set_int64(ud->settings, "preset_type", 1);
844 dict = ghb_dict_value_new();
845 ghb_dict_insert(dict, g_strdup("preset_name"), ghb_string_value_new(name));
846 gint pos = presets_find_pos(presetsPlist, name, 1);
847 ghb_array_insert(presetsPlist, pos, dict);
848 internal = plist_get_dict(internalPlist, "Presets");
850 ghb_dict_iter_init(&iter, internal);
851 // middle (void*) cast prevents gcc warning "defreferencing type-punned
852 // pointer will break strict-aliasing rules"
853 while (g_hash_table_iter_next(
854 &iter, (gpointer*)(void*)&key, (gpointer*)(void*)&value))
862 if (strcmp(key, "max_width") == 0)
864 key2 = "scale_width";
866 else if (strcmp(key, "max_height") == 0)
868 key2 = "scale_height";
871 gval = ghb_settings_get_value(ud->settings, key2);
874 g_debug("Setting (%s) is not in defaults\n", (gchar*)key);
877 if (ghb_value_cmp(gval, value) != 0)
879 // Differs from default value. Store it.
880 ghb_dict_insert(dict, g_strdup(key), ghb_value_dup(gval));
884 ud->dont_clear_presets = TRUE;
885 ghb_set_preset (ud, name);
886 ud->dont_clear_presets = FALSE;
890 ghb_presets_remove(const gchar *name)
892 if (presets_get_dict(presetsPlist, name))
894 presets_remove(presetsPlist, name);
900 ghb_presets_list_update(signal_user_data_t *ud)
902 GtkTreeView *treeview;
908 const gchar *description;
909 gint flags, custom, def;
913 g_debug("ghb_presets_list_update ()");
914 def_preset = ghb_settings_get_string(ud->settings, "default_preset");
915 count = ghb_array_len(presetsPlist);
916 treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "presets_list"));
917 store = GTK_TREE_STORE(gtk_tree_view_get_model(treeview));
919 if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter))
925 // Update row with settings data
926 g_debug("Updating row");
927 dict = ghb_array_get_nth(presetsPlist, ii);
928 preset = preset_get_name(dict);
930 if (strcmp(preset, def_preset) == 0)
931 def = PRESET_DEFAULT;
933 description = ghb_presets_get_description(dict);
934 flags = ghb_preset_flags(dict);
935 custom = flags & PRESET_CUSTOM;
936 gtk_tree_store_set(store, &iter,
940 3, custom ? "black" : "blue",
944 done = !gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &iter);
948 // No more settings data, remove row
949 g_debug("Removing row");
950 done = !gtk_tree_store_remove(store, &iter);
956 // Additional settings, add row
957 g_debug("Adding rows");
958 dict = ghb_array_get_nth(presetsPlist, ii);
959 preset = preset_get_name(dict);
961 if (strcmp(preset, def_preset) == 0)
962 def = PRESET_DEFAULT;
964 description = ghb_presets_get_description(dict);
965 gtk_tree_store_append(store, &iter, NULL);
966 flags = ghb_preset_flags(dict);
967 custom = flags & PRESET_CUSTOM;
968 gtk_tree_store_set(store, &iter, 0, preset,
971 3, custom ? "black" : "blue",
980 ghb_select_preset(GtkBuilder *builder, const gchar *preset)
982 GtkTreeView *treeview;
983 GtkTreeSelection *selection;
988 gboolean foundit = FALSE;
990 g_debug("select_preset()");
991 if (preset == NULL) return;
992 treeview = GTK_TREE_VIEW(GHB_WIDGET(builder, "presets_list"));
993 selection = gtk_tree_view_get_selection (treeview);
994 store = gtk_tree_view_get_model (treeview);
995 if (gtk_tree_model_get_iter_first(store, &iter))
999 gtk_tree_model_get(store, &iter, 0, &tpreset, -1);
1000 if (strcmp(preset, tpreset) == 0)
1002 gtk_tree_selection_select_iter (selection, &iter);
1008 done = !gtk_tree_model_iter_next(store, &iter);
1013 gtk_tree_model_get_iter_first(store, &iter);
1014 gtk_tree_selection_select_iter (selection, &iter);
1019 update_audio_presets(signal_user_data_t *ud)
1021 g_debug("update_audio_presets");
1022 const GValue *audio_list;
1024 audio_list = ghb_settings_get_value(ud->settings, "audio_list");
1025 ghb_settings_set_value(ud->settings, "pref_audio_list", audio_list);
1029 presets_save_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
1034 GtkResponseType response;
1037 g_debug("presets_save_clicked_cb ()");
1038 preset = ghb_settings_get_string (ud->settings, "preset");
1039 // Clear the description
1040 desc = GTK_TEXT_VIEW(GHB_WIDGET(ud->builder, "preset_description"));
1041 dialog = GHB_WIDGET(ud->builder, "preset_save_dialog");
1042 entry = GTK_ENTRY(GHB_WIDGET(ud->builder, "preset_name"));
1043 gtk_entry_set_text(entry, preset);
1045 response = gtk_dialog_run(GTK_DIALOG(dialog));
1046 gtk_widget_hide(dialog);
1047 if (response == GTK_RESPONSE_OK)
1050 const gchar *name = gtk_entry_get_text(entry);
1051 g_debug("description to settings");
1052 ghb_widget_to_setting(ud->settings, GTK_WIDGET(desc));
1053 // Construct the audio settings presets from the current audio list
1054 update_audio_presets(ud);
1055 ghb_settings_save(ud, name);
1056 ghb_presets_list_update(ud);
1057 // Make the new preset the selected item
1058 ghb_select_preset(ud->builder, name);
1063 presets_restore_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
1065 g_debug("presets_restore_clicked_cb ()");
1066 // Reload only the standard presets
1067 ghb_presets_reload(ud);
1068 ghb_presets_list_update(ud);
1069 // Updating the presets list shuffles things around
1070 // need to make sure the proper preset is selected
1071 gchar *preset = ghb_settings_get_string (ud->settings, "preset");
1072 ghb_select_preset(ud->builder, preset);
1077 presets_remove_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
1079 GtkTreeView *treeview;
1080 GtkTreeSelection *selection;
1081 GtkTreeModel *store;
1084 GtkResponseType response;
1086 g_debug("presets_remove_clicked_cb ()");
1087 treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "presets_list"));
1088 selection = gtk_tree_view_get_selection (treeview);
1089 if (gtk_tree_selection_get_selected(selection, &store, &iter))
1093 gtk_tree_model_get(store, &iter, 0, &preset, -1);
1094 dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL,
1095 GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO,
1096 "Confirm deletion of preset %s.", preset);
1097 response = gtk_dialog_run(GTK_DIALOG(dialog));
1098 gtk_widget_destroy (dialog);
1099 if (response == GTK_RESPONSE_YES)
1101 GtkTreeIter nextIter = iter;
1102 gchar *nextPreset = NULL;
1103 if (!gtk_tree_model_iter_next(store, &nextIter))
1105 if (gtk_tree_model_get_iter_first(store, &nextIter))
1107 gtk_tree_model_get(store, &nextIter, 0, &nextPreset, -1);
1112 gtk_tree_model_get(store, &nextIter, 0, &nextPreset, -1);
1114 // Remove the selected item
1115 // First unselect it so that selecting the new item works properly
1116 gtk_tree_selection_unselect_iter (selection, &iter);
1117 ghb_presets_remove(preset);
1118 ghb_presets_list_update(ud);
1119 ghb_select_preset(ud->builder, nextPreset);
1125 preset_update_title_deps(signal_user_data_t *ud, ghb_title_info_t *tinfo)
1129 ghb_ui_update(ud, "scale_width",
1130 ghb_int64_value(tinfo->width - tinfo->crop[2] - tinfo->crop[3]));
1131 // If anamorphic or keep_aspect, the hight will be automatically calculated
1132 gboolean keep_aspect, anamorphic;
1133 keep_aspect = ghb_settings_get_boolean(ud->settings, "keep_aspect");
1134 anamorphic = ghb_settings_get_boolean(ud->settings, "anamorphic");
1135 if (!(keep_aspect || anamorphic))
1137 ghb_ui_update(ud, "scale_height",
1138 ghb_int64_value(tinfo->height - tinfo->crop[0] - tinfo->crop[1]));
1141 // Set the limits of cropping. hb_set_anamorphic_size crashes if
1142 // you pass it a cropped width or height == 0.
1144 bound = tinfo->height / 2 - 2;
1145 widget = GHB_WIDGET (ud->builder, "crop_top");
1146 gtk_spin_button_set_range (GTK_SPIN_BUTTON(widget), 0, bound);
1147 widget = GHB_WIDGET (ud->builder, "crop_bottom");
1148 gtk_spin_button_set_range (GTK_SPIN_BUTTON(widget), 0, bound);
1149 bound = tinfo->width / 2 - 2;
1150 widget = GHB_WIDGET (ud->builder, "crop_left");
1151 gtk_spin_button_set_range (GTK_SPIN_BUTTON(widget), 0, bound);
1152 widget = GHB_WIDGET (ud->builder, "crop_right");
1153 gtk_spin_button_set_range (GTK_SPIN_BUTTON(widget), 0, bound);
1154 if (ghb_settings_get_boolean(ud->settings, "autocrop"))
1156 ghb_ui_update(ud, "crop_top", ghb_int64_value(tinfo->crop[0]));
1157 ghb_ui_update(ud, "crop_bottom", ghb_int64_value(tinfo->crop[1]));
1158 ghb_ui_update(ud, "crop_left", ghb_int64_value(tinfo->crop[2]));
1159 ghb_ui_update(ud, "crop_right", ghb_int64_value(tinfo->crop[3]));
1164 presets_list_selection_changed_cb(GtkTreeSelection *selection, signal_user_data_t *ud)
1166 GtkTreeModel *store;
1169 ghb_title_info_t tinfo;
1172 g_debug("presets_list_selection_changed_cb ()");
1173 widget = GHB_WIDGET (ud->builder, "presets_remove");
1174 if (gtk_tree_selection_get_selected(selection, &store, &iter))
1176 gtk_tree_model_get(store, &iter, 0, &preset, -1);
1177 ud->dont_clear_presets = TRUE;
1178 // Temporarily set the video_quality range to (0,100)
1179 // This is needed so the video_quality value does not get
1180 // truncated when set. The range will be readjusted below
1181 GtkWidget *qp = GHB_WIDGET(ud->builder, "video_quality");
1182 gtk_range_set_range (GTK_RANGE(qp), 0, 100);
1183 // Clear the audio list prior to changing the preset. Existing audio
1184 // can cause the container extension to be automatically changed when
1186 ghb_clear_audio_list(ud);
1187 ghb_set_preset(ud, preset);
1189 titleindex = ghb_settings_combo_int(ud->settings, "title");
1190 ghb_set_pref_audio(titleindex, ud);
1191 ghb_settings_set_boolean(ud->settings, "preset_modified", FALSE);
1192 ud->dont_clear_presets = FALSE;
1193 if (ghb_get_title_info (&tinfo, titleindex))
1195 preset_update_title_deps(ud, &tinfo);
1197 ghb_set_scale (ud, GHB_SCALE_KEEP_NONE);
1200 ghb_vquality_range(ud, &vqmin, &vqmax);
1201 gtk_range_set_range (GTK_RANGE(qp), vqmin, vqmax);
1202 gtk_widget_set_sensitive(widget, TRUE);
1206 g_debug("No selection??? Perhaps unselected.");
1207 gtk_widget_set_sensitive(widget, FALSE);
1212 ghb_clear_presets_selection(signal_user_data_t *ud)
1214 GtkTreeView *treeview;
1215 GtkTreeSelection *selection;
1217 if (ud->dont_clear_presets) return;
1218 g_debug("ghb_clear_presets_selection()");
1219 treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "presets_list"));
1220 selection = gtk_tree_view_get_selection (treeview);
1221 gtk_tree_selection_unselect_all (selection);
1222 ghb_settings_set_boolean(ud->settings, "preset_modified", TRUE);
1226 presets_frame_size_allocate_cb(GtkWidget *widget, GtkAllocation *allocation, signal_user_data_t *ud)
1228 GtkTreeView *treeview;
1229 GtkTreeSelection *selection;
1230 GtkTreeModel *store;
1233 treeview = GTK_TREE_VIEW(GHB_WIDGET(ud->builder, "presets_list"));
1234 selection = gtk_tree_view_get_selection(treeview);
1235 if (gtk_tree_selection_get_selected(selection, &store, &iter))
1238 path = gtk_tree_model_get_path (store, &iter);
1239 // Make the parent visible in scroll window if it is not.
1240 gtk_tree_view_scroll_to_cell (treeview, path, NULL, FALSE, 0, 0);
1241 gtk_tree_path_free(path);
1246 presets_default_clicked_cb(GtkWidget *xwidget, signal_user_data_t *ud)
1248 ghb_set_preset_default(ud->settings);
1249 ghb_presets_list_update(ud);