OSDN Git Service

LinGui: Store the activity log in the users config dir instead of PWD.
[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 gchar*
352 ghb_get_user_config_dir()
353 {
354         const gchar *dir;
355         gchar *config;
356
357         dir = g_get_user_config_dir();
358         if (!g_file_test(dir, G_FILE_TEST_IS_DIR))
359         {
360                 dir = g_get_home_dir();
361                 config = g_strdup_printf ("%s/.ghb", dir);
362                 if (!g_file_test(config, G_FILE_TEST_IS_DIR))
363                         g_mkdir (config, 0755);
364         }
365         else
366         {
367                 config = g_strdup_printf ("%s/ghb", dir);
368                 if (!g_file_test(config, G_FILE_TEST_IS_DIR))
369                         g_mkdir (config, 0755);
370         }
371         return config;
372 }
373
374 static void
375 store_plist(GValue *plist, const gchar *name)
376 {
377         gchar *config, *path;
378         FILE *file;
379
380         config = ghb_get_user_config_dir();
381         path = g_strdup_printf ("%s/%s", config, name);
382         file = g_fopen(path, "w");
383         g_free(config);
384         g_free(path);
385         ghb_plist_write(file, plist);
386         fclose(file);
387 }
388
389 static GValue*
390 load_plist(const gchar *name)
391 {
392         gchar *config, *path;
393         GValue *plist = NULL;
394
395         config = ghb_get_user_config_dir();
396         path = g_strdup_printf ("%s/%s", config, name);
397         if (g_file_test(path, G_FILE_TEST_IS_REGULAR))
398         {
399                 plist = ghb_plist_parse_file(path);
400         }
401         g_free(config);
402         g_free(path);
403         return plist;
404 }
405
406 static void
407 remove_plist(const gchar *name)
408 {
409         gchar *config, *path;
410
411         config = ghb_get_user_config_dir();
412         path = g_strdup_printf ("%s/%s", config, name);
413         if (g_file_test(path, G_FILE_TEST_IS_REGULAR))
414         {
415                 g_unlink(path);
416         }
417         g_free(path);
418         g_free(config);
419 }
420
421 static gboolean prefs_initializing = FALSE;
422
423 void
424 ghb_prefs_to_ui(signal_user_data_t *ud)
425 {
426         const GValue *gval;
427         gchar *key;
428         gchar *str;
429         GValue *internal, *dict;
430         GHashTableIter iter;
431         
432
433         prefs_initializing = TRUE;
434
435         // Setting a ui widget will cause the corresponding setting
436         // to be set, but it also triggers a callback that can 
437         // have the side effect of using other settings values
438         // that have not yet been set.  So set *all* settings first
439         // then update the ui.
440         internal = plist_get_dict(internalPlist, "Initialization");
441         ghb_dict_iter_init(&iter, internal);
442         // middle (void*) cast prevents gcc warning "defreferencing type-punned
443         // pointer will break strict-aliasing rules"
444         while (g_hash_table_iter_next(
445                         &iter, (gpointer*)(void*)&key, (gpointer*)(void*)&gval))
446         {
447                 ghb_ui_update(ud, key, gval);
448         }
449
450         dict = plist_get_dict(prefsPlist, "Preferences");
451         internal = plist_get_dict(internalPlist, "Preferences");
452         ghb_dict_iter_init(&iter, internal);
453         // middle (void*) cast prevents gcc warning "defreferencing type-punned
454         // pointer will break strict-aliasing rules"
455         while (g_hash_table_iter_next(
456                         &iter, (gpointer*)(void*)&key, (gpointer*)(void*)&gval))
457     {
458                 const GValue *value = NULL;
459                 if (dict)
460                         value = ghb_dict_lookup(dict, key);
461                 if (value == NULL)
462                         value = gval;
463                 ghb_settings_set_value(ud->settings, key, value);
464     }
465         internal = plist_get_dict(internalPlist, "Preferences");
466         ghb_dict_iter_init(&iter, internal);
467         // middle (void*) cast prevents gcc warning "defreferencing type-punned
468         // pointer will break strict-aliasing rules"
469         while (g_hash_table_iter_next(
470                         &iter, (gpointer*)(void*)&key, (gpointer*)(void*)&gval))
471         {
472                 const GValue *value = NULL;
473                 if (dict)
474                         value = ghb_dict_lookup(dict, key);
475                 if (value == NULL)
476                         value = gval;
477                 ghb_ui_update(ud, key, value);
478         }
479         const GValue *val;
480         val = ghb_settings_get_value(ud->settings, "show_presets");
481         ghb_ui_update(ud, "show_presets", val);
482         if (ghb_settings_get_boolean(ud->settings, "hbfd_feature"))
483         {
484                 GtkAction *action;
485                 val = ghb_settings_get_value(ud->settings, "hbfd");
486                 ghb_ui_update(ud, "hbfd", val);
487                 action = GHB_ACTION (ud->builder, "hbfd");
488                 gtk_action_set_visible(action, TRUE);
489         }
490         else
491         {
492                 ghb_ui_update(ud, "hbfd", ghb_int64_value(0));
493         }
494         gval = ghb_settings_get_value(ud->settings, "default_source");
495         ghb_settings_set_value (ud->settings, "source", gval);
496         str = ghb_settings_get_string(ud->settings, "destination_dir");
497
498         gchar *path = g_strdup_printf ("%s/new_video.mp4", str);
499         ghb_ui_update(ud, "destination", ghb_string_value(path));
500         g_free(str);
501         g_free(path);
502
503         prefs_initializing = FALSE;
504 }
505
506 void
507 ghb_prefs_save(GValue *settings)
508 {
509         GValue *dict;
510         GValue *pref_dict;
511         GHashTableIter iter;
512         gchar *key;
513         const GValue *value;
514         
515         if (prefs_initializing) return;
516         dict = plist_get_dict(internalPlist, "Preferences");
517         if (dict == NULL) return;
518         pref_dict = plist_get_dict(prefsPlist, "Preferences");
519         if (pref_dict == NULL) return;
520         ghb_dict_iter_init(&iter, dict);
521         // middle (void*) cast prevents gcc warning "defreferencing type-punned
522         // pointer will break strict-aliasing rules"
523         while (g_hash_table_iter_next(
524                         &iter, (gpointer*)(void*)&key, (gpointer*)(void*)&value))
525     {
526             value = ghb_settings_get_value(settings, key);
527             if (value != NULL)
528             {
529                         ghb_dict_insert(pref_dict, g_strdup(key), ghb_value_dup(value));
530             }
531         }
532     store_plist(prefsPlist, "preferences");
533 }
534
535 void
536 ghb_pref_save(GValue *settings, const gchar *key)
537 {
538         const GValue *value;
539         
540         if (prefs_initializing) return;
541         value = ghb_settings_get_value(settings, key);
542         if (value != NULL)
543         {
544                 GValue *dict;
545                 dict = plist_get_dict(prefsPlist, "Preferences");
546                 if (dict == NULL) return;
547                 ghb_dict_insert(dict, g_strdup(key), ghb_value_dup(value));
548                 store_plist(prefsPlist, "preferences");
549         }
550 }
551
552 void
553 ghb_settings_init(signal_user_data_t *ud)
554 {
555         GValue *internal;
556         GHashTableIter iter;
557         gchar *key;
558         GValue *gval;
559
560
561         g_debug("ghb_settings_init");
562         prefs_initializing = TRUE;
563
564         internalPlist = ghb_resource_get("internal-defaults");
565         // Setting a ui widget will cause the corresponding setting
566         // to be set, but it also triggers a callback that can 
567         // have the side effect of using other settings values
568         // that have not yet been set.  So set *all* settings first
569         // then update the ui.
570         internal = plist_get_dict(internalPlist, "Initialization");
571         ghb_dict_iter_init(&iter, internal);
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*)&gval))
576         {
577                 ghb_settings_set_value(ud->settings, key, gval);
578         }
579
580         internal = plist_get_dict(internalPlist, "Presets");
581         ghb_dict_iter_init(&iter, internal);
582         // middle (void*) cast prevents gcc warning "defreferencing type-punned
583         // pointer will break strict-aliasing rules"
584         while (g_hash_table_iter_next(
585                         &iter, (gpointer*)(void*)&key, (gpointer*)(void*)&gval))
586         {
587                 ghb_settings_set_value(ud->settings, key, gval);
588         }
589
590         internal = plist_get_dict(internalPlist, "Preferences");
591         ghb_dict_iter_init(&iter, internal);
592         // middle (void*) cast prevents gcc warning "defreferencing type-punned
593         // pointer will break strict-aliasing rules"
594         while (g_hash_table_iter_next(
595                         &iter, (gpointer*)(void*)&key, (gpointer*)(void*)&gval))
596         {
597                 ghb_settings_set_value(ud->settings, key, gval);
598         }
599         prefs_initializing = FALSE;
600 }
601
602 void
603 ghb_settings_close()
604 {
605         //if (internalPlist)
606                 //ghb_value_free(internalPlist);
607         if (presetsPlist)
608                 ghb_value_free(presetsPlist);
609         if (prefsPlist)
610                 ghb_value_free(prefsPlist);
611 }
612
613 void
614 ghb_prefs_load(signal_user_data_t *ud)
615 {
616         GValue *dict, *internal;
617         GHashTableIter iter;
618         gchar *key;
619         GValue *gval;
620         
621         g_debug("ghb_prefs_load");
622         prefsPlist = load_plist("preferences");
623         if (prefsPlist == NULL)
624                 prefsPlist = ghb_dict_value_new();
625         dict = plist_get_dict(prefsPlist, "Preferences");
626         internal = plist_get_dict(internalPlist, "Preferences");
627     if (dict == NULL && internal)
628     {
629                 dict = ghb_dict_value_new();
630                 ghb_dict_insert(prefsPlist, g_strdup("Preferences"), dict);
631
632         // Get defaults from internal defaults 
633                 ghb_dict_iter_init(&iter, internal);
634                 // middle (void*) cast prevents gcc warning "defreferencing type-punned
635                 // pointer will break strict-aliasing rules"
636                 while (g_hash_table_iter_next(
637                                 &iter, (gpointer*)(void*)&key, (gpointer*)(void*)&gval))
638         {
639                         ghb_dict_insert(dict, g_strdup(key), ghb_value_dup(gval));
640         }
641                 const gchar *dir = g_get_user_special_dir (G_USER_DIRECTORY_VIDEOS);
642                 if (dir == NULL)
643                 {
644                         dir = ".";
645                 }
646                 ghb_dict_insert(dict, 
647                         g_strdup("destination_dir"), ghb_value_dup(ghb_string_value(dir)));
648                 store_plist(prefsPlist, "preferences");
649     }
650 }
651
652 void
653 ghb_presets_reload(signal_user_data_t *ud)
654 {
655         GValue *std_dict, *dict;
656         GHashTableIter std_iter;
657
658         g_debug("ghb_presets_reload()\n");
659         std_dict = ghb_resource_get("standard-presets");
660         if (std_dict == NULL) return;
661
662         // Merge the keyfile contents into our presets
663         gchar *name;
664         GValue *orig_dict;
665
666         ghb_dict_iter_init(&std_iter, std_dict);
667         // middle (void*) cast prevents gcc warning "defreferencing type-punned
668         // pointer will break strict-aliasing rules"
669         while (g_hash_table_iter_next(
670                         &std_iter, (gpointer*)(void*)&name, (gpointer*)(void*)&orig_dict))
671         {
672                 GHashTableIter iter;
673                 gchar *key;
674                 GValue *value;
675
676                 dict = ghb_dict_value_new();
677                 ghb_dict_insert(presetsPlist, g_strdup(name), dict);
678                 ghb_dict_iter_init(&iter, orig_dict);
679                 // middle (void*) cast prevents gcc warning "defreferencing type-punned
680                 // pointer will break strict-aliasing rules"
681                 while (g_hash_table_iter_next(
682                                 &iter, (gpointer*)(void*)&key, (gpointer*)(void*)&value))
683                 {
684                         ghb_dict_insert(dict, g_strdup(key), ghb_value_dup(value));
685                 }
686         }
687         store_plist(presetsPlist, "presets");
688 }
689
690 static void
691 presets_store()
692 {
693         g_debug("presets_store ()\n");
694         store_plist(presetsPlist, "presets");
695 }
696
697 void
698 ghb_save_queue(GValue *queue)
699 {
700         store_plist(queue, "queue");
701 }
702
703 GValue*
704 ghb_load_queue()
705 {
706         return load_plist("queue");
707 }
708
709 void
710 ghb_remove_queue_file()
711 {
712         remove_plist("queue");
713 }
714
715 void
716 ghb_presets_load()
717 {
718         presetsPlist = load_plist("presets");
719         if (presetsPlist == NULL)
720         {
721                 presetsPlist = ghb_value_dup(ghb_resource_get("standard-presets"));
722                 presets_store();
723         }
724 }
725
726 void
727 ghb_settings_save(signal_user_data_t *ud, const gchar *name)
728 {
729         GValue *dict, *internal;
730         GHashTableIter iter;
731         gchar *key;
732         GValue *value;
733         gboolean autoscale;
734
735         if (internalPlist == NULL) return;
736         if (ghb_settings_get_boolean(ud->settings, "allow_tweaks"))
737         {
738                 gchar *str;
739                 str = ghb_settings_get_string(ud->settings, "tweak_deinterlace");
740                 if (str)
741                 {
742                         ghb_settings_set_string(ud->settings, "deinterlace", str);
743                         g_free(str);
744                 }
745                 str = ghb_settings_get_string(ud->settings, "tweak_denoise");
746                 if (str)
747                 {
748                         ghb_settings_set_string(ud->settings, "denoise", str);
749                         g_free(str);
750                 }
751         }
752         autoscale = ghb_settings_get_boolean(ud->settings, "autoscale");
753         ghb_settings_set_int64(ud->settings, "preset_type", 1);
754
755         dict = ghb_dict_value_new();
756         ghb_dict_insert(presetsPlist, g_strdup(name), dict);
757         internal = plist_get_dict(internalPlist, "Presets");
758
759         ghb_dict_iter_init(&iter, internal);
760         // middle (void*) cast prevents gcc warning "defreferencing type-punned
761         // pointer will break strict-aliasing rules"
762         while (g_hash_table_iter_next(
763                         &iter, (gpointer*)(void*)&key, (gpointer*)(void*)&value))
764         {
765                 const GValue *gval;
766                 gchar *key2;
767
768                 key2 = key;
769                 if (!autoscale)
770                 {
771                         if (strcmp(key, "max_width") == 0)
772                         {
773                                 key2 = "scale_width";
774                         }
775                         else if (strcmp(key, "max_height") == 0)
776                         {
777                                 key2 = "scale_height";
778                         }
779                 }
780                 gval = ghb_settings_get_value(ud->settings, key2);
781                 if (gval == NULL)
782                 {
783                         g_debug("Setting (%s) is not in defaults\n", (gchar*)key);
784                         continue;
785                 }
786                 if (ghb_value_cmp(gval, value) != 0)
787                 {
788                         // Differs from default value.  Store it.
789                         ghb_dict_insert(dict, g_strdup(key), ghb_value_dup(gval));
790                 }
791         }
792         presets_store();
793         ud->dont_clear_presets = TRUE;
794         ghb_set_preset (ud, name);
795         ud->dont_clear_presets = FALSE;
796 }
797
798 void
799 ghb_presets_remove(const gchar *name)
800 {
801         if (ghb_dict_lookup(presetsPlist, name))
802         {
803                 ghb_dict_remove(presetsPlist, name);
804                 presets_store();
805         }
806 }
807