OSDN Git Service

Bump ffmpeg from 22950 to 25082
[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 const gchar*
183 ghb_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         name = gtk_buildable_get_name(GTK_BUILDABLE(widget));
190                 
191         if (name == NULL)
192         {
193                 // Bad widget pointer?  Should never happen.
194                 g_debug("Bad widget\n");
195                 return NULL;
196         }
197         return name;
198 }
199
200 GValue*
201 ghb_widget_value(GtkWidget *widget)
202 {
203         GValue *value = NULL;
204         const gchar *name;
205         GType type;
206         
207         if (widget == NULL)
208         {
209                 g_debug("NULL widget\n");
210                 return NULL;
211         }
212
213         type = GTK_WIDGET_TYPE(widget);
214         name = ghb_get_setting_key(widget);
215         g_debug("ghb_widget_value widget (%s)\n", name);
216         if (type == GTK_TYPE_ENTRY)
217         {
218                 const gchar *str = gtk_entry_get_text(GTK_ENTRY(widget));
219                 value = ghb_string_value_new(str);
220         }
221         else if (type == GTK_TYPE_RADIO_BUTTON)
222         {
223                 g_debug("\tradio_button");
224                 gboolean bval;
225                 bval = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
226                 value = ghb_boolean_value_new(bval);
227         }
228         else if (type == GTK_TYPE_CHECK_BUTTON)
229         {
230                 g_debug("\tcheck_button");
231                 gboolean bval;
232                 bval = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
233                 value = ghb_boolean_value_new(bval);
234         }
235         else if (type == GTK_TYPE_TOGGLE_TOOL_BUTTON)
236         {
237                 g_debug("\ttoggle_tool_button");
238                 gboolean bval;
239                 bval = gtk_toggle_tool_button_get_active(GTK_TOGGLE_TOOL_BUTTON(widget));
240                 value = ghb_boolean_value_new(bval);
241         }
242         else if (type == GTK_TYPE_TOGGLE_BUTTON)
243         {
244                 g_debug("\ttoggle_button");
245                 gboolean bval;
246                 bval = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
247                 value = ghb_boolean_value_new(bval);
248         }
249         else if (type == GTK_TYPE_TOGGLE_ACTION)
250         {
251                 g_debug("\ttoggle action");
252                 gboolean bval;
253                 bval = gtk_toggle_action_get_active(GTK_TOGGLE_ACTION(widget));
254                 value = ghb_boolean_value_new(bval);
255         }
256         else if (type == GTK_TYPE_CHECK_MENU_ITEM)
257         {
258                 g_debug("\tcheck_menu_item");
259                 gboolean bval;
260                 bval = gtk_check_menu_item_get_active(GTK_CHECK_MENU_ITEM(widget));
261                 value = ghb_boolean_value_new(bval);
262         }
263         else if (type == GTK_TYPE_COMBO_BOX)
264         {
265                 g_debug("\tcombo_box");
266                 GtkTreeModel *store;
267                 GtkTreeIter iter;
268                 gchar *shortOpt;
269
270                 store = gtk_combo_box_get_model(GTK_COMBO_BOX(widget));
271                 if (gtk_combo_box_get_active_iter(GTK_COMBO_BOX(widget), &iter))
272                 {
273                         gtk_tree_model_get(store, &iter, 2, &shortOpt, -1);
274                         value = ghb_string_value_new(shortOpt);
275                         g_free(shortOpt);
276                 }
277                 else
278                 {
279                         value = ghb_string_value_new("");
280                 }
281         }
282         else if (type == GTK_TYPE_COMBO_BOX_ENTRY)
283         {
284                 GtkTreeModel *store;
285                 GtkTreeIter iter;
286                 gchar *shortOpt;
287
288                 g_debug("\tcombo_box_entry");
289                 store = gtk_combo_box_get_model(GTK_COMBO_BOX(widget));
290                 if (gtk_combo_box_get_active_iter(GTK_COMBO_BOX(widget), &iter))
291                 {
292                         gtk_tree_model_get(store, &iter, 2, &shortOpt, -1);
293                         value = ghb_string_value_new(shortOpt);
294                         g_free(shortOpt);
295                 }
296                 else
297                 {
298                         const gchar *str;
299                         str = gtk_combo_box_get_active_text(GTK_COMBO_BOX(widget));
300                         if (str == NULL) str = "";
301                         value = ghb_string_value_new(str);
302                 }
303         }
304         else if (type == GTK_TYPE_SPIN_BUTTON)
305         {
306                 gint ival;
307                 ival = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(widget));
308                 value = ghb_int64_value_new(ival);
309         }
310         else if (type == GTK_TYPE_HSCALE)
311         {
312                 gdouble dval;
313                 gint digits;
314
315                 digits = gtk_scale_get_digits(GTK_SCALE(widget));
316                 dval = gtk_range_get_value(GTK_RANGE(widget));
317                 if (digits)
318                 {
319                         value = ghb_double_value_new(dval);
320                 }
321                 else
322                 {
323                         value = ghb_int_value_new(dval);
324                 }
325         }
326         else if (type == GTK_TYPE_SCALE_BUTTON)
327         {
328                 gdouble dval;
329
330                 dval = gtk_scale_button_get_value(GTK_SCALE_BUTTON(widget));
331                 value = ghb_double_value_new(dval);
332         }
333         else if (type == GTK_TYPE_TEXT_VIEW)
334         {
335                 GtkTextBuffer *buffer;
336                 GtkTextIter start, end;
337                 gchar *str;
338
339                 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(widget));
340                 gtk_text_buffer_get_bounds(buffer, &start, &end);
341                 str = gtk_text_buffer_get_text(buffer, &start, &end, FALSE);
342                 value = ghb_string_value_new(str);
343                 g_free(str);
344         }
345         else if (type == GTK_TYPE_LABEL)
346         {
347                 const gchar *str;
348                 str = gtk_label_get_text (GTK_LABEL(widget));
349                 value = ghb_string_value_new(str);
350         }
351         else if (type == GTK_TYPE_FILE_CHOOSER_BUTTON)
352         {
353                 gchar *str;
354                 str = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(widget));
355                 if (str == NULL)
356                         str = gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(widget));
357                 value = ghb_string_value_new(str);
358                 if (str != NULL)
359                         g_free(str);
360         }
361         else
362         {
363                 g_debug("Attempt to set unknown widget type: %s\n", name);
364                 g_free(value);
365                 value = NULL;
366         }
367         return value;
368 }
369
370 gchar*
371 ghb_widget_string(GtkWidget *widget)
372 {
373         GValue *value;
374         gchar *sval;
375         
376         value = ghb_widget_value(widget);
377         sval = ghb_value_string(value);
378         ghb_value_free(value);
379         return sval;
380 }
381
382 gdouble
383 ghb_widget_double(GtkWidget *widget)
384 {
385         GValue *value;
386         gdouble dval;
387         
388         value = ghb_widget_value(widget);
389         dval = ghb_value_double(value);
390         ghb_value_free(value);
391         return dval;
392 }
393
394 gint64
395 ghb_widget_int64(GtkWidget *widget)
396 {
397         GValue *value;
398         gint64 ival;
399         
400         value = ghb_widget_value(widget);
401         ival = ghb_value_int64(value);
402         ghb_value_free(value);
403         return ival;
404 }
405
406 gint
407 ghb_widget_int(GtkWidget *widget)
408 {
409         GValue *value;
410         gint ival;
411         
412         value = ghb_widget_value(widget);
413         ival = (gint)ghb_value_int64(value);
414         ghb_value_free(value);
415         return ival;
416 }
417
418 gint
419 ghb_widget_boolean(GtkWidget *widget)
420 {
421         GValue *value;
422         gboolean bval;
423         
424         value = ghb_widget_value(widget);
425         bval = ghb_value_boolean(value);
426         ghb_value_free(value);
427         return bval;
428 }
429
430 void
431 ghb_widget_to_setting(GValue *settings, GtkWidget *widget)
432 {
433         const gchar *key = NULL;
434         GValue *value;
435         
436         if (widget == NULL) return;
437         g_debug("ghb_widget_to_setting");
438         // Find corresponding setting
439         key = ghb_get_setting_key(widget);
440         if (key == NULL) return;
441         value = ghb_widget_value(widget);
442         if (value != NULL)
443         {
444                 ghb_settings_take_value(settings, key, value);
445         }
446         else
447         {
448                 g_debug("No value found for %s\n", key);
449         }
450 }
451
452 static void
453 update_widget(GtkWidget *widget, const GValue *value)
454 {
455         GType type;
456         gchar *str;
457         gint ival;
458         gdouble dval;
459
460         g_debug("update_widget");
461         type = G_VALUE_TYPE(value);
462         if (type == ghb_array_get_type() || type == ghb_dict_get_type())
463                 return;
464         if (value == NULL) return;
465         str = ghb_value_string(value);
466         ival = ghb_value_int(value);
467         dval = ghb_value_double(value);
468         type = GTK_OBJECT_TYPE(widget);
469         if (type == GTK_TYPE_ENTRY)
470         {
471                 g_debug("entry");
472                 gtk_entry_set_text((GtkEntry*)widget, str);
473         }
474         else if (type == GTK_TYPE_RADIO_BUTTON)
475         {
476                 g_debug("radio button");
477                 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), ival);
478         }
479         else if (type == GTK_TYPE_CHECK_BUTTON)
480         {
481                 g_debug("check button");
482                 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), ival);
483         }
484         else if (type == GTK_TYPE_TOGGLE_TOOL_BUTTON)
485         {
486                 g_debug("toggle button");
487                 gtk_toggle_tool_button_set_active(GTK_TOGGLE_TOOL_BUTTON(widget), ival);
488         }
489         else if (type == GTK_TYPE_TOGGLE_BUTTON)
490         {
491                 g_debug("toggle button");
492                 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), ival);
493         }
494         else if (type == GTK_TYPE_TOGGLE_ACTION)
495         {
496                 g_debug("toggle action");
497                 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(widget), ival);
498         }
499         else if (type == GTK_TYPE_CHECK_MENU_ITEM)
500         {
501                 g_debug("check menu item");
502                 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(widget), ival);
503         }
504         else if (type == GTK_TYPE_COMBO_BOX)
505         {
506                 GtkTreeModel *store;
507                 GtkTreeIter iter;
508                 gchar *shortOpt;
509                 gdouble ivalue;
510                 gboolean foundit = FALSE;
511
512                 g_debug("combo (%s)", str);
513                 store = gtk_combo_box_get_model(GTK_COMBO_BOX(widget));
514                 if (gtk_tree_model_get_iter_first (store, &iter))
515                 {
516                         do
517                         {
518                                 gtk_tree_model_get(store, &iter, 2, &shortOpt, -1);
519                                 if (strcmp(shortOpt, str) == 0)
520                                 {
521                                         gtk_combo_box_set_active_iter (
522                                                 GTK_COMBO_BOX(widget), &iter);
523                                         g_free(shortOpt);
524                                         foundit = TRUE;
525                                         break;
526                                 }
527                                 g_free(shortOpt);
528                         } while (gtk_tree_model_iter_next (store, &iter));
529                 }
530                 if (!foundit && gtk_tree_model_get_iter_first (store, &iter))
531                 {
532                         do
533                         {
534                                 gtk_tree_model_get(store, &iter, 3, &ivalue, -1);
535                                 if ((gint)ivalue == ival || ivalue == dval)
536                                 {
537                                         gtk_combo_box_set_active_iter (
538                                                 GTK_COMBO_BOX(widget), &iter);
539                                         foundit = TRUE;
540                                         break;
541                                 }
542                         } while (gtk_tree_model_iter_next (store, &iter));
543                 }
544                 if (!foundit)
545                 {
546                         gtk_combo_box_set_active (GTK_COMBO_BOX(widget), 0);
547                 }
548         }
549         else if (type == GTK_TYPE_COMBO_BOX_ENTRY)
550         {
551                 GtkTreeModel *store;
552                 GtkTreeIter iter;
553                 gchar *shortOpt;
554                 gdouble ivalue;
555                 gboolean foundit = FALSE;
556
557                 g_debug("GTK_COMBO_BOX_ENTRY");
558                 store = gtk_combo_box_get_model(GTK_COMBO_BOX(widget));
559                 if (gtk_tree_model_get_iter_first (store, &iter))
560                 {
561                         do
562                         {
563                                 gtk_tree_model_get(store, &iter, 2, &shortOpt, -1);
564                                 if (strcmp(shortOpt, str) == 0)
565                                 {
566                                         gtk_combo_box_set_active_iter (
567                                                 GTK_COMBO_BOX(widget), &iter);
568                                         g_free(shortOpt);
569                                         foundit = TRUE;
570                                         break;
571                                 }
572                                 g_free(shortOpt);
573                         } while (gtk_tree_model_iter_next (store, &iter));
574                 }
575                 if (!foundit && gtk_tree_model_get_iter_first (store, &iter))
576                 {
577                         do
578                         {
579                                 gtk_tree_model_get(store, &iter, 3, &ivalue, -1);
580                                 if ((gint)ivalue == ival || ivalue == dval)
581                                 {
582                                         gtk_combo_box_set_active_iter (
583                                                 GTK_COMBO_BOX(widget), &iter);
584                                         foundit = TRUE;
585                                         break;
586                                 }
587                         } while (gtk_tree_model_iter_next (store, &iter));
588                 }
589                 if (!foundit)
590                 {
591                         GtkEntry *entry = GTK_ENTRY(gtk_bin_get_child(GTK_BIN(widget)));
592                         if (entry)
593                         {
594                                 gtk_entry_set_text (entry, str);
595                         }
596                 }
597         }
598         else if (type == GTK_TYPE_SPIN_BUTTON)
599         {
600                 g_debug("spin (%s)", str);
601                 gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), dval);
602         }
603         else if (type == GTK_TYPE_HSCALE)
604         {
605                 g_debug("hscale");
606                 gtk_range_set_value(GTK_RANGE(widget), dval);
607         }
608         else if (type == GTK_TYPE_SCALE_BUTTON)
609         {
610                 g_debug("scale_button");
611                 gtk_scale_button_set_value(GTK_SCALE_BUTTON(widget), dval);
612         }
613         else if (type == GTK_TYPE_TEXT_VIEW)
614         {
615                 g_debug("textview (%s)", str);
616                 GtkTextBuffer *buffer = gtk_text_view_get_buffer(
617                                                                                                 GTK_TEXT_VIEW(widget));
618                 gtk_text_buffer_set_text (buffer, str, -1);
619         }
620         else if (type == GTK_TYPE_LABEL)
621         {
622                 gtk_label_set_markup (GTK_LABEL(widget), str);
623         }
624         else if (type == GTK_TYPE_FILE_CHOOSER_BUTTON)
625         {
626                 GtkFileChooserAction act;
627                 act = gtk_file_chooser_get_action(GTK_FILE_CHOOSER(widget));
628                 if (str[0] == 0)
629                 {
630                         // Do nothing
631                         ;
632                 }
633                 else if (act == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
634                         act == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
635                 {
636                         gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(widget), str);
637                 }
638                 else if (act == GTK_FILE_CHOOSER_ACTION_SAVE)
639                 {
640                         gtk_file_chooser_set_filename (GTK_FILE_CHOOSER(widget), str);
641                 }
642                 else
643                 {
644                         if (g_file_test(str, G_FILE_TEST_IS_DIR))
645                         {
646                                 gtk_file_chooser_set_current_folder(
647                                         GTK_FILE_CHOOSER(widget), str);
648                         }
649                         else if (g_file_test(str, G_FILE_TEST_EXISTS))
650                         {
651                                 gtk_file_chooser_set_filename (GTK_FILE_CHOOSER(widget), str);
652                         }
653                         else
654                         {
655                                 gchar *dirname;
656
657                                 dirname = g_path_get_dirname(str);
658                                 gtk_file_chooser_set_current_folder(
659                                         GTK_FILE_CHOOSER(widget), dirname);
660                                 g_free(dirname);
661                         }
662                 }
663         }
664         else
665         {
666                 g_debug("Attempt to set unknown widget type");
667         }
668         g_free(str);
669 }
670
671 int
672 ghb_ui_update(signal_user_data_t *ud, const gchar *name, const GValue *value)
673 {
674         GObject *object;
675
676         g_debug("ghb_ui_update() %s", name);
677         if (name == NULL || value == NULL)
678                 return 0;
679         object = GHB_OBJECT(ud->builder, name);
680         if (object == NULL)
681         {
682                 g_debug("Failed to find widget for key: %s\n", name);
683                 return -1;
684         }
685         update_widget((GtkWidget*)object, value);
686         // Its possible the value hasn't changed. Since settings are only
687         // updated when the value changes, I'm initializing settings here as well.
688         ghb_widget_to_setting(ud->settings, (GtkWidget*)object);
689         return 0;
690 }
691