OSDN Git Service

LinGui: clean up hb status handling. mostly just moving things around.
[handbrake-jp/handbrake-jp-git.git] / gtk / src / settings.c
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3  * settings.c
4  * Copyright (C) John Stebbins 2008 <stebbins@stebbins>
5  * 
6  * settings.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 <fcntl.h>
15 #include <unistd.h>
16 #include <glib.h>
17 #include <glib/gstdio.h>
18 #include <string.h>
19 #include <gtk/gtk.h>
20 #include "settings.h"
21 #include "hb-backend.h"
22
23 void dump_settings(GHashTable *settings);
24
25 GObject*
26 debug_get_object(GtkBuilder* b, const gchar *n)
27 {
28         g_message("name %s\n", n);
29         return gtk_builder_get_object(b, n);
30 }
31
32 static gchar *true_strings[] =
33 {
34         "enable",
35         "yes",
36         "true",
37         "1"
38 };
39
40 static gboolean
41 string_is_true(const gchar *str)
42 {
43         gint count = sizeof(true_strings) / sizeof(gchar*);
44         gint ii;
45         
46         for (ii = 0; ii < count; ii++)
47         {
48                 if (strcmp(str, true_strings[ii]) == 0)
49                 {
50                         return TRUE;
51                 }
52         }
53         return FALSE;
54 }
55
56 static void
57 delete_key(gpointer str)
58 {
59         g_debug("delete_key (%s)\n", (gchar*)str);
60         g_free(str);
61 }
62
63 static void
64 delete_value(gpointer val)
65 {
66         g_debug("delete_value (%s)\n", ((setting_value_t*)val)->svalue);
67         g_free(((setting_value_t*)val)->svalue);
68         g_free(((setting_value_t*)val)->option);
69         g_free(((setting_value_t*)val)->shortOpt);
70         g_free(val);
71 }
72
73 void
74 ghb_free_setting_value(setting_value_t *val)
75 {
76         delete_value((gpointer)val);
77 }
78
79 GHashTable*
80 ghb_settings_new()
81 {
82         GHashTable* settings;
83         
84         g_debug("ghb_settings_new ()\n");
85         settings = g_hash_table_new_full(g_str_hash, g_str_equal, 
86                                                   delete_key, delete_value);
87         return settings;
88 }
89
90 static void
91 settings_set(GHashTable *settings, const gchar *key, 
92                                  const gchar *str, gint val, gdouble dbl)
93 {
94         g_debug("ghb_setting_set () key (%s), svalue (%s), ivalue %d, dvalue %.2g\n", key, str, val, dbl);
95         setting_value_t *value = g_malloc(sizeof(setting_value_t));
96         if (str != NULL)
97                 value->svalue = g_strdup(str);
98         else
99                 value->svalue = g_strdup("");
100         value->option = g_strdup(value->svalue);
101         value->shortOpt = g_strdup(value->svalue);
102         value->index = val;
103         value->ivalue = val;
104         value->dvalue = dbl;
105         g_hash_table_insert(settings, g_strdup(key), value);
106 }
107
108 static setting_value_t*
109 copy_settings_value(const setting_value_t *value)
110 {
111         setting_value_t *copy = g_malloc(sizeof(setting_value_t));
112         copy->index = value->index;
113         copy->ivalue = value->ivalue;
114         copy->dvalue = value->dvalue;
115         copy->svalue = g_strdup(value->svalue);
116         copy->option = g_strdup(value->option);
117         copy->shortOpt = g_strdup(value->shortOpt);
118         return copy;
119 }
120
121 void
122 ghb_settings_set(GHashTable *settings, const gchar *key, setting_value_t *value)
123 {
124         g_debug("ghb_settings_set () key (%s)\n", key);
125         if ((key == NULL) || (value == NULL))
126         {
127                 g_debug("Bad key or value\n");
128                 return;
129         }
130         g_debug("\tkey (%s) -- value (%s)\n", key, value->svalue);
131         g_hash_table_insert(settings, g_strdup(key), value);
132 }
133
134 void
135 ghb_settings_set_string(GHashTable *settings, const gchar *key, const gchar *str)
136 {
137         gdouble dvalue = 0;
138         gchar *end;
139
140         if (str == NULL) str = "";
141         dvalue = g_strtod (str, &end);
142         if ((end == str) && string_is_true (str))
143         {
144                 dvalue = 1;
145         }
146         settings_set(settings, key, str, dvalue, dvalue);
147 }
148
149 void
150 ghb_settings_set_dbl(GHashTable *settings, const gchar *key, gdouble dvalue)
151 {
152         setting_value_t *value;
153         
154         value = g_malloc(sizeof(setting_value_t));
155         value->index = 0;
156         value->dvalue = dvalue;
157         value->option = g_strdup_printf("%.8g", dvalue);
158         value->shortOpt = g_strdup(value->option);
159         value->svalue = g_strdup(value->option);
160         value->ivalue = dvalue;
161         ghb_settings_set( settings, key, value);
162 }
163
164 void
165 ghb_settings_copy(GHashTable *settings, const gchar *key, const setting_value_t *value)
166 {
167         setting_value_t *copy = copy_settings_value(value);
168         g_hash_table_insert(settings, g_strdup(key), copy);
169 }
170
171 const setting_value_t*
172 ghb_settings_get(GHashTable *settings, const gchar *key)
173 {
174         const setting_value_t* value;
175         g_debug("ghb_settings_get () key (%s)\n", key);
176         value = g_hash_table_lookup(settings, key);
177         return value;
178 }
179
180 gboolean
181 ghb_settings_get_bool(GHashTable *settings, const gchar *key)
182 {
183         const setting_value_t* value;
184         g_debug("ghb_settings_get_bool () key (%s)\n", key);
185         value = ghb_settings_get(settings, key);
186         if (value == NULL) 
187         {
188                 g_debug("\tNo value found\n");
189                 return FALSE;
190         }
191         g_debug("\tvalue is %d\n", value->ivalue);
192         return value->ivalue;
193 }
194
195 gint
196 ghb_settings_get_int(GHashTable *settings, const gchar *key)
197 {
198         const setting_value_t* value;
199         g_debug("ghb_settings_get_int () key (%s)\n", key);
200         value = ghb_settings_get(settings, key);
201         if (value == NULL) return 0;
202         return value->ivalue;
203 }
204
205 gint
206 ghb_settings_get_index(GHashTable *settings, const gchar *key)
207 {
208         const setting_value_t* value;
209         g_debug("ghb_settings_get_index () key (%s)\n", key);
210         value = ghb_settings_get(settings, key);
211         if (value == NULL) return 0;
212         return value->index;
213 }
214
215 gdouble
216 ghb_settings_get_dbl(GHashTable *settings, const gchar *key)
217 {
218         const setting_value_t* value;
219         g_debug("ghb_settings_get_dbl () key (%s)\n", key);
220         value = ghb_settings_get(settings, key);
221         if (value == NULL) return 0.0;
222         return value->dvalue;
223 }
224
225 const gchar*
226 ghb_settings_get_string(GHashTable *settings, const gchar *key)
227 {
228         const setting_value_t* value;
229         g_debug("ghb_settings_get_string () key (%s)\n", key);
230         value = ghb_settings_get(settings, key);
231         if (value == NULL) return "";
232         return value->svalue;
233         
234 }
235
236 const gchar*
237 ghb_settings_get_option(GHashTable *settings, const gchar *key)
238 {
239         const setting_value_t* value;
240         g_debug("ghb_settings_get_option () key (%s)\n", key);
241         value = ghb_settings_get(settings, key);
242         if (value == NULL) return "";
243         g_debug("option: (%s)\n", value->option);
244         return value->option;
245 }
246
247 const gchar*
248 ghb_settings_get_short_opt(GHashTable *settings, const gchar *key)
249 {
250         const setting_value_t* value;
251         g_debug("ghb_settings_get_short_opt () key (%s)\n", key);
252         value = ghb_settings_get(settings, key);
253         if (value == NULL) return "";
254         g_debug("shrot option: (%s)\n", value->shortOpt);
255         return value->shortOpt;
256 }
257
258 static void 
259 copy_key_val(gpointer key, gpointer val, gpointer settings)
260 {
261         g_hash_table_insert((GHashTable*)settings, 
262                                                 g_strdup((gchar*)key), 
263                                                 copy_settings_value((setting_value_t*)val));
264 }
265
266 GHashTable*
267 ghb_settings_dup(GHashTable *settings)
268 {
269         GHashTable *dup_settings;
270         
271         if (settings == NULL) return NULL;
272         dup_settings = ghb_settings_new();
273         g_hash_table_foreach (settings, copy_key_val, dup_settings);
274         return dup_settings;
275 }
276
277 // Map widget names to setting keys
278 // Widgets that map to settings have names
279 // of this format: s_<setting key>
280 static const gchar*
281 get_setting_key(GtkWidget *widget)
282 {
283         const gchar *name;
284         
285         g_debug("get_setting_key ()\n");
286         if (widget == NULL) return NULL;
287         if (GTK_IS_ACTION(widget))
288                 name = gtk_action_get_name(GTK_ACTION(widget));
289         else
290                 name = gtk_widget_get_name(widget);
291                 
292         if (name == NULL)
293         {
294                 // Bad widget pointer?  Should never happen.
295                 g_debug("Bad widget\n");
296                 return NULL;
297         }
298         return name;
299 }
300
301 setting_value_t*
302 ghb_widget_value(GtkWidget *widget)
303 {
304         setting_value_t *value;
305         const gchar *name;
306         GType type;
307         
308         if (widget == NULL)
309         {
310                 g_debug("NULL widget\n");
311                 return NULL;
312         }
313         value = g_malloc(sizeof(setting_value_t));
314         if (GTK_IS_ACTION(widget))
315                 name = gtk_action_get_name(GTK_ACTION(widget));
316         else
317                 name = gtk_widget_get_name(widget);
318         g_debug("ghb_widget_value widget (%s)\n", name);
319         type = GTK_OBJECT_TYPE(widget);
320         if (type == GTK_TYPE_ENTRY)
321         {
322                 const gchar *str = gtk_entry_get_text((GtkEntry*)widget);
323                 value->option = g_strdup(str);
324                 value->shortOpt = g_strdup(str);
325                 value->svalue = g_strdup(str);
326                 value->dvalue = g_strtod(str, NULL);
327                 value->ivalue = value->dvalue;
328                 value->index = 0;
329         }
330         else if (type == GTK_TYPE_RADIO_BUTTON)
331         {
332                 g_debug("\tradio_button");
333                 value->index = 0;
334                 if (gtk_toggle_button_get_active((GtkToggleButton*)widget))
335                 {
336                         g_debug("\tenable");
337                         value->option = g_strdup("enable");
338                         value->shortOpt = g_strdup("enable");
339                         value->svalue = g_strdup("enable");
340                         value->ivalue = 1;
341                         value->dvalue = 1;
342                 }
343                 else
344                 {
345                         g_debug("\tdisable");
346                         value->option = g_strdup("disable");
347                         value->shortOpt = g_strdup("disable");
348                         value->svalue = g_strdup("disable");
349                         value->ivalue = 0;
350                         value->dvalue = 0;
351                 }
352         }
353         else if (type == GTK_TYPE_CHECK_BUTTON)
354         {
355                 g_debug("\tcheck_button");
356                 value->index = 0;
357                 if (gtk_toggle_button_get_active((GtkToggleButton*)widget))
358                 {
359                         g_debug("\tenable");
360                         value->option = g_strdup("enable");
361                         value->shortOpt = g_strdup("enable");
362                         value->svalue = g_strdup("enable");
363                         value->ivalue = 1;
364                         value->dvalue = 1;
365                 }
366                 else
367                 {
368                         g_debug("\tdisable");
369                         value->option = g_strdup("disable");
370                         value->shortOpt = g_strdup("disable");
371                         value->svalue = g_strdup("disable");
372                         value->ivalue = 0;
373                         value->dvalue = 0;
374                 }
375         }
376         else if (type == GTK_TYPE_TOGGLE_ACTION)
377         {
378                 g_debug("\ttoggle action");
379                 value->index = 0;
380                 if (gtk_toggle_action_get_active((GtkToggleAction*)widget))
381                 {
382                         g_debug("\tenable");
383                         value->option = g_strdup("enable");
384                         value->shortOpt = g_strdup("enable");
385                         value->svalue = g_strdup("enable");
386                         value->ivalue = 1;
387                         value->dvalue = 1;
388                 }
389                 else
390                 {
391                         g_debug("\tdisable");
392                         value->option = g_strdup("disable");
393                         value->shortOpt = g_strdup("disable");
394                         value->svalue = g_strdup("disable");
395                         value->ivalue = 0;
396                         value->dvalue = 0;
397                 }
398         }
399         else if (type == GTK_TYPE_CHECK_MENU_ITEM)
400         {
401                 g_debug("\tcheck_menu_item");
402                 value->index = 0;
403                 if (gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget)))
404                 {
405                         g_debug("\tenable");
406                         value->option = g_strdup("enable");
407                         value->shortOpt = g_strdup("enable");
408                         value->svalue = g_strdup("enable");
409                         value->ivalue = 1;
410                         value->dvalue = 1;
411                 }
412                 else
413                 {
414                         g_debug("\tdisable");
415                         value->option = g_strdup("disable");
416                         value->shortOpt = g_strdup("disable");
417                         value->svalue = g_strdup("disable");
418                         value->ivalue = 0;
419                         value->dvalue = 0;
420                 }
421         }
422         else if (type == GTK_TYPE_COMBO_BOX)
423         {
424                 GtkTreeModel *store;
425                 GtkTreeIter iter;
426                 gchar *shortOpt, *option, *svalue;
427                 gint ivalue;
428                 gint index = gtk_combo_box_get_active(GTK_COMBO_BOX(widget));
429
430                 store = gtk_combo_box_get_model(GTK_COMBO_BOX(widget));
431                 if (gtk_combo_box_get_active_iter(GTK_COMBO_BOX(widget), &iter))
432                 {
433                         gtk_tree_model_get(store, &iter, 0, &option, 2, &shortOpt, 
434                                                            3, &ivalue, 4, &svalue, -1);
435
436                         g_debug("\tcombo: index %d opt (%s) Short Opt (%s) value %d\n", index, option, shortOpt, ivalue);
437                         value->option = option;
438                         value->shortOpt = shortOpt;
439                         value->svalue = svalue;
440                         value->index = index;
441                         value->ivalue = ivalue;
442                         value->dvalue = ivalue;
443                 }
444                 else
445                 {
446                         value->option = g_strdup("");
447                         value->shortOpt = g_strdup("");
448                         value->svalue = g_strdup("");
449                         value->index = -1;
450                         value->ivalue = 0;
451                         value->dvalue = 0;
452                 }
453         }
454         else if (type == GTK_TYPE_SPIN_BUTTON)
455         {
456                 value->index = 0;
457                 value->dvalue = gtk_spin_button_get_value_as_int((GtkSpinButton*)widget);
458                 value->option = g_strdup_printf("%.8g", value->dvalue);
459                 value->shortOpt = g_strdup_printf("%.8g", value->dvalue);
460                 value->svalue = g_strdup_printf("%.8g", value->dvalue);
461                 value->ivalue = value->dvalue;
462         }
463         else if (type == GTK_TYPE_HSCALE)
464         {
465                 value->index = 0;
466                 value->dvalue = gtk_range_get_value((GtkRange*)widget);
467                 value->option = g_strdup_printf("%.8g", value->dvalue);
468                 value->shortOpt = g_strdup_printf("%.8g", value->dvalue);
469                 value->svalue = g_strdup_printf("%.8g", value->dvalue);
470                 value->ivalue = value->dvalue;
471         }
472         else if (type == GTK_TYPE_TEXT_VIEW)
473         {
474                 GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(widget));
475                 GtkTextIter start, end;
476                 gtk_text_buffer_get_bounds(buffer, &start, &end);
477                 value->svalue = gtk_text_buffer_get_text(buffer, &start, &end, FALSE);
478                 value->option = g_strdup(value->svalue);
479                 value->shortOpt = g_strdup(value->svalue);
480                 g_debug("text view (%s)\n", value->svalue);
481                 value->ivalue = 0;
482                 value->dvalue = 0;
483                 value->index = 0;
484         }
485         else if (type == GTK_TYPE_LABEL)
486         {
487                 value->index = 0;
488                 value->svalue = g_strdup(gtk_label_get_text (GTK_LABEL(widget)));
489                 value->dvalue = g_strtod(value->svalue, NULL);
490                 value->option = g_strdup(value->svalue);
491                 value->shortOpt = g_strdup(value->svalue);
492                 value->ivalue = value->dvalue;
493                 g_debug("label (%s)\n", value->shortOpt);
494         }
495         else
496         {
497                 g_debug("Attempt to set unknown widget type: %s\n", name);
498                 g_free(value);
499                 value = NULL;
500         }
501         return value;
502 }
503
504 gchar*
505 ghb_widget_option(GtkWidget *widget)
506 {
507         setting_value_t *value;
508         gchar *str = NULL;
509         
510         g_debug("ghb_widget_option ()\n");
511         value = ghb_widget_value(widget);
512         if (value != NULL)
513         {
514                 str = g_strdup(value->option);
515                 ghb_free_setting_value (value);
516         }
517         return str;
518 }
519
520 gchar*
521 ghb_widget_short_opt(GtkWidget *widget)
522 {
523         setting_value_t *value;
524         gchar *str = NULL;
525         
526         g_debug("ghb_widget_short_opt ()\n");
527         value = ghb_widget_value(widget);
528         if (value != NULL)
529         {
530                 str = g_strdup(value->shortOpt);
531                 ghb_free_setting_value (value);
532         }
533         return str;
534 }
535
536 gchar*
537 ghb_widget_string(GtkWidget *widget)
538 {
539         setting_value_t *value;
540         gchar *str = NULL;
541         
542         g_debug("ghb_widget_string ()\n");
543         value = ghb_widget_value(widget);
544         if (value != NULL)
545         {
546                 g_debug("str (%s)\n", value->svalue);
547                 str = g_strdup(value->svalue);
548                 ghb_free_setting_value (value);
549         }
550         return str;
551 }
552
553 gdouble
554 ghb_widget_dbl(GtkWidget *widget)
555 {
556         setting_value_t *value;
557         gdouble dbl = 0;
558         
559         g_debug("ghb_widget_dbl ()\n");
560         value = ghb_widget_value(widget);
561         if (value != NULL)
562         {
563                 dbl = value->dvalue;
564                 ghb_free_setting_value (value);
565         }
566         return dbl;
567 }
568
569 gint
570 ghb_widget_int(GtkWidget *widget)
571 {
572         setting_value_t *value;
573         gint ivalue = 0;
574         
575         g_debug("ghb_widget_int ()\n");
576         value = ghb_widget_value(widget);
577         if (value != NULL)
578         {
579                 ivalue = value->ivalue;
580                 ghb_free_setting_value (value);
581         }
582         return ivalue;
583 }
584
585 gint
586 ghb_widget_index(GtkWidget *widget)
587 {
588         setting_value_t *value;
589         gint index = 0;
590         
591         g_debug("ghb_widget_index ()\n");
592         value = ghb_widget_value(widget);
593         if (value != NULL)
594         {
595                 index = value->index;
596                 ghb_free_setting_value (value);
597         }
598         return index;
599 }
600
601 void
602 ghb_widget_to_setting(GHashTable *settings, GtkWidget *widget)
603 {
604         const gchar *key = NULL;
605         setting_value_t *value;
606         
607         g_debug("ghb_widget_to_setting ()\n");
608         if (widget == NULL) return;
609         // Find corresponding setting
610         key = get_setting_key(widget);
611         if (key == NULL) return;
612         value = ghb_widget_value(widget);
613         if (value != NULL)
614         {
615                 ghb_settings_set (settings, key, value);
616         }
617         else
618         {
619                 g_debug("No value found for %s\n", key);
620         }
621         //dump_settings(settings);
622 }
623
624 static void
625 update_widget(GtkWidget *widget, const gchar *parm_svalue, gint parm_ivalue)
626 {
627         GType type;
628         gchar *value;
629
630         g_debug("update_widget\n");
631         // make a dup of setting value because the setting hash gets 
632         // modified and thus the value pointer can become invalid.
633         if (parm_svalue == NULL)
634         {
635                 value = g_strdup_printf ("%d", parm_ivalue);
636         }
637         else
638         {
639                 value = g_strdup(parm_svalue);
640         }
641         g_debug("update widget value (%s)\n", value);
642         type = GTK_OBJECT_TYPE(widget);
643         if (type == GTK_TYPE_ENTRY)
644         {
645                 g_debug("entry\n");
646                 gtk_entry_set_text((GtkEntry*)widget, value);
647         }
648         else if (type == GTK_TYPE_RADIO_BUTTON)
649         {
650                 g_debug("radio button\n");
651                 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), string_is_true(value));
652         }
653         else if (type == GTK_TYPE_CHECK_BUTTON)
654         {
655                 g_debug("check button\n");
656                 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), string_is_true(value));
657         }
658         else if (type == GTK_TYPE_TOGGLE_ACTION)
659         {
660                 g_debug("toggle action\n");
661                 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(widget), string_is_true(value));
662         }
663         else if (type == GTK_TYPE_CHECK_MENU_ITEM)
664         {
665                 g_debug("check menu item\n");
666                 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(widget), string_is_true(value));
667         }
668         else if (type == GTK_TYPE_COMBO_BOX)
669         {
670                 GtkTreeModel *store;
671                 GtkTreeIter iter;
672                 gchar *shortOpt;
673                 gint ivalue;
674                 gboolean foundit = FALSE;
675
676                 store = gtk_combo_box_get_model(GTK_COMBO_BOX(widget));
677                 if (gtk_tree_model_get_iter_first (store, &iter))
678                 {
679                         do
680                         {
681                                 gtk_tree_model_get(store, &iter, 2, &shortOpt, 3, &ivalue, -1);
682                                 if (parm_svalue == NULL && ivalue == parm_ivalue)
683                                 {
684                                         gtk_combo_box_set_active_iter (GTK_COMBO_BOX(widget), &iter);
685                                         g_free(shortOpt);
686                                         foundit = TRUE;
687                                         break;
688                                 }
689                                 else if (strcmp(shortOpt, value) == 0)
690                                 {
691                                         gtk_combo_box_set_active_iter (GTK_COMBO_BOX(widget), &iter);
692                                         g_free(shortOpt);
693                                         foundit = TRUE;
694                                         break;
695                                 }
696                                 g_free(shortOpt);
697                         } while (gtk_tree_model_iter_next (store, &iter));
698                 }
699                 if (!foundit)
700                 {
701                         gtk_combo_box_set_active (GTK_COMBO_BOX(widget), 0);
702                 }
703         }
704         else if (type == GTK_TYPE_SPIN_BUTTON)
705         {
706                 gdouble val;
707                 
708                 g_debug("spin\n");
709                 val = g_strtod(value, NULL);
710                 gtk_spin_button_set_value((GtkSpinButton*)widget, val);
711         }
712         else if (type == GTK_TYPE_HSCALE)
713         {
714                 gdouble val;
715                 
716                 g_debug("hscale\n");
717                 val = g_strtod(value, NULL);
718                 gtk_range_set_value((GtkRange*)widget, val);
719         }
720         else if (type == GTK_TYPE_TEXT_VIEW)
721         {
722                 GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(widget));
723                 gtk_text_buffer_set_text (buffer, value, -1);
724         }
725         else
726         {
727                 g_debug("Attempt to set unknown widget type\n");
728         }
729         g_free(value);
730 }
731
732 int
733 ghb_ui_update(signal_user_data_t *ud, const gchar *name, const gchar *value)
734 {
735         GObject *object;
736
737         g_debug("ghb_ui_update ()\n");
738         object = GHB_OBJECT(ud->builder, name);
739         if (object == NULL)
740         {
741                 g_debug("Failed to find widget for key: %s\n", name);
742                 return -1;
743         }
744         update_widget((GtkWidget*)object, value, 0);
745         // Its possible the value hasn't changed. Since settings are only
746         // updated when the value changes, I'm initializing settings here as well.
747         ghb_widget_to_setting(ud->settings, (GtkWidget*)object);
748         return 0;
749 }
750
751 int
752 ghb_ui_update_int(signal_user_data_t *ud, const gchar *name, gint ivalue)
753 {
754         GObject *object;
755
756         g_debug("ghb_ui_update ()\n");
757         object = GHB_OBJECT(ud->builder, name);
758         if (object == NULL)
759         {
760                 g_debug("Failed to find widget for key: %s\n", name);
761                 return -1;
762         }
763         update_widget((GtkWidget*)object, NULL, ivalue);
764         // Its possible the value hasn't changed. Since settings are only
765         // updated when the value changes, I'm initializing settings here as well.
766         ghb_widget_to_setting(ud->settings, (GtkWidget*)object);
767         return 0;
768 }
769
770 static void
771 show_setting(gpointer key, gpointer value, gpointer user_data)
772 {
773         printf("key (%s) -- value (%s)\n", (gchar*)key, (gchar*)value);
774 }
775
776 void
777 dump_settings(GHashTable *settings)
778 {
779         printf("------------------------------------\n");
780         g_hash_table_foreach(settings, show_setting, NULL);
781 }
782
783 // This is a bit hackish, but effective
784 const gchar defaultSettings[] =
785 #include "internal_defaults.h"
786 ;
787
788 typedef struct
789 {
790         gchar *name;
791         gchar *description;
792         gboolean custom;
793         gboolean defalt;
794         GKeyFile *keyFile;
795 } presets_data_t;
796
797 static GKeyFile *standardKeyFile;
798 static GKeyFile *customKeyFile;
799 static GKeyFile *internalKeyFile;
800 static GKeyFile *prefsKeyFile;
801 static GList *presetsList;
802
803 static gint
804 search_group(const gchar *name, gchar **groups)
805 {
806         gint ii;
807
808         //g_debug("search_group\n");
809         if (groups == NULL) return -1;
810         for (ii = 0; groups[ii] != NULL; ii++)
811         {
812                 //g_debug("%s cmp %s\n", name, groups[ii]);
813                 if (strcmp(name, groups[ii]) == 0)
814                 {
815                         return ii;
816                 }
817         }
818         return -1;
819 }
820
821 presets_data_t *
822 presets_list_search(GList *list, const gchar *name)
823 {
824         GList *link = list;
825         while (link != NULL)
826         {
827                 presets_data_t *data;
828                 data = (presets_data_t*)link->data;
829                 g_debug("search -- %s\n", data->name);
830                 if (strcmp(name, data->name) == 0)
831                 {
832                         return data;
833                 }
834                 link = g_list_next(link);
835         }
836         return NULL;
837 }
838
839 void
840 ghb_set_preset_default(GHashTable *settings)
841 {
842         const gchar *preset;
843         presets_data_t *data;
844         
845         preset = ghb_settings_get_string (settings, "default_preset");
846         data = presets_list_search(presetsList, preset);
847         if (data != NULL)
848         {
849                 data->defalt = FALSE;
850         }
851         preset = ghb_settings_get_string (settings, "preset");
852         data = presets_list_search(presetsList, preset);
853         if (data != NULL)
854         {
855                 data->defalt = TRUE;
856         }
857         ghb_settings_set_string(settings, "default_preset", preset);
858         ghb_prefs_save(settings);
859 }
860
861 gint
862 ghb_presets_list_index(const gchar *name)
863 {
864         GList *link = presetsList;
865         int ii = 0;
866         while (link != NULL)
867         {
868                 presets_data_t *data;
869                 data = (presets_data_t*)link->data;
870                 if (strcmp(name, data->name) == 0)
871                 {
872                         return ii;
873                 }
874                 link = g_list_next(link);
875                 ii++;
876         }
877         return -1;
878 }
879
880 gint
881 ghb_preset_flags(const gchar *name, gint *index)
882 {
883         GList *link = presetsList;
884         int ii = 0;
885         while (link != NULL)
886         {
887                 presets_data_t *data;
888                 data = (presets_data_t*)link->data;
889                 if (strcmp(name, data->name) == 0)
890                 {
891                         gint ret = 0;
892                         
893                         *index = ii;
894                         ret = (data->custom ? PRESET_CUSTOM : 0);
895                         ret |= (data->defalt ? PRESET_DEFAULT : 0);
896                         return ret;
897                 }
898                 link = g_list_next(link);
899                 ii++;
900         }
901         *index = -1;
902         return 0;
903 }
904
905 gchar**
906 ghb_presets_get_names()
907 {
908         gchar **result;
909         GList *link = presetsList;
910         int ii = 0;
911
912         g_debug("ghb_presets_get_names()\n");
913         result = g_malloc((g_list_length(presetsList)+1) * sizeof(gchar*));
914         while (link != NULL)
915         {
916                 presets_data_t *data;
917                 data = (presets_data_t*)link->data;
918                 result[ii++] = g_strdup(data->name);
919                 link = g_list_next(link);
920         }
921         result[ii] = NULL;
922         return result;
923 }
924
925 gchar**
926 ghb_presets_get_descriptions()
927 {
928         gchar **result;
929         GList *link = presetsList;
930         int ii = 0;
931
932         g_debug("ghb_presets_get_names()\n");
933         result = g_malloc((g_list_length(presetsList)+1) * sizeof(gchar*));
934         while (link != NULL)
935         {
936                 presets_data_t *data;
937                 data = (presets_data_t*)link->data;
938                 result[ii++] = g_strdup(data->description);
939                 link = g_list_next(link);
940         }
941         result[ii] = NULL;
942         return result;
943 }
944
945 const gchar*
946 ghb_presets_get_name(gint index)
947 {
948         gchar *result = NULL;
949         GList *link = presetsList;
950         int ii = 0;
951
952         g_debug("ghb_presets_get_name()\n");
953         while ((link != NULL) && (ii < index))
954         {
955                 link = g_list_next(link);
956                 ii++;
957         }
958         if (link != NULL)
959         {
960                 presets_data_t *data;
961                 data = (presets_data_t*)link->data;
962                 result = data->name;
963         }
964         return result;
965 }
966
967 static gboolean
968 init_presets_hash_from_key_file(signal_user_data_t *ud, const gchar *name, GKeyFile *keyFile)
969 {
970         gchar **keys;
971         gsize length;
972         gchar *str;
973         
974         // Get key list from internal default presets.  This way we do not
975         // load any unknown keys.
976         keys = g_key_file_get_keys(internalKeyFile, "Presets", &length, NULL);
977         if (keys != NULL)
978         {
979                 gint ii;
980                 for (ii = 0; keys[ii] != NULL; ii++)
981                 {
982                         g_debug("key (%s)\n", keys[ii]);
983                         str = NULL;
984                         if (name != NULL && keyFile != NULL)
985                         {
986                                 str = g_key_file_get_string(keyFile, name, keys[ii], NULL);
987                                 g_debug("(%s, %s)\n", keys[ii], str);
988                         }
989                         if (str == NULL)
990                         {
991                                 str = g_key_file_get_string(internalKeyFile, "Presets", keys[ii], NULL);
992                         }
993                         if (str != NULL)
994                         {
995                                 g_debug("name (%s): key (%s) -- str (%s)\n", name, keys[ii], str);
996                                 ghb_settings_set_string(ud->settings, keys[ii], str);
997                                 ghb_ui_update(ud, keys[ii], str);
998                                 g_free(str);
999                         }
1000                 }
1001                 g_strfreev(keys);
1002                 return TRUE;
1003         }
1004         return FALSE;
1005 }
1006
1007 static void
1008 preset_to_ui(signal_user_data_t *ud, presets_data_t *data)
1009 {
1010         g_debug("preset_to_settings()\n");
1011         // Initialize the ui from presets file.
1012         if (data == NULL)
1013         {
1014                 // Set defaults
1015                 init_presets_hash_from_key_file(ud, NULL, NULL);
1016                 return;
1017         }
1018         else
1019         {
1020                 g_debug("preset name (%s)\n", data->name);
1021                 // Initialize from preset
1022                 init_presets_hash_from_key_file(ud, data->name, data->keyFile);
1023         }
1024 }
1025
1026 static void
1027 preset_update_ui(signal_user_data_t *ud, presets_data_t *data, const gchar *key)
1028 {
1029         gchar *str;
1030
1031         g_debug("preset_update_settings()\n");
1032         // Initialize the ui from presets file.
1033         if (data == NULL) return;
1034         str = g_key_file_get_string(data->keyFile, data->name, key, NULL);
1035         if (str != NULL)
1036         {
1037                 ghb_ui_update(ud, key, str);
1038                 g_free(str);
1039         }
1040 }
1041
1042 void
1043 ghb_set_preset(signal_user_data_t *ud, const gchar *name)
1044 {
1045         presets_data_t *data;
1046         
1047         g_debug("ghb_update_from_preset() %s\n", name);
1048         if (name == NULL)
1049         {
1050                 name = ghb_presets_get_name(0);
1051         }
1052         if (name == NULL)
1053         {
1054                 preset_to_ui(ud, NULL);
1055         }
1056         else
1057         {
1058                 data = presets_list_search(presetsList, name);
1059                 preset_to_ui(ud, data);
1060                 ghb_settings_set_string(ud->settings, "preset", name);
1061         }
1062 }
1063
1064 void
1065 ghb_update_from_preset(
1066         signal_user_data_t *ud, 
1067         const gchar *name, 
1068         const gchar *key)
1069 {
1070         presets_data_t *data;
1071         
1072         g_debug("ghb_set_preset() %s\n", name);
1073         if (name == NULL) return;
1074         data = presets_list_search(presetsList, name);
1075         preset_update_ui(ud, data, key);
1076 }
1077
1078 static void
1079 build_presets_list(GHashTable *settings)
1080 {
1081         GList *link = presetsList;
1082         presets_data_t *data;
1083         gchar **custom, **standard;
1084         gsize clength, slength;
1085         gint ii, jj;
1086         
1087         g_debug("build_presets_list ()\n");
1088         // First clear out the old presets list
1089         while (link != NULL)
1090         {
1091                 data = (presets_data_t*)link->data;
1092                 g_free(data->name);
1093                 if (data->description != NULL)
1094                         g_free(data->description);
1095                 g_free(data);
1096                 link = g_list_delete_link (link, link);
1097         }
1098         presetsList = NULL;
1099
1100         // Now build up the new list
1101         const gchar *def_name = ghb_settings_get_string(settings, "default_preset");
1102         custom = g_key_file_get_groups(customKeyFile, &clength);
1103         standard = g_key_file_get_groups(standardKeyFile, &slength);
1104         if ((slength + clength) <= 0) return;
1105         jj = 0;
1106         for (ii = 0; ii < slength; ii++)
1107         {
1108                 if (search_group(standard[ii], custom) < 0)
1109                 {
1110                         gchar *desc;
1111                         data = g_malloc(sizeof(presets_data_t));
1112                         data->name = g_strdup(standard[ii]);
1113                         data->keyFile = standardKeyFile;
1114                         data->custom = FALSE;
1115                         data->defalt = FALSE;
1116                         if ((def_name != NULL) && (strcmp(def_name, data->name) == 0))
1117                         {
1118                                 data->defalt = TRUE;
1119                         }
1120                         desc = g_key_file_get_string(standardKeyFile, standard[ii], "preset_description", NULL);
1121                         data->description = desc;
1122                         presetsList = g_list_append(presetsList, data);
1123                 }
1124         }
1125         for (ii = 0; ii < clength; ii++)
1126         {
1127                 gchar *desc;
1128                 data = g_malloc(sizeof(presets_data_t));
1129                 data->name = g_strdup(custom[ii]);
1130                 data->keyFile = customKeyFile;
1131                 data->custom = TRUE;
1132                 data->defalt = FALSE;
1133                 if ((def_name != NULL) && (strcmp(def_name, data->name) == 0))
1134                 {
1135                         data->defalt = TRUE;
1136                 }
1137                 desc = g_key_file_get_string(customKeyFile, custom[ii], "preset_description", NULL);
1138                 data->description = desc;
1139                 presetsList = g_list_append(presetsList, data);
1140         }
1141         g_strfreev(custom);
1142         g_strfreev(standard);
1143 }
1144
1145 static void
1146 store_key_file(GKeyFile *key_file, const gchar *name)
1147 {
1148         gchar *settingsString;
1149         const gchar *dir;
1150         gsize length;
1151         gchar *config;
1152         gint fd;
1153
1154         g_debug("store_key_file ()\n");
1155         settingsString = g_key_file_to_data(key_file, &length, NULL);
1156
1157         dir = g_get_user_config_dir();
1158         config = g_strdup_printf ("%s/ghb", dir);
1159         if (!g_file_test(config, G_FILE_TEST_IS_DIR))
1160         {
1161                 g_mkdir (config, 0755);
1162         }
1163         g_free(config);
1164         config = g_strdup_printf ("%s/ghb/%s", dir, name);
1165         fd = g_open(config, O_RDWR|O_CREAT|O_TRUNC, 0777);
1166         write(fd, settingsString, length);
1167         close(fd);
1168         g_debug("prefs:\n%s\n", settingsString);
1169         g_free(settingsString);
1170 }
1171
1172 void
1173 ghb_prefs_to_ui(signal_user_data_t *ud)
1174 {
1175         const gchar *str;
1176         
1177         str = ghb_settings_get_string(ud->settings, "default_source");
1178         ghb_settings_set_string (ud->settings, "source", str);
1179         str = ghb_settings_get_string(ud->settings, "destination_dir");
1180
1181         gchar *path = g_strdup_printf ("%s/new_video.mp4", str);
1182         ghb_ui_update(ud, "destination", path);
1183         g_free(path);
1184 }
1185
1186 static gboolean prefs_initializing = FALSE;
1187
1188 void
1189 ghb_prefs_save(GHashTable *settings)
1190 {
1191         gint ii;
1192         const gchar *value;
1193     gchar **keys;
1194     gsize length;
1195         
1196         if (prefs_initializing) return;
1197         keys = g_key_file_get_keys(internalKeyFile, "Preferences", &length, NULL);
1198     if (keys != NULL)
1199     {
1200             for (ii = 0; keys[ii] != NULL; ii++)
1201             {
1202                     value = ghb_settings_get_string(settings, keys[ii]);
1203                     if (value != NULL)
1204                     {
1205                             g_key_file_set_value(prefsKeyFile, "Preferences", keys[ii], value);
1206                     }
1207             }
1208         g_strfreev(keys);
1209             store_key_file(prefsKeyFile, "preferences");
1210     }
1211 }
1212
1213 void
1214 ghb_pref_save(GHashTable *settings, const gchar *key)
1215 {
1216         const gchar *value;
1217         
1218         if (prefs_initializing) return;
1219         value = ghb_settings_get_string(settings, key);
1220         if (value != NULL)
1221         {
1222                 g_key_file_set_value(prefsKeyFile, "Preferences", key, value);
1223                 store_key_file(prefsKeyFile, "preferences");
1224         }
1225 }
1226
1227 #if 0
1228 static void
1229 dump_key_file(GKeyFile *keyFile, const gchar *section)
1230 {
1231         gint ii;
1232     gchar **keys;
1233     gsize length;
1234
1235     // Get defaults from internal defaults 
1236         keys = g_key_file_get_keys(keyFile, section, &length, NULL);
1237     if (keys != NULL)
1238     {
1239         for (ii = 0; keys[ii] != NULL; ii++)
1240         {
1241             gchar *str;
1242
1243                         str = g_key_file_get_string(keyFile, section, keys[ii], NULL);
1244                         if (str != NULL)
1245                         {
1246                                 g_message("Preference: key (%s) -- str (%s)\n", keys[ii], str);
1247                                 g_free(str);
1248                         }
1249                         else
1250                         {
1251                                 g_message("Preference: key (%s) -- str **none**\n", keys[ii]);
1252                         }
1253         }
1254         g_strfreev(keys);
1255     }
1256         else
1257         {
1258                 g_message("no keys");
1259         }
1260 }
1261 #endif
1262
1263 void
1264 ghb_prefs_load(signal_user_data_t *ud)
1265 {
1266         gint ii;
1267         const gchar *dir;
1268         gchar *config;
1269         gchar *value;
1270     gchar **keys;
1271     gsize length;
1272         gboolean res;
1273         
1274         prefs_initializing = TRUE;
1275         internalKeyFile = g_key_file_new();
1276         res = g_key_file_load_from_data( internalKeyFile, defaultSettings, 
1277                                                           sizeof(defaultSettings), G_KEY_FILE_NONE, NULL);
1278         if (!res)
1279                 g_warning("Failed to initialize internal defaults\n");
1280
1281         keys = g_key_file_get_keys(internalKeyFile, "Initialization", &length, NULL);
1282         if (keys != NULL)
1283         {
1284                 gint ii;
1285                 for (ii = 0; keys[ii] != NULL; ii++)
1286                 {
1287                         gchar *str;
1288                         
1289                         g_debug("key (%s)\n", keys[ii]);
1290                         str = g_key_file_get_string(internalKeyFile, "Initialization", keys[ii], NULL);
1291                         if (str != NULL)
1292                         {
1293                                 g_debug("Initialization: key (%s) -- str (%s)\n", keys[ii], str);
1294                                 ghb_settings_set_string(ud->settings, keys[ii], str);
1295                                 ghb_ui_update(ud, keys[ii], str);
1296                                 g_free(str);
1297                         }
1298                 }
1299                 g_strfreev(keys);
1300         }
1301         prefsKeyFile = g_key_file_new();
1302         dir = g_get_user_config_dir();
1303         config = g_strdup_printf ("%s/ghb/preferences", dir);
1304         if (g_file_test(config, G_FILE_TEST_IS_REGULAR))
1305         {
1306                 g_key_file_load_from_file( prefsKeyFile, config, G_KEY_FILE_KEEP_COMMENTS, NULL);
1307         }
1308         value = g_key_file_get_value(prefsKeyFile, "Preferences", "version", NULL);
1309     if (value == NULL)
1310     {
1311         gint ii;
1312
1313         // Get defaults from internal defaults 
1314             keys = g_key_file_get_keys(internalKeyFile, "Preferences", &length, NULL);
1315         if (keys != NULL)
1316         {
1317             for (ii = 0; keys[ii] != NULL; ii++)
1318             {
1319                 gchar *str;
1320
1321                             str = g_key_file_get_string(internalKeyFile, "Preferences", keys[ii], NULL);
1322                             if (str != NULL)
1323                             {
1324                                     g_debug("Preference: key (%s) -- str (%s)\n", keys[ii], str);
1325                             g_key_file_set_value(prefsKeyFile, "Preferences", keys[ii], str);
1326                                     g_free(str);
1327                             }
1328             }
1329             g_strfreev(keys);
1330         }
1331                 const gchar *dir = g_get_user_special_dir (G_USER_DIRECTORY_VIDEOS);
1332                 g_key_file_set_value(prefsKeyFile, "Preferences", "destination_dir", dir);
1333                 store_key_file(prefsKeyFile, "preferences");
1334     }
1335         g_free(config);
1336         keys = g_key_file_get_keys(internalKeyFile, "Preferences", &length, NULL);
1337     if (keys != NULL)
1338     {
1339             for (ii = 0; keys[ii] != NULL; ii++)
1340             {
1341                     value = g_key_file_get_value(prefsKeyFile, "Preferences", keys[ii], NULL);
1342                     if (value != NULL)
1343                     {
1344                             ghb_settings_set_string(ud->settings, keys[ii], value);
1345                                 ghb_ui_update(ud, keys[ii], value);
1346                             g_free(value);
1347                     }
1348             else
1349             {
1350                         value = g_key_file_get_value(internalKeyFile, "Preferences", keys[ii], NULL);
1351                         if (value != NULL)
1352                         {
1353                                 ghb_settings_set_string(ud->settings, keys[ii], value);
1354                                         ghb_ui_update(ud, keys[ii], value);
1355                                 g_free(value);
1356                         }
1357             }
1358             }
1359         g_strfreev(keys);
1360     }
1361         gint bval = ghb_settings_get_int(ud->settings, "show_presets");
1362         ghb_ui_update_int(ud, "show_presets", bval);
1363         if (ghb_settings_get_bool(ud->settings, "hbfd_feature"))
1364         {
1365                 GtkAction *action;
1366                 bval = ghb_settings_get_int(ud->settings, "hbfd");
1367                 ghb_ui_update_int(ud, "hbfd", bval);
1368                 action = GHB_ACTION (ud->builder, "hbfd");
1369                 gtk_action_set_visible(action, TRUE);
1370         }
1371         else
1372         {
1373                 ghb_ui_update_int(ud, "hbfd", 0);
1374         }
1375         prefs_initializing = FALSE;
1376 }
1377
1378 void
1379 ghb_presets_load(signal_user_data_t *ud)
1380 {
1381         const gchar *dir;
1382         gchar *config;
1383         GHashTable *settings = ud->settings;
1384
1385         g_debug("ghb_presets_load()\n");
1386         customKeyFile = g_key_file_new();
1387         standardKeyFile = g_key_file_new();
1388         dir = g_get_user_config_dir();
1389         config = g_strdup_printf ("%s/ghb/custom_presets", dir);
1390         if (g_file_test(config, G_FILE_TEST_IS_REGULAR))
1391         {
1392                 g_key_file_load_from_file( customKeyFile, config, 
1393                                                                   G_KEY_FILE_KEEP_COMMENTS, NULL);
1394         }
1395         g_free(config);
1396         // Try current dir first. Makes testing prior to installation easier
1397         if (g_file_test("./standard_presets", G_FILE_TEST_IS_REGULAR))
1398         {
1399                 g_key_file_load_from_file( standardKeyFile, "./standard_presets", 
1400                                                                   G_KEY_FILE_KEEP_COMMENTS, NULL);
1401         }
1402         else
1403         {
1404                 // Try users config dir
1405                 config = g_strdup_printf ("%s/ghb/standard_presets", dir);
1406                 if (g_file_test(config, G_FILE_TEST_IS_REGULAR))
1407                 {
1408                         g_key_file_load_from_file( standardKeyFile, config, 
1409                                                                           G_KEY_FILE_KEEP_COMMENTS, NULL);
1410                         g_free(config);
1411                 }
1412                 else
1413                 {
1414                         const gchar* const *dirs;
1415                         gint ii;
1416                         g_free(config);
1417                         dirs = g_get_system_data_dirs();
1418                         if (dirs != NULL)
1419                         {
1420                                 for (ii = 0; dirs[ii] != NULL; ii++)
1421                                 {
1422                                         config = g_strdup_printf("%s/ghb/standard_presets", dirs[ii]);
1423                                         if (g_file_test(config, G_FILE_TEST_IS_REGULAR))
1424                                         {
1425                                                 g_key_file_load_from_file( standardKeyFile, config, 
1426                                                                                                   G_KEY_FILE_KEEP_COMMENTS, NULL);
1427                                                 break;
1428                                         }
1429                                         g_free(config);
1430                                 }
1431                         }
1432                 }
1433         }
1434         build_presets_list(settings);
1435 }
1436
1437 static void
1438 presets_store()
1439 {
1440         g_debug("presets_store ()\n");
1441         store_key_file(customKeyFile, "custom_presets");
1442 }
1443
1444 typedef struct
1445 {
1446         const gchar *name;
1447         GKeyFile *keyFile;
1448         gboolean autoscale;
1449 } store_key_info_t;
1450
1451 static void
1452 store_to_key_file(gpointer xkey, gpointer xvalue, gpointer xski)
1453 {
1454         store_key_info_t *ski = (store_key_info_t*)xski;
1455         setting_value_t *value = (setting_value_t *)xvalue;
1456         gchar *key = (gchar*)xkey;
1457         gchar *str;
1458
1459         if (!ski->autoscale)
1460         {
1461                 if (strcmp(key, "scale_width"))
1462                 {
1463                         key = "max_width";
1464                 }
1465                 if (strcmp(key, "scale_height"))
1466                 {
1467                         key = "max_height";
1468                 }
1469         }
1470         str = g_key_file_get_string(internalKeyFile, "Presets", key, NULL);
1471         if (str == NULL)
1472         {
1473                 g_debug("Setting (%s) is not in defaults\n", (gchar*)key);
1474                 return;
1475         }
1476         g_debug("comparing: key (%s) -- (%s) == (%s)\n", (gchar*)key, str, value->svalue);
1477         if (strcmp(str, value->shortOpt) != 0)
1478         {
1479                 // Differs from default value.  Store it.
1480                 g_debug("storing: key (%s) -- (%s)\n", (gchar*)key, value->shortOpt);
1481                 gchar *tmp = g_strescape (value->shortOpt, NULL);
1482                 g_key_file_set_value(ski->keyFile, ski->name, (gchar*)key, tmp);
1483                 g_free(tmp);
1484         }
1485         else
1486         {
1487                 // Remove it if it exists already in keyfile
1488                 g_key_file_remove_key (ski->keyFile, ski->name, (gchar*)key, NULL);
1489         }
1490         g_free(str);
1491 }
1492
1493 void
1494 ghb_settings_save(signal_user_data_t *ud, const gchar *name)
1495 {
1496         store_key_info_t ski;
1497
1498         g_debug("ghb_settings_save ()\n");
1499         ski.name = name;
1500         ski.keyFile = customKeyFile;
1501         ski.autoscale = ghb_settings_get_bool (ud->settings, "autoscale");
1502         g_hash_table_foreach(ud->settings, store_to_key_file, &ski);
1503         presets_store();
1504         build_presets_list(ud->settings);
1505         ud->dont_clear_presets = TRUE;
1506         ghb_set_preset (ud, name);
1507         ud->dont_clear_presets = FALSE;
1508 }
1509
1510 // Checks to see if the preset is in standard presets
1511 // I allow standard to be overridden by adding a preset with the
1512 // same name to the custom list.  So to determine if the named 
1513 // preset is standard, I must first check to see if is in the
1514 // custom list.
1515 gboolean
1516 ghb_presets_is_standard(const gchar *name)
1517 {
1518         g_debug("ghb_presets_is_standard()\n");
1519         if (g_key_file_has_group(customKeyFile, name))
1520         {
1521                 // The preset is in the custom list, so it
1522                 // can not be a standard.
1523                 return FALSE;
1524         }
1525         return g_key_file_has_group(standardKeyFile, name);
1526 }
1527
1528 // This function will not remove presets from the standard preset list.
1529 // Return false if attempt is made.
1530 gboolean
1531 ghb_presets_remove(GHashTable *settings, const gchar *name)
1532 {
1533         g_debug("ghb_presets_remove()\n");
1534         if (g_key_file_has_group(customKeyFile, name))
1535         {
1536                 g_debug("\t removing %s\n", name);
1537                 g_key_file_remove_group(customKeyFile, name, NULL);
1538                 presets_store();
1539                 build_presets_list(settings);
1540                 return TRUE;
1541         }
1542         return FALSE;
1543 }
1544