OSDN Git Service

LinGui: preference improvements
[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                 const gchar *str;
353                 str = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER(widget));
354                 value = ghb_string_value_new(str);
355         }
356         else
357         {
358                 g_debug("Attempt to set unknown widget type: %s\n", name);
359                 g_free(value);
360                 value = NULL;
361         }
362         return value;
363 }
364
365 gchar*
366 ghb_widget_string(GtkWidget *widget)
367 {
368         GValue *value;
369         gchar *sval;
370         
371         value = ghb_widget_value(widget);
372         sval = ghb_value_string(value);
373         ghb_value_free(value);
374         return sval;
375 }
376
377 gdouble
378 ghb_widget_double(GtkWidget *widget)
379 {
380         GValue *value;
381         gdouble dval;
382         
383         value = ghb_widget_value(widget);
384         dval = ghb_value_double(value);
385         ghb_value_free(value);
386         return dval;
387 }
388
389 gint64
390 ghb_widget_int64(GtkWidget *widget)
391 {
392         GValue *value;
393         gint64 ival;
394         
395         value = ghb_widget_value(widget);
396         ival = ghb_value_int64(value);
397         ghb_value_free(value);
398         return ival;
399 }
400
401 gint
402 ghb_widget_int(GtkWidget *widget)
403 {
404         GValue *value;
405         gint ival;
406         
407         value = ghb_widget_value(widget);
408         ival = (gint)ghb_value_int64(value);
409         ghb_value_free(value);
410         return ival;
411 }
412
413 gint
414 ghb_widget_boolean(GtkWidget *widget)
415 {
416         GValue *value;
417         gboolean bval;
418         
419         value = ghb_widget_value(widget);
420         bval = ghb_value_boolean(value);
421         ghb_value_free(value);
422         return bval;
423 }
424
425 void
426 ghb_widget_to_setting(GValue *settings, GtkWidget *widget)
427 {
428         const gchar *key = NULL;
429         GValue *value;
430         
431         if (widget == NULL) return;
432         g_debug("ghb_widget_to_setting");
433         // Find corresponding setting
434         key = get_setting_key(widget);
435         if (key == NULL) return;
436         value = ghb_widget_value(widget);
437         if (value != NULL)
438         {
439                 ghb_settings_take_value(settings, key, value);
440         }
441         else
442         {
443                 g_debug("No value found for %s\n", key);
444         }
445 }
446
447 static void
448 update_widget(GtkWidget *widget, const GValue *value)
449 {
450         GType type;
451         gchar *str;
452         gint ival;
453         gdouble dval;
454
455         g_debug("update_widget");
456         type = G_VALUE_TYPE(value);
457         if (type == ghb_array_get_type() || type == ghb_dict_get_type())
458                 return;
459         if (value == NULL) return;
460         str = ghb_value_string(value);
461         ival = ghb_value_int(value);
462         dval = ghb_value_double(value);
463         type = GTK_OBJECT_TYPE(widget);
464         if (type == GTK_TYPE_ENTRY)
465         {
466                 g_debug("entry");
467                 gtk_entry_set_text((GtkEntry*)widget, str);
468         }
469         else if (type == GTK_TYPE_RADIO_BUTTON)
470         {
471                 g_debug("radio button");
472                 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), ival);
473         }
474         else if (type == GTK_TYPE_CHECK_BUTTON)
475         {
476                 g_debug("check button");
477                 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), ival);
478         }
479         else if (type == GTK_TYPE_TOGGLE_BUTTON)
480         {
481                 g_debug("toggle button");
482                 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), ival);
483         }
484         else if (type == GTK_TYPE_TOGGLE_ACTION)
485         {
486                 g_debug("toggle action");
487                 gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(widget), ival);
488         }
489         else if (type == GTK_TYPE_CHECK_MENU_ITEM)
490         {
491                 g_debug("check menu item");
492                 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(widget), ival);
493         }
494         else if (type == GTK_TYPE_COMBO_BOX)
495         {
496                 GtkTreeModel *store;
497                 GtkTreeIter iter;
498                 gchar *shortOpt;
499                 gdouble ivalue;
500                 gboolean foundit = FALSE;
501
502                 g_debug("combo (%s)", str);
503                 store = gtk_combo_box_get_model(GTK_COMBO_BOX(widget));
504                 if (gtk_tree_model_get_iter_first (store, &iter))
505                 {
506                         do
507                         {
508                                 gtk_tree_model_get(store, &iter, 2, &shortOpt, -1);
509                                 if (strcmp(shortOpt, str) == 0)
510                                 {
511                                         gtk_combo_box_set_active_iter (
512                                                 GTK_COMBO_BOX(widget), &iter);
513                                         g_free(shortOpt);
514                                         foundit = TRUE;
515                                         break;
516                                 }
517                                 g_free(shortOpt);
518                         } while (gtk_tree_model_iter_next (store, &iter));
519                 }
520                 if (!foundit && gtk_tree_model_get_iter_first (store, &iter))
521                 {
522                         do
523                         {
524                                 gtk_tree_model_get(store, &iter, 3, &ivalue, -1);
525                                 if ((gint)ivalue == ival || ivalue == dval)
526                                 {
527                                         gtk_combo_box_set_active_iter (
528                                                 GTK_COMBO_BOX(widget), &iter);
529                                         foundit = TRUE;
530                                         break;
531                                 }
532                         } while (gtk_tree_model_iter_next (store, &iter));
533                 }
534                 if (!foundit)
535                 {
536                         gtk_combo_box_set_active (GTK_COMBO_BOX(widget), 0);
537                 }
538         }
539         else if (type == GTK_TYPE_COMBO_BOX_ENTRY)
540         {
541                 GtkTreeModel *store;
542                 GtkTreeIter iter;
543                 gchar *shortOpt;
544                 gdouble ivalue;
545                 gboolean foundit = FALSE;
546
547                 g_debug("GTK_COMBO_BOX_ENTRY");
548                 store = gtk_combo_box_get_model(GTK_COMBO_BOX(widget));
549                 if (gtk_tree_model_get_iter_first (store, &iter))
550                 {
551                         do
552                         {
553                                 gtk_tree_model_get(store, &iter, 2, &shortOpt, -1);
554                                 if (strcmp(shortOpt, str) == 0)
555                                 {
556                                         gtk_combo_box_set_active_iter (
557                                                 GTK_COMBO_BOX(widget), &iter);
558                                         g_free(shortOpt);
559                                         foundit = TRUE;
560                                         break;
561                                 }
562                                 g_free(shortOpt);
563                         } while (gtk_tree_model_iter_next (store, &iter));
564                 }
565                 if (!foundit && gtk_tree_model_get_iter_first (store, &iter))
566                 {
567                         do
568                         {
569                                 gtk_tree_model_get(store, &iter, 3, &ivalue, -1);
570                                 if ((gint)ivalue == ival || ivalue == dval)
571                                 {
572                                         gtk_combo_box_set_active_iter (
573                                                 GTK_COMBO_BOX(widget), &iter);
574                                         foundit = TRUE;
575                                         break;
576                                 }
577                         } while (gtk_tree_model_iter_next (store, &iter));
578                 }
579                 if (!foundit)
580                 {
581                         GtkEntry *entry = GTK_ENTRY(gtk_bin_get_child(GTK_BIN(widget)));
582                         if (entry)
583                         {
584                                 gtk_entry_set_text (entry, str);
585                         }
586                 }
587         }
588         else if (type == GTK_TYPE_SPIN_BUTTON)
589         {
590                 g_debug("spin (%s)", str);
591                 gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), dval);
592         }
593         else if (type == GTK_TYPE_HSCALE)
594         {
595                 g_debug("hscale");
596                 gtk_range_set_value(GTK_RANGE(widget), dval);
597         }
598         else if (type == GTK_TYPE_SCALE_BUTTON)
599         {
600                 g_debug("scale_button");
601                 gtk_scale_button_set_value(GTK_SCALE_BUTTON(widget), dval);
602         }
603         else if (type == GTK_TYPE_TEXT_VIEW)
604         {
605                 g_debug("textview (%s)", str);
606                 GtkTextBuffer *buffer = gtk_text_view_get_buffer(
607                                                                                                 GTK_TEXT_VIEW(widget));
608                 gtk_text_buffer_set_text (buffer, str, -1);
609         }
610         else if (type == GTK_TYPE_LABEL)
611         {
612                 gtk_label_set_text (GTK_LABEL(widget), str);
613         }
614         else if (type == GTK_TYPE_FILE_CHOOSER_BUTTON)
615         {
616                 GtkFileChooserAction act;
617                 act = gtk_file_chooser_get_action(GTK_FILE_CHOOSER(widget));
618                 if (act == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER ||
619                         act == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
620                 {
621                         gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(widget), str);
622                 }
623                 else
624                 {
625                         gtk_file_chooser_set_filename (GTK_FILE_CHOOSER(widget), str);
626                 }
627         }
628         else
629         {
630                 g_debug("Attempt to set unknown widget type");
631         }
632         g_free(str);
633 }
634
635 int
636 ghb_ui_update(signal_user_data_t *ud, const gchar *name, const GValue *value)
637 {
638         GObject *object;
639
640         g_debug("ghb_ui_update() %s", name);
641         if (name == NULL || value == NULL)
642                 return 0;
643         object = GHB_OBJECT(ud->builder, name);
644         if (object == NULL)
645         {
646                 g_debug("Failed to find widget for key: %s\n", name);
647                 return -1;
648         }
649         update_widget((GtkWidget*)object, value);
650         // Its possible the value hasn't changed. Since settings are only
651         // updated when the value changes, I'm initializing settings here as well.
652         ghb_widget_to_setting(ud->settings, (GtkWidget*)object);
653         return 0;
654 }
655