OSDN Git Service

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