OSDN Git Service

LinGui: tidy up how combobox values are handled internally and stored in plists
[handbrake-jp/handbrake-jp-git.git] / gtk / src / presets.c
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3  * presets.c
4  * Copyright (C) John Stebbins 2008 <stebbins@stebbins>
5  * 
6  * presets.c is free software.
7  * 
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)
11  * any later version.
12  * 
13  */
14 #include <glib.h>
15 #include <glib-object.h>
16 #include <glib/gstdio.h>
17 #include <string.h>
18 #include <gtk/gtk.h>
19 #include "settings.h"
20 #include "plist.h"
21 #include "resources.h"
22 #include "presets.h"
23 #include "values.h"
24
25 static GValue *presetsPlist = NULL;
26 static GValue *internalPlist = NULL;
27 static GValue *prefsPlist = NULL;
28
29 static GValue*
30 plist_get_dict(GValue *presets, const gchar *name)
31 {
32         if (presets == NULL || name == NULL) return NULL;
33         return ghb_dict_lookup(presets, name);
34 }
35
36 void
37 ghb_set_preset_default(GValue *settings)
38 {
39         gchar *preset;
40         
41         preset = ghb_settings_get_string (settings, "preset");
42         ghb_settings_set_string(settings, "default_preset", preset);
43         ghb_prefs_save(settings);
44         g_free(preset);
45 }
46
47 // Used for sorting dictionaries.
48 gint
49 key_cmp(gconstpointer a, gconstpointer b)
50 {
51         gchar *stra = (gchar*)a;
52         gchar *strb = (gchar*)b;
53
54         return strcmp(stra, strb);
55 }
56
57 gchar*
58 ghb_presets_get_description(const gchar *name)
59 {
60         GValue *pdict;
61         pdict = plist_get_dict(presetsPlist, name);
62         if (pdict == NULL) return g_strdup("");
63         return ghb_value_string(ghb_dict_lookup(pdict, "preset_description"));
64 }
65
66 static const GValue*
67 preset_dict_get_value(
68         GValue *dict,
69         const gchar *key)
70 {
71         const GValue *gval = NULL;
72
73         if (dict)
74         {
75                 gval = ghb_dict_lookup(dict, key);
76         }
77         if (internalPlist == NULL) return NULL;
78         if (gval == NULL)
79         {
80                 dict = plist_get_dict(internalPlist, "Presets");
81                 if (dict == NULL) return NULL;
82                 gval = ghb_dict_lookup(dict, key);
83         }
84         return gval;
85 }
86
87 static const GValue*
88 preset_get_value(
89         const gchar *name,
90         const gchar *key)
91 {
92         GValue *dict;
93
94         dict = plist_get_dict(presetsPlist, name);
95         return preset_dict_get_value(dict, key);
96 }
97
98 GList*
99 ghb_presets_get_names()
100 {
101         GHashTable *dict;
102         GList *names, *link;
103         GList *standard = NULL;
104         GList *custom = NULL;
105
106         if (presetsPlist == NULL) return NULL;
107         dict = g_value_get_boxed(presetsPlist);
108         link = names = g_hash_table_get_keys(dict);
109         while (link)
110         {
111                 gchar *name;
112                 gint ptype;
113
114                 name = (gchar*)link->data;
115                 ptype = ghb_value_int(preset_get_value(name, "preset_type"));
116                 if (ptype)
117                         custom = g_list_append(custom, name);
118                 else
119                         standard = g_list_append(standard, name);
120                 link = link->next;
121         }
122         custom = g_list_sort(custom, key_cmp);
123         standard = g_list_sort(standard, key_cmp);
124         g_list_free(names);
125         names = g_list_concat(standard, custom);
126         return names;
127 }
128
129 gint
130 ghb_preset_flags(const gchar *name)
131 {
132         GValue *dict;
133         const GValue *gval;
134         gint ptype;
135         gint ret = 0;
136
137         dict = plist_get_dict(presetsPlist, name);
138         gval = preset_dict_get_value(dict, "preset_type");
139         if (gval)
140         {
141                 ptype = ghb_value_int(gval);
142                 ret = (ptype != 0 ? PRESET_CUSTOM : 0);
143         }
144         return ret;
145 }
146
147 static void init_settings_from_dict(
148         GValue *dest, GValue *internal, GValue *dict);
149
150 static void
151 init_settings_from_array(
152         GValue *dest, 
153         GValue *internal,
154         GValue *array)
155 {
156         GValue *gval, *val;
157         gint count, ii;
158         
159         count = ghb_array_len(array);
160         // The first element of the internal version is always the 
161         // template for the allowed values
162         gval = ghb_array_get_nth(internal, 0);
163         for (ii = 0; ii < count; ii++)
164         {
165                 val = NULL;
166                 val = ghb_array_get_nth(array, ii);
167                 if (val == NULL)
168                         val = gval;
169                 if (G_VALUE_TYPE(gval) == ghb_dict_get_type())
170                 {
171                         GValue *new_dict;
172                         new_dict = ghb_dict_value_new();
173                         ghb_array_append(dest, new_dict);
174                         if (G_VALUE_TYPE(val) == ghb_dict_get_type())
175                                 init_settings_from_dict(new_dict, gval, val);
176                         else
177                                 init_settings_from_dict(new_dict, gval, gval);
178                 }
179                 else if (G_VALUE_TYPE(gval) == ghb_array_get_type())
180                 {
181                         GValue *new_array;
182                         new_array = ghb_array_value_new(8);
183                         ghb_array_append(dest, new_array);
184                         if (G_VALUE_TYPE(val) == ghb_array_get_type())
185                                 init_settings_from_array(new_array, gval, val);
186                         else
187                                 init_settings_from_array(new_array, gval, gval);
188                 }
189                 else
190                 {
191                         ghb_array_append(dest, val);
192                 }
193         }
194 }
195
196 static void
197 init_settings_from_dict(
198         GValue *dest, 
199         GValue *internal,
200         GValue *dict)
201 {
202         GHashTableIter iter;
203         gchar *key;
204         GValue *gval, *val;
205         
206         ghb_dict_iter_init(&iter, internal);
207         // middle (void*) cast prevents gcc warning "defreferencing type-punned
208         // pointer will break strict-aliasing rules"
209         while (g_hash_table_iter_next(
210                         &iter, (gpointer*)(void*)&key, (gpointer*)(void*)&gval))
211         {
212                 val = NULL;
213                 if (dict)
214                         val = ghb_dict_lookup(dict, key);
215                 if (val == NULL)
216                         val = gval;
217                 if (G_VALUE_TYPE(gval) == ghb_dict_get_type())
218                 {
219                         GValue *new_dict;
220                         new_dict = ghb_dict_value_new();
221                         ghb_settings_take_value(dest, key, new_dict);
222                         if (G_VALUE_TYPE(val) == ghb_dict_get_type())
223                                 init_settings_from_dict(new_dict, gval, val);
224                         else
225                                 init_settings_from_dict(new_dict, gval, gval);
226                 }
227                 else if (G_VALUE_TYPE(gval) == ghb_array_get_type())
228                 {
229                         GValue *new_array;
230                         new_array = ghb_array_value_new(8);
231                         ghb_settings_take_value(dest, key, new_array);
232                         if (G_VALUE_TYPE(val) == ghb_array_get_type())
233                                 init_settings_from_array(new_array, gval, val);
234                         else
235                                 init_settings_from_array(new_array, gval, gval);
236         
237                 }
238                 else
239                 {
240                         ghb_settings_set_value(dest, key, val);
241                 }
242         }
243 }
244
245 void
246 init_ui_from_dict(
247         signal_user_data_t *ud, 
248         GValue *internal,
249         GValue *dict)
250 {
251         GHashTableIter iter;
252         gchar *key;
253         GValue *gval, *val;
254         
255         ghb_dict_iter_init(&iter, internal);
256         // middle (void*) cast prevents gcc warning "defreferencing type-punned
257         // pointer will break strict-aliasing rules"
258         while (g_hash_table_iter_next(
259                         &iter, (gpointer*)(void*)&key, (gpointer*)(void*)&gval))
260         {
261                 val = NULL;
262                 if (dict)
263                         val = ghb_dict_lookup(dict, key);
264                 if (val == NULL)
265                         val = gval;
266                 ghb_ui_update(ud, key, val);
267         }
268 }
269
270 static void
271 preset_to_ui(signal_user_data_t *ud, GValue *dict)
272 {
273         g_debug("preset_to_ui()\n");
274         // Initialize the ui from presets file.
275         GValue *internal;
276
277         // Get key list from internal default presets.  This way we do not
278         // load any unknown keys.
279         if (internalPlist == NULL) return;
280         internal = plist_get_dict(internalPlist, "Presets");
281         // Setting a ui widget will cause the corresponding setting
282         // to be set, but it also triggers a callback that can 
283         // have the side effect of using other settings values
284         // that have not yet been set.  So set *all* settings first
285         // then update the ui.
286         init_settings_from_dict(ud->settings, internal, dict);
287         init_ui_from_dict(ud, internal, dict);
288
289         if (ghb_settings_get_boolean(ud->settings, "allow_tweaks"))
290         {
291                 const GValue *gval;
292                 gval = preset_dict_get_value(dict, "deinterlace");
293                 if (gval)
294                 {
295                         ghb_ui_update(ud, "tweak_deinterlace", gval);
296                 }
297                 gval = preset_dict_get_value(dict, "denoise");
298                 if (gval)
299                 {
300                         ghb_ui_update(ud, "tweak_denoise", gval);
301                 }
302         }
303 }
304
305 void
306 ghb_set_preset(signal_user_data_t *ud, const gchar *name)
307 {
308         GValue *dict;
309         
310         g_debug("ghb_set_preset() %s\n", name);
311         if (name == NULL)
312         {
313                 GList *presets;
314                 // Try to get the first preset
315                 presets = ghb_presets_get_names();
316                 if (presets)
317                 {
318                         name = (const gchar*)presets->data;
319                         g_list_free(presets);
320                 }
321         }
322         dict = plist_get_dict(presetsPlist, name);
323         if (dict == NULL || name == NULL)
324         {
325                 preset_to_ui(ud, NULL);
326         }
327         else
328         {
329                 preset_to_ui(ud, dict);
330                 ghb_settings_set_string(ud->settings, "preset", name);
331         }
332 }
333
334 void
335 ghb_update_from_preset(
336         signal_user_data_t *ud, 
337         const gchar *name, 
338         const gchar *key)
339 {
340         const GValue *gval;
341         
342         g_debug("ghb_update_from_preset() %s %s", name, key);
343         if (name == NULL) return;
344         gval = preset_get_value(name, key);
345         if (gval != NULL)
346         {
347                 ghb_ui_update(ud, key, gval);
348         }
349 }
350
351 static void
352 store_plist(GValue *plist, const gchar *name)
353 {
354         const gchar *dir;
355         gchar *config;
356         FILE *file;
357
358         dir = g_get_user_config_dir();
359         config = g_strdup_printf ("%s/ghb", dir);
360         if (!g_file_test(config, G_FILE_TEST_IS_DIR))
361         {
362                 g_mkdir (config, 0755);
363         }
364         g_free(config);
365         config = g_strdup_printf ("%s/ghb/%s", dir, name);
366         file = g_fopen(config, "w");
367         g_free(config);
368         ghb_plist_write(file, plist);
369         fclose(file);
370 }
371
372 static GValue*
373 load_plist(const gchar *name)
374 {
375         const gchar *dir;
376         gchar *config;
377         GValue *plist = NULL;
378
379         dir = g_get_user_config_dir();
380         config = g_strdup_printf ("%s/ghb/%s", dir, name);
381         if (g_file_test(config, G_FILE_TEST_IS_REGULAR))
382         {
383                 plist = ghb_plist_parse_file(config);
384         }
385         g_free(config);
386         return plist;
387 }
388
389 static void
390 remove_plist(const gchar *name)
391 {
392         const gchar *dir;
393         gchar *config;
394
395         dir = g_get_user_config_dir();
396         config = g_strdup_printf ("%s/ghb/%s", dir, name);
397         if (g_file_test(config, G_FILE_TEST_IS_REGULAR))
398         {
399                 g_unlink(config);
400         }
401         g_free(config);
402 }
403
404 static gboolean prefs_initializing = FALSE;
405
406 void
407 ghb_prefs_to_ui(signal_user_data_t *ud)
408 {
409         const GValue *gval;
410         gchar *key;
411         gchar *str;
412         GValue *internal, *dict;
413         GHashTableIter iter;
414         
415
416         prefs_initializing = TRUE;
417
418         // Setting a ui widget will cause the corresponding setting
419         // to be set, but it also triggers a callback that can 
420         // have the side effect of using other settings values
421         // that have not yet been set.  So set *all* settings first
422         // then update the ui.
423         internal = plist_get_dict(internalPlist, "Initialization");
424         ghb_dict_iter_init(&iter, internal);
425         // middle (void*) cast prevents gcc warning "defreferencing type-punned
426         // pointer will break strict-aliasing rules"
427         while (g_hash_table_iter_next(
428                         &iter, (gpointer*)(void*)&key, (gpointer*)(void*)&gval))
429         {
430                 ghb_ui_update(ud, key, gval);
431         }
432
433         dict = plist_get_dict(prefsPlist, "Preferences");
434         internal = plist_get_dict(internalPlist, "Preferences");
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))
440     {
441                 const GValue *value = NULL;
442                 if (dict)
443                         value = ghb_dict_lookup(dict, key);
444                 if (value == NULL)
445                         value = gval;
446                 ghb_settings_set_value(ud->settings, key, value);
447     }
448         internal = plist_get_dict(internalPlist, "Preferences");
449         ghb_dict_iter_init(&iter, internal);
450         // middle (void*) cast prevents gcc warning "defreferencing type-punned
451         // pointer will break strict-aliasing rules"
452         while (g_hash_table_iter_next(
453                         &iter, (gpointer*)(void*)&key, (gpointer*)(void*)&gval))
454         {
455                 const GValue *value = NULL;
456                 if (dict)
457                         value = ghb_dict_lookup(dict, key);
458                 if (value == NULL)
459                         value = gval;
460                 ghb_ui_update(ud, key, value);
461         }
462         const GValue *val;
463         val = ghb_settings_get_value(ud->settings, "show_presets");
464         ghb_ui_update(ud, "show_presets", val);
465         if (ghb_settings_get_boolean(ud->settings, "hbfd_feature"))
466         {
467                 GtkAction *action;
468                 val = ghb_settings_get_value(ud->settings, "hbfd");
469                 ghb_ui_update(ud, "hbfd", val);
470                 action = GHB_ACTION (ud->builder, "hbfd");
471                 gtk_action_set_visible(action, TRUE);
472         }
473         else
474         {
475                 ghb_ui_update(ud, "hbfd", ghb_int64_value(0));
476         }
477         gval = ghb_settings_get_value(ud->settings, "default_source");
478         ghb_settings_set_value (ud->settings, "source", gval);
479         str = ghb_settings_get_string(ud->settings, "destination_dir");
480
481         gchar *path = g_strdup_printf ("%s/new_video.mp4", str);
482         ghb_ui_update(ud, "destination", ghb_string_value(path));
483         g_free(str);
484         g_free(path);
485
486         prefs_initializing = FALSE;
487 }
488
489 void
490 ghb_prefs_save(GValue *settings)
491 {
492         GValue *dict;
493         GValue *pref_dict;
494         GHashTableIter iter;
495         gchar *key;
496         const GValue *value;
497         
498         if (prefs_initializing) return;
499         dict = plist_get_dict(internalPlist, "Preferences");
500         if (dict == NULL) return;
501         pref_dict = plist_get_dict(prefsPlist, "Preferences");
502         if (pref_dict == NULL) return;
503         ghb_dict_iter_init(&iter, dict);
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*)&value))
508     {
509             value = ghb_settings_get_value(settings, key);
510             if (value != NULL)
511             {
512                         ghb_dict_insert(pref_dict, g_strdup(key), ghb_value_dup(value));
513             }
514         }
515     store_plist(prefsPlist, "preferences");
516 }
517
518 void
519 ghb_pref_save(GValue *settings, const gchar *key)
520 {
521         const GValue *value;
522         
523         if (prefs_initializing) return;
524         value = ghb_settings_get_value(settings, key);
525         if (value != NULL)
526         {
527                 GValue *dict;
528                 dict = plist_get_dict(prefsPlist, "Preferences");
529                 if (dict == NULL) return;
530                 ghb_dict_insert(dict, g_strdup(key), ghb_value_dup(value));
531                 store_plist(prefsPlist, "preferences");
532         }
533 }
534
535 void
536 ghb_settings_init(signal_user_data_t *ud)
537 {
538         GValue *internal;
539         GHashTableIter iter;
540         gchar *key;
541         GValue *gval;
542
543
544         g_debug("ghb_settings_init");
545         prefs_initializing = TRUE;
546
547         internalPlist = ghb_resource_get("internal-defaults");
548         // Setting a ui widget will cause the corresponding setting
549         // to be set, but it also triggers a callback that can 
550         // have the side effect of using other settings values
551         // that have not yet been set.  So set *all* settings first
552         // then update the ui.
553         internal = plist_get_dict(internalPlist, "Initialization");
554         ghb_dict_iter_init(&iter, internal);
555         // middle (void*) cast prevents gcc warning "defreferencing type-punned
556         // pointer will break strict-aliasing rules"
557         while (g_hash_table_iter_next(
558                         &iter, (gpointer*)(void*)&key, (gpointer*)(void*)&gval))
559         {
560                 ghb_settings_set_value(ud->settings, key, gval);
561         }
562
563         internal = plist_get_dict(internalPlist, "Presets");
564         ghb_dict_iter_init(&iter, internal);
565         // middle (void*) cast prevents gcc warning "defreferencing type-punned
566         // pointer will break strict-aliasing rules"
567         while (g_hash_table_iter_next(
568                         &iter, (gpointer*)(void*)&key, (gpointer*)(void*)&gval))
569         {
570                 ghb_settings_set_value(ud->settings, key, gval);
571         }
572
573         internal = plist_get_dict(internalPlist, "Preferences");
574         ghb_dict_iter_init(&iter, internal);
575         // middle (void*) cast prevents gcc warning "defreferencing type-punned
576         // pointer will break strict-aliasing rules"
577         while (g_hash_table_iter_next(
578                         &iter, (gpointer*)(void*)&key, (gpointer*)(void*)&gval))
579         {
580                 ghb_settings_set_value(ud->settings, key, gval);
581         }
582         prefs_initializing = FALSE;
583 }
584
585 void
586 ghb_settings_close()
587 {
588         //if (internalPlist)
589                 //ghb_value_free(internalPlist);
590         if (presetsPlist)
591                 ghb_value_free(presetsPlist);
592         if (prefsPlist)
593                 ghb_value_free(prefsPlist);
594 }
595
596 void
597 ghb_prefs_load(signal_user_data_t *ud)
598 {
599         GValue *dict, *internal;
600         GHashTableIter iter;
601         gchar *key;
602         GValue *gval;
603         
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)
611     {
612                 dict = ghb_dict_value_new();
613                 ghb_dict_insert(prefsPlist, g_strdup("Preferences"), dict);
614
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))
621         {
622                         ghb_dict_insert(dict, g_strdup(key), ghb_value_dup(gval));
623         }
624                 const gchar *dir = g_get_user_special_dir (G_USER_DIRECTORY_VIDEOS);
625                 if (dir == NULL)
626                 {
627                         dir = ".";
628                 }
629                 ghb_dict_insert(dict, 
630                         g_strdup("destination_dir"), ghb_value_dup(ghb_string_value(dir)));
631                 store_plist(prefsPlist, "preferences");
632     }
633 }
634
635 void
636 ghb_presets_reload(signal_user_data_t *ud)
637 {
638         GValue *std_dict, *dict;
639         GHashTableIter std_iter;
640
641         g_debug("ghb_presets_reload()\n");
642         std_dict = ghb_resource_get("standard-presets");
643         if (std_dict == NULL) return;
644
645         // Merge the keyfile contents into our presets
646         gchar *name;
647         GValue *orig_dict;
648
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))
654         {
655                 GHashTableIter iter;
656                 gchar *key;
657                 GValue *value;
658
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))
666                 {
667                         ghb_dict_insert(dict, g_strdup(key), ghb_value_dup(value));
668                 }
669         }
670         store_plist(presetsPlist, "presets");
671 }
672
673 static void
674 presets_store()
675 {
676         g_debug("presets_store ()\n");
677         store_plist(presetsPlist, "presets");
678 }
679
680 void
681 ghb_save_queue(GValue *queue)
682 {
683         store_plist(queue, "queue");
684 }
685
686 GValue*
687 ghb_load_queue()
688 {
689         return load_plist("queue");
690 }
691
692 void
693 ghb_remove_queue_file()
694 {
695         remove_plist("queue");
696 }
697
698 void
699 ghb_presets_load()
700 {
701         presetsPlist = load_plist("presets");
702         if (presetsPlist == NULL)
703         {
704                 presetsPlist = ghb_value_dup(ghb_resource_get("standard-presets"));
705                 presets_store();
706         }
707 }
708
709 void
710 ghb_settings_save(signal_user_data_t *ud, const gchar *name)
711 {
712         GValue *dict, *internal;
713         GHashTableIter iter;
714         gchar *key;
715         GValue *value;
716         gboolean autoscale;
717
718         if (internalPlist == NULL) return;
719         if (ghb_settings_get_boolean(ud->settings, "allow_tweaks"))
720         {
721                 gchar *str;
722                 str = ghb_settings_get_string(ud->settings, "tweak_deinterlace");
723                 if (str)
724                 {
725                         ghb_settings_set_string(ud->settings, "deinterlace", str);
726                         g_free(str);
727                 }
728                 str = ghb_settings_get_string(ud->settings, "tweak_denoise");
729                 if (str)
730                 {
731                         ghb_settings_set_string(ud->settings, "denoise", str);
732                         g_free(str);
733                 }
734         }
735         autoscale = ghb_settings_get_boolean(ud->settings, "autoscale");
736         ghb_settings_set_int64(ud->settings, "preset_type", 1);
737
738         dict = ghb_dict_value_new();
739         ghb_dict_insert(presetsPlist, g_strdup(name), dict);
740         internal = plist_get_dict(internalPlist, "Presets");
741
742         ghb_dict_iter_init(&iter, internal);
743         // middle (void*) cast prevents gcc warning "defreferencing type-punned
744         // pointer will break strict-aliasing rules"
745         while (g_hash_table_iter_next(
746                         &iter, (gpointer*)(void*)&key, (gpointer*)(void*)&value))
747         {
748                 const GValue *gval;
749                 gchar *key2;
750
751                 key2 = key;
752                 if (!autoscale)
753                 {
754                         if (strcmp(key, "max_width") == 0)
755                         {
756                                 key2 = "scale_width";
757                         }
758                         else if (strcmp(key, "max_height") == 0)
759                         {
760                                 key2 = "scale_height";
761                         }
762                 }
763                 gval = ghb_settings_get_value(ud->settings, key2);
764                 if (gval == NULL)
765                 {
766                         g_debug("Setting (%s) is not in defaults\n", (gchar*)key);
767                         continue;
768                 }
769                 if (ghb_value_cmp(gval, value) != 0)
770                 {
771                         // Differs from default value.  Store it.
772                         ghb_dict_insert(dict, g_strdup(key), ghb_value_dup(gval));
773                 }
774         }
775         presets_store();
776         ud->dont_clear_presets = TRUE;
777         ghb_set_preset (ud, name);
778         ud->dont_clear_presets = FALSE;
779 }
780
781 void
782 ghb_presets_remove(const gchar *name)
783 {
784         if (ghb_dict_lookup(presetsPlist, name))
785         {
786                 ghb_dict_remove(presetsPlist, name);
787                 presets_store();
788         }
789 }
790