OSDN Git Service

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