OSDN Git Service

LinGui: add mbtree checkbox to x264 settings tab
[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 #include "values.h"
23
24 void dump_settings(GValue *settings);
25 void ghb_pref_audio_init(signal_user_data_t *ud);
26
27 GObject*
28 debug_get_object(GtkBuilder* b, const gchar *n)
29 {
30         g_message("name %s\n", n);
31         return gtk_builder_get_object(b, n);
32 }
33
34 GValue*
35 ghb_settings_new()
36 {
37         return ghb_dict_value_new();
38 }
39
40 void
41 ghb_settings_set_value(
42         GValue *settings, 
43         const gchar *key, 
44         const GValue *value)
45 {
46         if (key == NULL || value == NULL)
47                 return;
48         ghb_dict_insert(settings, g_strdup(key), ghb_value_dup(value));
49 }
50
51 void
52 ghb_settings_take_value(GValue *settings, const gchar *key, GValue *value)
53 {
54         ghb_dict_insert(settings, g_strdup(key), value);
55 }
56
57 void
58 ghb_settings_set_string(
59         GValue *settings, 
60         const gchar *key, 
61         const gchar *sval)
62 {
63         GValue *value;
64         value = ghb_string_value_new(sval);
65         ghb_dict_insert(settings, g_strdup(key), value);
66 }
67
68 void
69 ghb_settings_set_double(GValue *settings, const gchar *key, gdouble dval)
70 {
71         GValue *value;
72         value = ghb_double_value_new(dval);
73         ghb_dict_insert(settings, g_strdup(key), value);
74 }
75
76 void
77 ghb_settings_set_int64(GValue *settings, const gchar *key, gint64 ival)
78 {
79         GValue *value;
80         value = ghb_int64_value_new(ival);
81         ghb_dict_insert(settings, g_strdup(key), value);
82 }
83
84 void
85 ghb_settings_set_int(GValue *settings, const gchar *key, gint ival)
86 {
87         GValue *value;
88         value = ghb_int64_value_new((gint64)ival);
89         ghb_dict_insert(settings, g_strdup(key), value);
90 }
91
92 void
93 ghb_settings_set_boolean(GValue *settings, const gchar *key, gboolean bval)
94 {
95         GValue *value;
96         value = ghb_boolean_value_new(bval);
97         ghb_dict_insert(settings, g_strdup(key), value);
98 }
99
100 GValue*
101 ghb_settings_get_value(const GValue *settings, const gchar *key)
102 {
103         GValue *value;
104         value = ghb_dict_lookup(settings, key);
105         if (value == NULL)
106                 g_warning("returning null (%s)", key);
107         return value;
108 }
109
110 gboolean
111 ghb_settings_get_boolean(const GValue *settings, const gchar *key)
112 {
113         const GValue* value;
114         value = ghb_settings_get_value(settings, key);
115         if (value == NULL) return FALSE;
116         return ghb_value_boolean(value);
117 }
118
119 gint64
120 ghb_settings_get_int64(const GValue *settings, const gchar *key)
121 {
122         const GValue* value;
123         value = ghb_settings_get_value(settings, key);
124         if (value == NULL) return 0;
125         return ghb_value_int64(value);
126 }
127
128 gint
129 ghb_settings_get_int(const GValue *settings, const gchar *key)
130 {
131         const GValue* value;
132         value = ghb_settings_get_value(settings, key);
133         if (value == NULL) return 0;
134         return ghb_value_int(value);
135 }
136
137 gdouble
138 ghb_settings_get_double(const GValue *settings, const gchar *key)
139 {
140         const GValue* value;
141         value = ghb_settings_get_value(settings, key);
142         if (value == NULL) return 0;
143         return ghb_value_double(value);
144 }
145
146 gchar*
147 ghb_settings_get_string(const GValue *settings, const gchar *key)
148 {
149         const GValue* value;
150         value = ghb_settings_get_value(settings, key);
151         if (value == NULL) return g_strdup("");
152         return ghb_value_string(value);
153 }
154
155 gint
156 ghb_settings_combo_int(const GValue *settings, const gchar *key)
157 {
158         return ghb_lookup_combo_int(key, ghb_settings_get_value(settings, key));
159 }
160
161 gdouble
162 ghb_settings_combo_double(const GValue *settings, const gchar *key)
163 {
164         return ghb_lookup_combo_double(key, ghb_settings_get_value(settings, key));
165 }
166
167 const gchar*
168 ghb_settings_combo_option(const GValue *settings, const gchar *key)
169 {
170         return ghb_lookup_combo_option(key, ghb_settings_get_value(settings, key));
171 }
172
173 const gchar*
174 ghb_settings_combo_string(const GValue *settings, const gchar *key)
175 {
176         return ghb_lookup_combo_string(key, ghb_settings_get_value(settings, key));
177 }
178
179 // Map widget names to setting keys
180 // Widgets that map to settings have names
181 // of this format: s_<setting key>
182 static const gchar*
183 get_setting_key(GtkWidget *widget)
184 {
185         const gchar *name;
186         
187         g_debug("get_setting_key ()\n");
188         if (widget == NULL) return NULL;
189         if (GTK_IS_ACTION(widget))
190                 name = gtk_action_get_name(GTK_ACTION(widget));
191         else
192                 name = gtk_widget_get_name(widget);
193                 
194         if (name == NULL)
195         {
196                 // Bad widget pointer?  Should never happen.
197                 g_debug("Bad widget\n");
198                 return NULL;
199         }
200         return name;
201 }
202
203 GValue*
204 ghb_widget_value(GtkWidget *widget)
205 {
206         GValue *value = NULL;
207         const gchar *name;
208         GType type;
209         
210         if (widget == NULL)
211         {
212                 g_debug("NULL widget\n");
213                 return NULL;
214         }
215
216         type = GTK_WIDGET_TYPE(widget);
217         if (GTK_IS_ACTION(widget))
218                 name = gtk_action_get_name(GTK_ACTION(widget));
219         else
220                 name = gtk_widget_get_name(widget);
221         g_debug("ghb_widget_value widget (%s)\n", name);
222         if (type == GTK_TYPE_ENTRY)
223         {
224                 const gchar *str = gtk_entry_get_text(GTK_ENTRY(widget));
225                 value = ghb_string_value_new(str);
226         }
227         else if (type == GTK_TYPE_RADIO_BUTTON)
228         {
229                 g_debug("\tradio_button");
230                 gboolean bval;
231                 bval = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
232                 value = ghb_boolean_value_new(bval);
233         }
234         else if (type == GTK_TYPE_CHECK_BUTTON)
235         {
236                 g_debug("\tcheck_button");
237                 gboolean bval;
238                 bval = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
239                 value = ghb_boolean_value_new(bval);
240         }
241         else if (type == GTK_TYPE_TOGGLE_BUTTON)
242         {
243                 g_debug("\ttoggle_button");
244                 gboolean bval;
245                 bval = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
246                 value = ghb_boolean_value_new(bval);
247         }
248         else if (type == GTK_TYPE_TOGGLE_ACTION)
249         {
250                 g_debug("\ttoggle action");
251                 gboolean bval;
252                 bval = gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(widget));
253                 value = ghb_boolean_value_new(bval);
254         }
255         else if (type == GTK_TYPE_CHECK_MENU_ITEM)
256         {
257                 g_debug("\tcheck_menu_item");
258                 gboolean bval;
259                 bval = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget));
260                 value = ghb_boolean_value_new(bval);
261         }
262         else if (type == GTK_TYPE_COMBO_BOX)
263         {
264                 g_debug("\tcombo_box");
265                 GtkTreeModel *store;
266                 GtkTreeIter iter;
267                 gchar *shortOpt;
268
269                 store = gtk_combo_box_get_model(GTK_COMBO_BOX(widget));
270                 if (gtk_combo_box_get_active_iter(GTK_COMBO_BOX(widget), &iter))
271                 {
272                         gtk_tree_model_get(store, &iter, 2, &shortOpt, -1);
273                         value = ghb_string_value_new(shortOpt);
274                         g_free(shortOpt);
275                 }
276                 else
277                 {
278                         value = ghb_string_value_new("");
279                 }
280         }
281         else if (type == GTK_TYPE_COMBO_BOX_ENTRY)
282         {
283                 GtkTreeModel *store;
284                 GtkTreeIter iter;
285                 gchar *shortOpt;
286
287                 g_debug("\tcombo_box_entry");
288                 store = gtk_combo_box_get_model(GTK_COMBO_BOX(widget));
289                 if (gtk_combo_box_get_active_iter(GTK_COMBO_BOX(widget), &iter))
290                 {
291                         gtk_tree_model_get(store, &iter, 2, &shortOpt, -1);
292                         value = ghb_string_value_new(shortOpt);
293                         g_free(shortOpt);
294                 }
295                 else
296                 {
297                         const gchar *str;
298                         str = gtk_combo_box_get_active_text(GTK_COMBO_BOX(widget));
299                         if (str == NULL) str = "";
300                         value = ghb_string_value_new(str);
301                 }
302         }
303         else if (type == GTK_TYPE_SPIN_BUTTON)
304         {
305                 gint ival;
306                 ival = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
307                 value = ghb_int64_value_new(ival);
308         }
309         else if (type == GTK_TYPE_HSCALE)
310         {
311                 gdouble dval;
312                 gint digits;
313
314                 digits = gtk_scale_get_digits(GTK_SCALE(widget));
315                 dval = gtk_range_get_value(GTK_RANGE(widget));
316                 if (digits)
317                 {
318                         value = ghb_double_value_new(dval);
319                 }
320                 else
321                 {
322                         value = ghb_int_value_new(dval);
323                 }
324         }
325         else if (type == GTK_TYPE_SCALE_BUTTON)
326         {
327                 gdouble dval;
328
329                 dval = gtk_scale_button_get_value(GTK_SCALE_BUTTON(widget));
330                 value = ghb_double_value_new(dval);
331         }
332         else if (type == GTK_TYPE_TEXT_VIEW)
333         {
334                 GtkTextBuffer *buffer;
335                 GtkTextIter start, end;
336                 gchar *str;
337
338                 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(widget));
339                 gtk_text_buffer_get_bounds(buffer, &start, &end);
340                 str = gtk_text_buffer_get_text(buffer, &start, &end, FALSE);
341                 value = ghb_string_value_new(str);
342                 g_free(str);
343         }
344         else if (type == GTK_TYPE_LABEL)
345         {
346                 const gchar *str;
347                 str = gtk_label_get_text (GTK_LABEL(widget));
348                 value = ghb_string_value_new(str);
349         }
350         else if (type == GTK_TYPE_FILE_CHOOSER_BUTTON)
351         {
352                 gchar *str;
353                 str = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(widget));
354                 if (str == NULL)
355                         str = gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(widget));
356                 value = ghb_string_value_new(str);
357                 if (str != NULL)
358                         g_free(str);
359         }
360         else
361         {
362                 g_debug("Attempt to set unknown widget type: %s\n", name);
363                 g_free(value);
364                 value = NULL;
365         }
366         return value;
367 }
368
369 gchar*
370 ghb_widget_string(GtkWidget *widget)
371 {
372         GValue *value;
373         gchar *sval;
374         
375         value = ghb_widget_value(widget);
376         sval = ghb_value_string(value);
377         ghb_value_free(value);
378         return sval;
379 }
380
381 gdouble
382 ghb_widget_double(GtkWidget *widget)
383 {
384         GValue *value;
385         gdouble dval;
386         
387         value = ghb_widget_value(widget);
388         dval = ghb_value_double(value);
389         ghb_value_free(value);
390         return dval;
391 }
392
393 gint64
394 ghb_widget_int64(GtkWidget *widget)
395 {
396         GValue *value;
397         gint64 ival;
398         
399         value = ghb_widget_value(widget);
400         ival = ghb_value_int64(value);
401         ghb_value_free(value);
402         return ival;
403 }
404
405 gint
406 ghb_widget_int(GtkWidget *widget)
407 {
408         GValue *value;
409         gint ival;
410         
411         value = ghb_widget_value(widget);
412         ival = (gint)ghb_value_int64(value);
413         ghb_value_free(value);
414         return ival;
415 }
416
417 gint
418 ghb_widget_boolean(GtkWidget *widget)
419 {
420         GValue *value;
421         gboolean bval;
422         
423         value = ghb_widget_value(widget);
424         bval = ghb_value_boolean(value);
425         ghb_value_free(value);
426         return bval;
427 }
428
429 void
430 ghb_widget_to_setting(GValue *settings, GtkWidget *widget)
431 {
432         const gchar *key = NULL;
433         GValue *value;
434         
435         if (widget == NULL) return;
436         g_debug("ghb_widget_to_setting");
437         // Find corresponding setting
438         key = get_setting_key(widget);
439         if (key == NULL) return;
440         value = ghb_widget_value(widget);
441         if (value != NULL)
442         {
443                 ghb_settings_take_value(settings, key, value);
444         }
445         else
446         {
447                 g_debug("No value found for %s\n", key);
448         }
449 }
450
451 static void
452 update_widget(GtkWidget *widget, const GValue *value)
453 {
454         GType type;
455         gchar *str;
456         gint ival;
457         gdouble dval;
458
459         g_debug("update_widget");
460         type = G_VALUE_TYPE(value);
461         if (type == ghb_array_get_type() || type == ghb_dict_get_type())
462                 return;
463         if (value == NULL) return;
464         str = ghb_value_string(value);
465         ival = ghb_value_int(value);
466         dval = ghb_value_double(value);
467         type = GTK_OBJECT_TYPE(widget);
468         if (type == GTK_TYPE_ENTRY)
469         {
470                 g_debug("entry");
471                 gtk_entry_set_text((GtkEntry*)widget, str);
472         }
473         else if (type == GTK_TYPE_RADIO_BUTTON)
474         {
475                 g_debug("radio button");
476                 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), ival);
477         }
478         else if (type == GTK_TYPE_CHECK_BUTTON)
479         {
480                 g_debug("check button");
481                 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), ival);
482         }
483         else if (type == GTK_TYPE_TOGGLE_BUTTON)
484         {
485                 g_debug("toggle button");
486                 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), ival);
487         }
488         else if (type == GTK_TYPE_TOGGLE_ACTION)
489         {
490                 g_debug("toggle action");
491                 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(widget), ival);
492         }
493         else if (type == GTK_TYPE_CHECK_MENU_ITEM)
494         {
495                 g_debug("check menu item");
496                 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(widget), ival);
497         }
498         else if (type == GTK_TYPE_COMBO_BOX)
499         {
500                 GtkTreeModel *store;
501                 GtkTreeIter iter;
502                 gchar *shortOpt;
503                 gdouble ivalue;
504                 gboolean foundit = FALSE;
505
506                 g_debug("combo (%s)", str);
507                 store = gtk_combo_box_get_model(GTK_COMBO_BOX(widget));
508                 if (gtk_tree_model_get_iter_first (store, &iter))
509                 {
510                         do
511                         {
512                                 gtk_tree_model_get(store, &iter, 2, &shortOpt, -1);
513                                 if (strcmp(shortOpt, str) == 0)
514                                 {
515                                         gtk_combo_box_set_active_iter (
516                                                 GTK_COMBO_BOX(widget), &iter);
517                                         g_free(shortOpt);
518                                         foundit = TRUE;
519                                         break;
520                                 }
521                                 g_free(shortOpt);
522                         } while (gtk_tree_model_iter_next (store, &iter));
523                 }
524                 if (!foundit && gtk_tree_model_get_iter_first (store, &iter))
525                 {
526                         do
527                         {
528                                 gtk_tree_model_get(store, &iter, 3, &ivalue, -1);
529                                 if ((gint)ivalue == ival || ivalue == dval)
530                                 {
531                                         gtk_combo_box_set_active_iter (
532                                                 GTK_COMBO_BOX(widget), &iter);
533                                         foundit = TRUE;
534                                         break;
535                                 }
536                         } while (gtk_tree_model_iter_next (store, &iter));
537                 }
538                 if (!foundit)
539                 {
540                         gtk_combo_box_set_active (GTK_COMBO_BOX(widget), 0);
541                 }
542         }
543         else if (type == GTK_TYPE_COMBO_BOX_ENTRY)
544         {
545                 GtkTreeModel *store;
546                 GtkTreeIter iter;
547                 gchar *shortOpt;
548                 gdouble ivalue;
549                 gboolean foundit = FALSE;
550
551                 g_debug("GTK_COMBO_BOX_ENTRY");
552                 store = gtk_combo_box_get_model(GTK_COMBO_BOX(widget));
553                 if (gtk_tree_model_get_iter_first (store, &iter))
554                 {
555                         do
556                         {
557                                 gtk_tree_model_get(store, &iter, 2, &shortOpt, -1);
558                                 if (strcmp(shortOpt, str) == 0)
559                                 {
560                                         gtk_combo_box_set_active_iter (
561                                                 GTK_COMBO_BOX(widget), &iter);
562                                         g_free(shortOpt);
563                                         foundit = TRUE;
564                                         break;
565                                 }
566                                 g_free(shortOpt);
567                         } while (gtk_tree_model_iter_next (store, &iter));
568                 }
569                 if (!foundit && gtk_tree_model_get_iter_first (store, &iter))
570                 {
571                         do
572                         {
573                                 gtk_tree_model_get(store, &iter, 3, &ivalue, -1);
574                                 if ((gint)ivalue == ival || ivalue == dval)
575                                 {
576                                         gtk_combo_box_set_active_iter (
577                                                 GTK_COMBO_BOX(widget), &iter);
578                                         foundit = TRUE;
579                                         break;
580                                 }
581                         } while (gtk_tree_model_iter_next (store, &iter));
582                 }
583                 if (!foundit)
584                 {
585                         GtkEntry *entry = GTK_ENTRY(gtk_bin_get_child(GTK_BIN(widget)));
586                         if (entry)
587                         {
588                                 gtk_entry_set_text (entry, str);
589                         }
590                 }
591         }
592         else if (type == GTK_TYPE_SPIN_BUTTON)
593         {
594                 g_debug("spin (%s)", str);
595                 gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), dval);
596         }
597         else if (type == GTK_TYPE_HSCALE)
598         {
599                 g_debug("hscale");
600                 gtk_range_set_value(GTK_RANGE(widget), dval);
601         }
602         else if (type == GTK_TYPE_SCALE_BUTTON)
603         {
604                 g_debug("scale_button");
605                 gtk_scale_button_set_value(GTK_SCALE_BUTTON(widget), dval);
606         }
607         else if (type == GTK_TYPE_TEXT_VIEW)
608         {
609                 g_debug("textview (%s)", str);
610                 GtkTextBuffer *buffer = gtk_text_view_get_buffer(
611                                                                                                 GTK_TEXT_VIEW(widget));
612                 gtk_text_buffer_set_text (buffer, str, -1);
613         }
614         else if (type == GTK_TYPE_LABEL)
615         {
616                 gtk_label_set_text (GTK_LABEL(widget), str);
617         }
618         else if (type == GTK_TYPE_FILE_CHOOSER_BUTTON)
619         {
620                 GtkFileChooserAction act;
621                 act = gtk_file_chooser_get_action(GTK_FILE_CHOOSER(widget));
622                 if (act == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
623                         act == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
624                 {
625                         gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(widget), str);
626                 }
627                 else if (act == GTK_FILE_CHOOSER_ACTION_SAVE)
628                 {
629                         gtk_file_chooser_set_filename (GTK_FILE_CHOOSER(widget), str);
630                 }
631                 else
632                 {
633                         if (!g_file_test(str, G_FILE_TEST_IS_DIR))
634                         {
635                                 gchar *dirname;
636
637                                 dirname = g_path_get_dirname(str);
638                                 gtk_file_chooser_set_current_folder(
639                                         GTK_FILE_CHOOSER(widget), dirname);
640                                 g_free(dirname);
641                         }
642                         else
643                         {
644                                 gtk_file_chooser_set_current_folder(
645                                         GTK_FILE_CHOOSER(widget), str);
646                         }
647                 }
648         }
649         else
650         {
651                 g_debug("Attempt to set unknown widget type");
652         }
653         g_free(str);
654 }
655
656 int
657 ghb_ui_update(signal_user_data_t *ud, const gchar *name, const GValue *value)
658 {
659         GObject *object;
660
661         g_debug("ghb_ui_update() %s", name);
662         if (name == NULL || value == NULL)
663                 return 0;
664         object = GHB_OBJECT(ud->builder, name);
665         if (object == NULL)
666         {
667                 g_debug("Failed to find widget for key: %s\n", name);
668                 return -1;
669         }
670         update_widget((GtkWidget*)object, value);
671         // Its possible the value hasn't changed. Since settings are only
672         // updated when the value changes, I'm initializing settings here as well.
673         ghb_widget_to_setting(ud->settings, (GtkWidget*)object);
674         return 0;
675 }
676