OSDN Git Service

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