/* gcompris - board_config_combo.c * * Copyright (C) 2009 Miguel De Izarra * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . */ #include "board_config.h" #include "board_config_common.h" #include /***********************************************/ /* L10n */ /***********************************************/ /** \brief return the list of locales in which GCompris has been translated * even partialy. * * \note The list is calculated at the first call and must not be freed. * Uppon next call, the same list is returned. * * \return a list containing the locales we suport */ GList* gc_locale_gets_list(){ static GList *gcompris_locales_list = NULL; GcomprisProperties *properties = gc_prop_get(); GDir *textdomain_dir; GError **error = NULL; GList *locales = NULL; if(gcompris_locales_list) return(gcompris_locales_list); /* There is no english locale but it exists anyway */ locales = g_list_append(locales, g_strdup("en")); textdomain_dir = g_dir_open (properties->package_locale_dir, 0, error); const gchar *fname; gchar *fname_abs; gchar *catalog; if(textdomain_dir) { while ((fname = g_dir_read_name(textdomain_dir))) { fname_abs = g_strdup_printf("%s/%s", properties->package_locale_dir, fname); if (!g_file_test(fname_abs, G_FILE_TEST_IS_DIR)) continue; catalog = g_strdup_printf("%s/LC_MESSAGES/gcompris.mo", fname_abs); if (g_file_test(catalog, G_FILE_TEST_EXISTS)){ locales = g_list_append(locales, g_strdup(fname)); } g_free (fname_abs); g_free(catalog); } g_dir_close (textdomain_dir); } #if DEBUG /* to find locales list when run from src directory */ if(g_file_test("po", G_FILE_TEST_IS_DIR)) { textdomain_dir= g_dir_open("po",0, error); while((fname = g_dir_read_name(textdomain_dir))) { if(g_str_has_suffix(fname,".po")) locales = g_list_append(locales, g_strndup(fname,2)); } g_dir_close(textdomain_dir); } #endif /* Save it for next call */ gcompris_locales_list = locales; return locales; } void gc_board_config_combo_locales_changed(GtkComboBox *combobox, gpointer data) { _gc_boardconf_key*u = (_gc_boardconf_key*)data; gchar *the_key = g_strdup((gchar *)u->key); gchar *value; gint index = gtk_combo_box_get_active (combobox); if (index == 0) /* Default value of gcompris selected */ value = g_strdup ("NULL"); else value = _get_active_text (combobox); g_hash_table_replace(u->config->hash_conf, (gpointer) the_key, (gpointer) value); } /* key = "locale" */ GtkComboBox* gc_board_config_combo_locales(GcomprisBoardConf *config, gchar *init) { g_return_val_if_fail(config, NULL); GtkWidget *combobox; GtkWidget *hbox = gtk_hbox_new (FALSE, 8); GList *list, *strings; GtkWidget *label_combo; gint init_index = 0; strings = gc_locale_gets_list(); strings = g_list_prepend( strings, _("Default")); if (init) init_index = g_list_position(strings, g_list_find_custom(strings, (gconstpointer) init, (GCompareFunc) strcmp)); if (init_index < 0) init_index=0; gtk_widget_show(hbox); gtk_box_pack_start (GTK_BOX(config->main_conf_box), hbox, FALSE, FALSE, 0); /* Label */ label_combo = gtk_label_new ((gchar *)NULL); gtk_widget_show(label_combo); gtk_box_pack_start (GTK_BOX(hbox), label_combo, FALSE, FALSE, 0); gtk_label_set_justify (GTK_LABEL(label_combo), GTK_JUSTIFY_RIGHT); gtk_label_set_markup (GTK_LABEL(label_combo), _("Select the language\n to use in the board")); combobox = gtk_combo_box_new_text(); gtk_widget_show(combobox); gtk_box_pack_start (GTK_BOX(hbox), combobox, FALSE, FALSE, 0); for (list = strings; list != NULL; list = list->next) gtk_combo_box_append_text (GTK_COMBO_BOX(combobox), list->data); if (g_list_length(strings) > COMBOBOX_COL_MAX) gtk_combo_box_set_wrap_width (GTK_COMBO_BOX(combobox), g_list_length(strings) / COMBOBOX_COL_MAX +1 ); gtk_combo_box_set_active (GTK_COMBO_BOX(combobox), init_index); _gc_boardconf_key *u = g_malloc0(sizeof(_gc_boardconf_key)); u -> key = g_strdup("locale"); u -> config = config; g_signal_connect(G_OBJECT(combobox), "changed", G_CALLBACK(gc_board_config_combo_locales_changed), u); g_signal_connect(G_OBJECT(combobox), "destroy", G_CALLBACK(_gc_destroy_boardconf_key), u); return GTK_COMBO_BOX(combobox); } void gc_board_config_combo_drag_changed(GtkComboBox *combobox, gpointer data) { _gc_boardconf_key *u = (_gc_boardconf_key*)data; gchar *the_key = g_strdup((gchar *)u->key); gchar *value; gint index = gtk_combo_box_get_active (combobox); if (index == 0) /* Default value of gcompris selected */ value = g_strdup ("NULL"); else value = g_strdup_printf("%d", index); g_hash_table_replace(u->config->hash_conf, (gpointer) the_key, (gpointer) value); } /* key = "locale" */ GtkComboBox* gc_board_config_combo_drag(GcomprisBoardConf *config, gint init) { g_return_val_if_fail(config, NULL); GtkWidget *combobox; GtkWidget *hbox = gtk_hbox_new (FALSE, 8); GList *list, *strings; GtkWidget *label_combo; gint init_index; strings = NULL; strings = g_list_prepend( strings, _("Global GCompris mode")); strings = g_list_append( strings, _("Normal")); strings = g_list_append( strings, _("2 clicks")); strings = g_list_append( strings, _("both modes")); if (init < 0) init_index =0; else init_index = init; gtk_widget_show(hbox); gtk_box_pack_start (GTK_BOX(config->main_conf_box), hbox, FALSE, FALSE, 0); /* Label */ label_combo = gtk_label_new ((gchar *)NULL); gtk_widget_show(label_combo); gtk_box_pack_start (GTK_BOX(hbox), label_combo, FALSE, FALSE, 0); gtk_label_set_justify (GTK_LABEL(label_combo), GTK_JUSTIFY_RIGHT); gtk_label_set_markup (GTK_LABEL(label_combo), _("Select the drag and drop mode\n to use in the board")); combobox = gtk_combo_box_new_text(); gtk_widget_show(combobox); gtk_box_pack_start (GTK_BOX(hbox), combobox, FALSE, FALSE, 0); for (list = strings; list != NULL; list = list->next) gtk_combo_box_append_text (GTK_COMBO_BOX(combobox), list->data); if (g_list_length(strings) > COMBOBOX_COL_MAX) gtk_combo_box_set_wrap_width (GTK_COMBO_BOX(combobox), g_list_length(strings) / COMBOBOX_COL_MAX +1 ); gtk_combo_box_set_active (GTK_COMBO_BOX(combobox), init_index); _gc_boardconf_key *u = g_malloc0(sizeof(_gc_boardconf_key)); u->key = g_strdup("drag_mode"); u->config = config; g_signal_connect(G_OBJECT(combobox), "changed", G_CALLBACK(gc_board_config_combo_drag_changed), u); g_signal_connect(G_OBJECT(combobox), "destroy", G_CALLBACK(_gc_destroy_boardconf_key), u); return GTK_COMBO_BOX(combobox); } static gchar *current_locale = NULL; void gc_locale_change(gchar *locale) { if (!locale) return; if (strcmp(locale, "NULL") == 0){ gc_locale_reset(); return; } current_locale = g_strdup(gc_locale_get()); gc_locale_set(locale); } void gc_locale_reset() { if (current_locale == NULL) return; gc_locale_change(current_locale); g_free(current_locale); current_locale = NULL; } /** \brief Search the given file for each locale and returns the locale list * * \param file: the file to search. In order to work, you need to provide a * filename that includes a $LOCALE in it like: * voices/$LOCALE/colors/blue.ogg * * \return a list of locale */ GList* gc_locale_gets_asset_list(const gchar *filename) { GList *locales, *list, *locales_asset = NULL; gchar *abs_filename; locales = gc_locale_gets_list(); for (list = locales; list != NULL; list = list->next) { gchar **tmp; /* Check there is a $LOCALE to replace */ if((tmp = g_strsplit(filename, "$LOCALE", -1))) { gchar locale[6]; gchar *filename2; /* try with the locale */ g_strlcpy(locale, list->data, sizeof(locale)); filename2 = g_strjoinv(locale, tmp); g_warning("trying locale file '%s'\n", filename2); abs_filename = gc_file_find_absolute(filename2); g_free(filename2); g_strfreev(tmp); } else { abs_filename = gc_file_find_absolute(filename); } if(abs_filename) { /* It would be cleaner to provide the real locale name but then we need a way * to get back the locale code from it's name and from the boards * * locales_asset = g_list_append(locales_asset, gc_locale_get_name(list->data)); * */ locales_asset = g_list_append(locales_asset, list->data); g_free(abs_filename); } } return locales_asset; } /* key = "locale_sound" */ GtkComboBox *gc_board_config_combo_locales_asset(GcomprisBoardConf *config, const gchar *label, gchar *init, const gchar *file) { g_return_val_if_fail(config, NULL); GtkWidget *combobox; GtkWidget *hbox = gtk_hbox_new (FALSE, 8); GList *list, *strings; GtkWidget *label_combo; gint init_index = 0; strings = gc_locale_gets_asset_list(file); strings = g_list_prepend( strings, _("Default")); if (init) { init_index = g_list_position(strings, g_list_find_custom(strings, (gconstpointer)init, (GCompareFunc) strcmp)); } if (init_index < 0) init_index=0; gtk_widget_show(hbox); gtk_box_pack_start (GTK_BOX(config->main_conf_box), hbox, FALSE, FALSE, 0); /* Label */ label_combo = gtk_label_new ((gchar *)NULL); gtk_widget_show(label_combo); gtk_box_pack_start (GTK_BOX(hbox), label_combo, FALSE, FALSE, 0); gtk_label_set_justify (GTK_LABEL(label_combo), GTK_JUSTIFY_RIGHT); gtk_label_set_markup (GTK_LABEL(label_combo), label); combobox = gtk_combo_box_new_text(); gtk_widget_show(combobox); gtk_box_pack_start (GTK_BOX(hbox), combobox, FALSE, FALSE, 0); for (list = strings; list != NULL; list = list->next) gtk_combo_box_append_text(GTK_COMBO_BOX(combobox), list->data); if (g_list_length(strings) > COMBOBOX_COL_MAX) gtk_combo_box_set_wrap_width(GTK_COMBO_BOX(combobox), g_list_length(strings) / COMBOBOX_COL_MAX +1 ); gtk_combo_box_set_active (GTK_COMBO_BOX(combobox), init_index); _gc_boardconf_key *u = g_malloc0(sizeof(_gc_boardconf_key)); u -> key = g_strdup("locale_sound"); u -> config = config; g_signal_connect(G_OBJECT(combobox), "destroy", G_CALLBACK(_gc_destroy_boardconf_key), u); g_signal_connect(G_OBJECT(combobox), "changed", G_CALLBACK(gc_board_config_combo_locales_changed), u); return GTK_COMBO_BOX(combobox); } static void _combo_box_changed(GtkComboBox *combobox, gpointer data) { _gc_boardconf_key *u = (_gc_boardconf_key*)data; gchar *the_key = g_strdup(u->key); gchar *value = g_strdup_printf("%s", _get_active_text (combobox)); g_hash_table_replace(u->config->hash_conf, (gpointer) the_key, (gpointer) value); } GtkComboBox *gc_board_config_combo_box(GcomprisBoardConf *config, const gchar *label, GList *strings, gchar *key, gchar *init) { g_return_val_if_fail(config, NULL); check_key(key); GtkWidget *combobox; GtkWidget *hbox = gtk_hbox_new (FALSE, 8); GList *list; GtkWidget *label_combo; gint init_index = 0; if (init) init_index = g_list_position ( strings, g_list_find_custom ( strings,(gconstpointer) init, (GCompareFunc) strcmp)); if (init_index < 0) init_index=0; gtk_widget_show(hbox); gtk_box_pack_start (GTK_BOX(config->main_conf_box), hbox, FALSE, FALSE, 0); /* Label */ label_combo = gtk_label_new ((gchar *)NULL); gtk_widget_show(label_combo); gtk_box_pack_start (GTK_BOX(hbox), label_combo, FALSE, FALSE, 0); gtk_label_set_justify (GTK_LABEL(label_combo), GTK_JUSTIFY_RIGHT); gtk_label_set_markup (GTK_LABEL(label_combo), (const gchar *)label); combobox = gtk_combo_box_new_text(); gtk_widget_show(combobox); gtk_box_pack_start (GTK_BOX(hbox), combobox, FALSE, FALSE, 0); for (list = strings; list != NULL; list = list->next) gtk_combo_box_append_text (GTK_COMBO_BOX(combobox), list->data); if (g_list_length(strings) > COMBOBOX_COL_MAX) gtk_combo_box_set_wrap_width (GTK_COMBO_BOX(combobox), g_list_length(strings) / COMBOBOX_COL_MAX +1 ); gtk_combo_box_set_active (GTK_COMBO_BOX(combobox), init_index); _gc_boardconf_key *u = g_malloc0(sizeof(_gc_boardconf_key)); u -> key = g_strdup(key); u -> config = config; g_signal_connect(G_OBJECT(combobox), "changed", G_CALLBACK(_combo_box_changed), u); g_signal_connect(G_OBJECT(combobox), "destroy", G_CALLBACK(_gc_destroy_boardconf_key), u); return GTK_COMBO_BOX(combobox); }