diff options
author | Bruno Coudoin <bcoudoin@src.gnome.org> | 2009-01-30 21:15:28 (GMT) |
---|---|---|
committer | Bruno Coudoin <bcoudoin@src.gnome.org> | 2009-01-30 21:15:28 (GMT) |
commit | 82f8cd260494e0c2e119db6911965d1c7def881b (patch) | |
tree | a78a373b11ccb5805735030e94cac3d32d746b9b /src/gcompris | |
parent | 1ba35d1721e21ff06364adb8ed20419add37aeea (diff) |
Miguel DE IZARRA implemented the wordlist selector.
We need some improvement to save data in the ~/My GCompris
instead of the system datadir directory.
svn path=/trunk/; revision=3700
Diffstat (limited to 'src/gcompris')
-rw-r--r-- | src/gcompris/Makefile.am | 4 | ||||
-rw-r--r-- | src/gcompris/board_config.c | 1021 | ||||
-rw-r--r-- | src/gcompris/board_config.h | 44 | ||||
-rw-r--r-- | src/gcompris/wordlist.c | 243 | ||||
-rw-r--r-- | src/gcompris/wordlist.h | 4 |
5 files changed, 287 insertions, 1029 deletions
diff --git a/src/gcompris/Makefile.am b/src/gcompris/Makefile.am index ddf07be..f10a712 100644 --- a/src/gcompris/Makefile.am +++ b/src/gcompris/Makefile.am @@ -70,7 +70,9 @@ gcompris_SOURCES = \ binreloc.c \ binreloc.h \ board.h board.c \ - board_config.h \ + board_config_common.c board_config_common.h \ + board_config_combo.c board_config_radio.c\ + board_config_textview.c board_config_wordlist.c \ board_config.h board_config.c \ bonus.c \ bonus.h \ diff --git a/src/gcompris/board_config.c b/src/gcompris/board_config.c index 9753a39..d47a859 100644 --- a/src/gcompris/board_config.c +++ b/src/gcompris/board_config.c @@ -19,10 +19,8 @@ */ #include <string.h> - #include "gcompris.h" - -#define COMBOBOX_COL_MAX 15 +#include "board_config_common.h" static GcomprisBoard *config_board; @@ -60,37 +58,23 @@ gc_board_config_stop() return; } -static GtkWindow *conf_window = NULL; -static GtkVBox *main_conf_box = NULL; -static GHashTable *hash_conf = NULL; -static GcomprisConfCallback Confcallback = NULL; -static gchar *label_markup = NULL; - - -static void -check_key(gchar *key) -{ - if ((strcmp(key, "locale") == 0) || - (strcmp(key, "locale_sound") == 0) || - (strcmp(key, "wordlist") == 0)) - g_error(" Key %s forbiden ! Change !", key); -} - void gc_board_conf_close (GtkDialog *dialog, gpointer user_data) { + GcomprisBoardConf *u= (GcomprisBoardConf*)user_data; + gtk_object_destroy(GTK_OBJECT(dialog)); - g_hash_table_destroy (hash_conf); - hash_conf = NULL; + g_hash_table_destroy (u->hash_conf); + u->hash_conf = NULL; /* in case we close without response */ - if (Confcallback){ - Confcallback(NULL); - Confcallback = NULL; + if (u->Confcallback){ + u->Confcallback(NULL); + u->Confcallback = NULL; } + g_free(u); - g_free(label_markup); } void @@ -98,28 +82,29 @@ _response_board_conf (GtkButton *button, gint arg1, gpointer user_data) { + GcomprisBoardConf *u= (GcomprisBoardConf*)user_data; - if (Confcallback){ + if (u->Confcallback){ switch (arg1){ case GTK_RESPONSE_APPLY: - Confcallback(hash_conf); + u->Confcallback(u->hash_conf); break; case GTK_RESPONSE_CANCEL: - Confcallback(NULL); + u->Confcallback(NULL); break; case GTK_RESPONSE_NONE: - Confcallback(NULL); + u->Confcallback(NULL); break; default: - Confcallback(NULL); + u->Confcallback(NULL); break; } - Confcallback = NULL; + u->Confcallback = NULL; } - gc_board_conf_close (GTK_DIALOG(conf_window), NULL); + gc_board_conf_close (GTK_DIALOG(u->conf_window), u); } @@ -130,6 +115,7 @@ static gint _conf_window_configured(GtkWindow *window, GdkEventConfigure *event, gpointer param) { + GcomprisBoardConf *u= (GcomprisBoardConf*)param; gint new_x, new_y; double screen_width, screen_height; /* Because we call gtk_window_move, we cause a configure event. Filter out @@ -143,7 +129,7 @@ _conf_window_configured(GtkWindow *window, new_x = ((gint)screen_width - event->width) / 2; new_y = ((gint)screen_height - event->height) / 2; /* printf("screen %dx%d, window %dx%d, place %dx%d\n", (int)screen_width, (int)screen_height, event->width, event->height, new_x, new_y); */ - gtk_window_move (conf_window, new_x, new_y); + gtk_window_move (u->conf_window, new_x, new_y); memcpy(&last_configure_event, event, sizeof(GdkEventConfigure)); } @@ -152,14 +138,17 @@ _conf_window_configured(GtkWindow *window, } #endif -GtkVBox * +GcomprisBoardConf * gc_board_config_window_display(gchar *label, GcomprisConfCallback callback) { GtkWidget *header; + GcomprisBoardConf *config; + + config = g_malloc0(sizeof(GcomprisBoardConf)); /* init static values or callbacks */ - Confcallback = callback; - hash_conf = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); + config->Confcallback = callback; + config->hash_conf = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); /* Creating a config window will cause our main window to loose focus, this tells the main window to ignore the next focus out event (and thus @@ -167,7 +156,7 @@ gc_board_config_window_display(gchar *label, GcomprisConfCallback callback) gc_ignore_next_focus_out(); /* main configuration window */ - conf_window = \ + config->conf_window = \ GTK_WINDOW(gtk_dialog_new_with_buttons ("GCompris", GTK_WINDOW(gtk_widget_get_toplevel (GTK_WIDGET(gc_board_get_current()->canvas))), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, @@ -184,16 +173,16 @@ gc_board_config_window_display(gchar *label, GcomprisConfCallback callback) !gc_prop_get()->noxf86vm) { memset(&last_configure_event, 0, sizeof(GdkEventConfigure)); - gtk_widget_add_events(GTK_WIDGET(conf_window), GDK_STRUCTURE_MASK); - gtk_signal_connect (GTK_OBJECT (conf_window), "configure_event", + gtk_widget_add_events(GTK_WIDGET(config->conf_window), GDK_STRUCTURE_MASK); + gtk_signal_connect (GTK_OBJECT (config->conf_window), "configure_event", GTK_SIGNAL_FUNC (_conf_window_configured), 0); } else #endif - gtk_window_set_position (conf_window, + gtk_window_set_position (config->conf_window, GTK_WIN_POS_CENTER_ALWAYS); - gtk_widget_show(GTK_WIDGET(conf_window)); + gtk_widget_show(GTK_WIDGET(config->conf_window)); GcomprisProperties *properties = gc_prop_get(); if (properties->fullscreen && !properties->noxf86vm) @@ -203,24 +192,24 @@ gc_board_config_window_display(gchar *label, GcomprisConfCallback callback) g_warning("Pointer grab failed"); /* main vbox in window */ - main_conf_box = GTK_VBOX(GTK_DIALOG(conf_window)->vbox); + config->main_conf_box = GTK_VBOX(GTK_DIALOG(config->conf_window)->vbox); - g_signal_connect(G_OBJECT(conf_window), + g_signal_connect(G_OBJECT(config->conf_window), "response", G_CALLBACK(_response_board_conf), - NULL); + config); - g_signal_connect (G_OBJECT(conf_window), + g_signal_connect (G_OBJECT(config->conf_window), "close", G_CALLBACK(gc_board_conf_close), - NULL); + config); /* Label header */ header = gtk_label_new ((gchar *)NULL); gtk_widget_show(header); - gtk_box_pack_start (GTK_BOX(main_conf_box), + gtk_box_pack_start (GTK_BOX(config->main_conf_box), header, FALSE, FALSE, @@ -229,20 +218,23 @@ gc_board_config_window_display(gchar *label, GcomprisConfCallback callback) gtk_label_set_justify (GTK_LABEL(header), GTK_JUSTIFY_CENTER); + gchar *label_markup = NULL; label_markup = g_strdup_printf("<span size='large'>%s</span>",label); gtk_label_set_markup (GTK_LABEL(header), (const gchar *)label_markup); + g_free(label_markup); - gc_board_conf_separator(); + gc_board_conf_separator(config); - return main_conf_box; + return config; } void gc_board_conf_boolean_box_toggled (GtkToggleButton *togglebutton, gpointer key) { - gchar *the_key = g_strdup((gchar *)key); + _gc_boardconf_key *u = (_gc_boardconf_key*)key; + gchar *the_key = g_strdup(u->key); gchar *value; if (gtk_toggle_button_get_active (togglebutton)) @@ -250,19 +242,22 @@ gc_board_conf_boolean_box_toggled (GtkToggleButton *togglebutton, else value = g_strdup("False"); - g_hash_table_replace(hash_conf, (gpointer) the_key, (gpointer) value); + g_hash_table_replace(u->config->hash_conf, (gpointer) the_key, (gpointer) value); } GtkCheckButton * -gc_board_config_boolean_box(const gchar *label, gchar *key, gboolean initial_value) +gc_board_config_boolean_box(GcomprisBoardConf *config, const gchar *label, gchar *key, gboolean initial_value) { + _gc_boardconf_key *user_data; + + g_return_val_if_fail(config, NULL); check_key( key); GtkWidget *CheckBox = gtk_check_button_new_with_label (label); gtk_widget_show(CheckBox); - gtk_box_pack_start (GTK_BOX(main_conf_box), + gtk_box_pack_start (GTK_BOX(config->main_conf_box), CheckBox, FALSE, FALSE, @@ -271,242 +266,37 @@ gc_board_config_boolean_box(const gchar *label, gchar *key, gboolean initial_val gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(CheckBox), initial_value); + user_data = g_malloc0(sizeof(_gc_boardconf_key)); + user_data -> key =g_strdup(key); + user_data -> config = config; + g_signal_connect (G_OBJECT(CheckBox), "toggled", G_CALLBACK(gc_board_conf_boolean_box_toggled), - key); - + user_data); + g_signal_connect (G_OBJECT(CheckBox), + "destroy", + G_CALLBACK(_gc_destroy_boardconf_key), + user_data); return GTK_CHECK_BUTTON(CheckBox); } -/* code get from gtk */ -/* included here to not depend on gtk 2.6 */ - -static gchar * -_get_active_text (GtkComboBox *combo_box) -{ - GtkTreeIter iter; - gchar *text = NULL; - - g_return_val_if_fail (GTK_IS_LIST_STORE (gtk_combo_box_get_model (combo_box)), NULL); - - if (gtk_combo_box_get_active_iter (combo_box, &iter)) - gtk_tree_model_get (gtk_combo_box_get_model (combo_box), &iter, - 0, &text, -1); - - return text; -} - -static void -_combo_box_changed(GtkComboBox *combobox, - gpointer key) -{ - gchar *the_key = g_strdup((gchar *)key); - - gchar *value = g_strdup_printf("%s", _get_active_text (combobox)); - - g_hash_table_replace(hash_conf, (gpointer) the_key, (gpointer) value); -} - -static inline int my_strcmp(gchar *a, gchar *b) { return strcmp( a, b); } - - -GtkComboBox *gc_board_config_combo_box(const gchar *label, GList *strings, gchar *key, gchar *init) -{ - 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) my_strcmp)); - - if (init_index < 0) - init_index=0; - - gtk_widget_show(hbox); - - gtk_box_pack_start (GTK_BOX(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); - - g_signal_connect(G_OBJECT(combobox), - "changed", - G_CALLBACK(_combo_box_changed), - key); - - return GTK_COMBO_BOX(combobox); -} - -static GSList *radio_group = NULL; -static GtkWidget *radio_box; -static gchar *radio_key = NULL; -static gchar *radio_text = NULL; -static gchar *radio_init = NULL; - -static void radio_changed(GtkToggleButton *togglebutton, - gpointer key) -{ - gboolean state = gtk_toggle_button_get_active (togglebutton); - gchar *h_key; - gchar *h_value; - - if (state){ - h_key = g_strdup (radio_key); - h_value = g_strdup((gchar *) key); - g_hash_table_replace (hash_conf, h_key, h_value); - } -} - -static void -create_radio_buttons(gpointer key, - gpointer value, - gpointer hash_radio) -{ - GtkWidget *radio_button; - gchar *key_copy; - - radio_button = gtk_radio_button_new_with_label (radio_group, - (const gchar *) g_strdup(value)); - - gtk_box_pack_start (GTK_BOX (radio_box), radio_button, TRUE, TRUE, 2); - - gtk_widget_show (GTK_WIDGET (radio_button)); - - radio_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio_button)); - - key_copy = g_strdup ((gchar *)key); - - if (strcmp( key_copy, radio_init)==0) - gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(radio_button),TRUE); - - g_signal_connect(G_OBJECT(radio_button), - "toggled", - G_CALLBACK(radio_changed), - (gpointer) key_copy); - - g_hash_table_replace ( hash_radio, (gpointer) key_copy, (gpointer) radio_button); -} - -static void -destroy_hash (GtkObject *object, - gpointer hash_table) -{ - g_hash_table_destroy((GHashTable *)hash_table); - radio_group = NULL; - g_free(radio_text); - g_free(radio_key); - g_free(radio_init); -} - -GHashTable * -gc_board_config_radio_buttons(const gchar *label, - gchar *key, - GHashTable *buttons_label, - gchar *init) -{ - check_key( key); - - GtkWidget *radio_label; - - GHashTable *buttons = g_hash_table_new_full (g_str_hash, - g_str_equal, - g_free, - NULL); - - radio_box = gtk_vbox_new (TRUE, 2); - gtk_widget_show (GTK_WIDGET (radio_box)); - - gtk_box_pack_start (GTK_BOX(main_conf_box), - radio_box, - FALSE, - FALSE, - 0); - - radio_label = gtk_label_new ((gchar *)NULL); - gtk_widget_show(radio_label); - - gtk_box_pack_start (GTK_BOX(radio_box), - radio_label, - FALSE, - FALSE, - 0); - - gtk_label_set_justify (GTK_LABEL(radio_label), - GTK_JUSTIFY_CENTER); - - radio_text = g_strdup(label); - gtk_label_set_markup (GTK_LABEL(radio_label), - (const gchar *)radio_text); - - radio_key = g_strdup(key); - radio_init = g_strdup(init); - - g_hash_table_foreach( buttons_label, - (GHFunc) create_radio_buttons, - (gpointer) buttons); - - g_signal_connect (G_OBJECT(radio_box), "destroy", G_CALLBACK(destroy_hash), (gpointer) buttons); - - return buttons; -} - static void spin_changed (GtkSpinButton *spinbutton, - gpointer key) + gpointer data) { - gchar *h_key = g_strdup((gchar *) key); + _gc_boardconf_key *u = (_gc_boardconf_key*)data; + + gchar *h_key = g_strdup(u->key); gchar *h_value = g_strdup_printf("%d",gtk_spin_button_get_value_as_int (spinbutton)); - g_hash_table_replace (hash_conf, h_key, h_value); + g_hash_table_replace (u->config->hash_conf, h_key, h_value); } GtkSpinButton * -gc_board_config_spin_int(const gchar *label, gchar *key, gint min, gint max, gint step, gint init) +gc_board_config_spin_int(GcomprisBoardConf *config, const gchar *label, gchar *key, gint min, gint max, gint step, gint init) { + g_return_val_if_fail(config, NULL); check_key( key); GtkWidget *spin; @@ -515,7 +305,7 @@ gc_board_config_spin_int(const gchar *label, gchar *key, gint min, gint max, gin gtk_widget_show(hbox); - gtk_box_pack_start (GTK_BOX(main_conf_box), + gtk_box_pack_start (GTK_BOX(config->main_conf_box), hbox, FALSE, FALSE, @@ -551,24 +341,33 @@ gc_board_config_spin_int(const gchar *label, gchar *key, gint min, gint max, gin gtk_spin_button_set_digits ( GTK_SPIN_BUTTON(spin), 0); gtk_spin_button_set_value ( GTK_SPIN_BUTTON(spin), (gdouble) init); + + _gc_boardconf_key *u = g_malloc0(sizeof(_gc_boardconf_key)); + u->key = g_strdup(key); + u->config = config; g_signal_connect (G_OBJECT(spin), "value-changed", G_CALLBACK(spin_changed), - key); + u); + g_signal_connect( G_OBJECT(spin), + "destroy", + G_CALLBACK(_gc_destroy_boardconf_key), + u); return GTK_SPIN_BUTTON(spin); } GtkHSeparator * -gc_board_conf_separator() +gc_board_conf_separator(GcomprisBoardConf *config) { + g_return_val_if_fail(config, NULL); GtkWidget *separator = gtk_hseparator_new (); gtk_widget_show(separator); - gtk_box_pack_start (GTK_BOX(main_conf_box), + gtk_box_pack_start (GTK_BOX(config->main_conf_box), separator, FALSE, FALSE, @@ -578,669 +377,3 @@ gc_board_conf_separator() } -/***********************************************/ -/* 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; - - 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); - - /* Save it for next call */ - gcompris_locales_list = locales; - - return locales; -} - - -void -gc_board_config_combo_locales_changed(GtkComboBox *combobox, - gpointer key) -{ - gchar *the_key = g_strdup((gchar *)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(hash_conf, (gpointer) the_key, (gpointer) value); -} - -/* key = "locale" */ -GtkComboBox* -gc_board_config_combo_locales(gchar *init) -{ - - 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) my_strcmp)); - - if (init_index < 0) - init_index=0; - - gtk_widget_show(hbox); - - gtk_box_pack_start (GTK_BOX(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); - - g_signal_connect(G_OBJECT(combobox), - "changed", - G_CALLBACK(gc_board_config_combo_locales_changed), - "locale"); - - return GTK_COMBO_BOX(combobox); - -} - -void -gc_board_config_combo_drag_changed(GtkComboBox *combobox, - gpointer key) -{ - gchar *the_key = g_strdup((gchar *)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(hash_conf, (gpointer) the_key, (gpointer) value); -} - -/* key = "locale" */ -GtkComboBox* -gc_board_config_combo_drag(gint init) -{ - - 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(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); - - g_signal_connect(G_OBJECT(combobox), - "changed", - G_CALLBACK(gc_board_config_combo_drag_changed), - "drag_mode"); - - 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); - - } - - - return locales_asset; -} - -/* key = "locale_sound" */ -GtkComboBox *gc_board_config_combo_locales_asset(const gchar *label, - gchar *init, - const gchar *file) -{ - - 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) my_strcmp)); - } - - if (init_index < 0) - init_index=0; - - gtk_widget_show(hbox); - - gtk_box_pack_start (GTK_BOX(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); - - g_signal_connect(G_OBJECT(combobox), - "changed", - G_CALLBACK(gc_board_config_combo_locales_changed), - "locale_sound"); - - return GTK_COMBO_BOX(combobox); - -} - -/****************************************/ -/* TextView */ - -typedef struct { - gchar *key; - GcomprisTextCallback callback; - GtkLabel *feedback; - GtkTextBuffer *TextBuffer; -} user_param_type; - -static void * -_textview_destroy (GtkButton *button, - gpointer user_data) -{ - g_free(((user_param_type *)user_data)->key); - g_free(user_data); - - return NULL; -} - - -static void * -_textbuffer_changed (GtkTextBuffer *buffer, - gpointer user_data) -{ - gtk_widget_set_sensitive (GTK_WIDGET(user_data), - TRUE); - - return NULL; -} - -static void * -_textview_yes (GtkButton *button, - gpointer user_data) -{ - - user_param_type *params= (user_param_type *) user_data; - - gchar *key = params->key; - GcomprisTextCallback validate = params->callback; - GtkLabel *label = params->feedback; - GtkTextBuffer *text_buffer = params->TextBuffer; - - GtkTextIter start_iter; - GtkTextIter end_iter; - - gtk_text_buffer_get_start_iter (text_buffer, - &start_iter); - - gtk_text_buffer_get_end_iter (text_buffer, - &end_iter); - - /* has this to be freed ? */ - gchar *text = gtk_text_buffer_get_slice (text_buffer, - &start_iter, - &end_iter, - TRUE); - - - - gchar *in_memoriam_text = g_strdup (text); - gchar *in_memoriam_key = g_strdup (key); - - if (validate( key, text, label)){ - g_hash_table_replace ( hash_conf, (gpointer) in_memoriam_key, (gpointer) in_memoriam_text); - gtk_widget_set_sensitive (GTK_WIDGET(button), - FALSE); - } - else { - g_free (in_memoriam_text); - g_free (in_memoriam_key); - } - g_free(text); - - return NULL; -} - -GtkTextView * -gc_board_config_textview(const gchar *label, - gchar *key, - const gchar*description, - gchar *init_text, - GcomprisTextCallback validate) -{ - GtkWidget*frame = gtk_frame_new ("GCompris text tool"); - gtk_widget_show(frame); - - gtk_box_pack_start (GTK_BOX(main_conf_box), - frame, - FALSE, - FALSE, - 8); - - - - /* Main vbox for all our widegt */ - GtkWidget *textVbox = gtk_vbox_new ( FALSE, 8); - gtk_widget_show(textVbox); - - gtk_container_add(GTK_CONTAINER(frame), - textVbox); - /* Title */ - GtkWidget *title = gtk_label_new ((gchar *)NULL); - gtk_widget_show(title); - - gtk_box_pack_start (GTK_BOX(textVbox), - title, - FALSE, - FALSE, - 8); - - gtk_label_set_justify (GTK_LABEL(title), - GTK_JUSTIFY_CENTER); - - gchar *title_text = g_strdup(label); - gtk_label_set_markup (GTK_LABEL(title), - (const gchar *)title_text); - - GtkWidget *separator = gtk_hseparator_new (); - - gtk_widget_show(separator); - - gtk_box_pack_start (GTK_BOX(textVbox), - separator, - FALSE, - FALSE, - 0); - - /* Description */ - GtkWidget *desc = gtk_label_new ((gchar *)NULL); - gtk_widget_show(desc); - - gtk_box_pack_start (GTK_BOX(textVbox), - desc, - FALSE, - FALSE, - 0); - - //gtk_label_set_justify (GTK_LABEL(title), - // GTK_JUSTIFY_CENTER); - - gtk_label_set_line_wrap(GTK_LABEL(desc), TRUE); - - gchar *desc_text = g_strdup(description); - gtk_label_set_markup (GTK_LABEL(desc), - (const gchar *)desc_text); - - GtkWidget *scroll = gtk_scrolled_window_new ( NULL, NULL); - - - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW(scroll), - GTK_POLICY_AUTOMATIC, - GTK_POLICY_AUTOMATIC); - - gtk_widget_set_size_request (scroll, - -1, - 100); - - gtk_widget_show( scroll); - - gtk_box_pack_start (GTK_BOX(textVbox), - scroll, - FALSE, - FALSE, - 0); - - /* TextView */ - GtkWidget *textView = gtk_text_view_new (); - gtk_widget_show(textView); - - gtk_container_add (GTK_CONTAINER(scroll), - textView); - - gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (textView), GTK_WRAP_WORD_CHAR); - - - GtkTextBuffer *buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (textView)); - - gtk_text_buffer_set_text (buffer, g_strdup(init_text), -1); - - - /* hbox for feedback and validation button */ - GtkWidget *validationHbox = gtk_vbox_new ( FALSE, 8); - gtk_widget_show(validationHbox); - - gtk_box_pack_start (GTK_BOX(textVbox), - validationHbox, - FALSE, - FALSE, - 0); - - /* Feedback */ - GtkWidget *feedback = gtk_label_new ((gchar *)NULL); - gtk_widget_show(feedback); - - gtk_box_pack_start (GTK_BOX(validationHbox), - feedback, - FALSE, - FALSE, - 0); - - gtk_label_set_justify (GTK_LABEL(title), - GTK_JUSTIFY_FILL); - - gtk_label_set_line_wrap(GTK_LABEL(feedback), TRUE); - - user_param_type *user_param = g_malloc0(sizeof(user_param_type)); - - user_param->key = g_strdup(key); - user_param->callback = validate; - user_param->feedback = GTK_LABEL(feedback); - user_param->TextBuffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW(textView)); - - - /* vbox for feedback and validation button */ - GtkWidget *validationVbox = gtk_hbox_new ( FALSE, 8); - gtk_widget_show(validationVbox); - - gtk_box_pack_end (GTK_BOX(validationHbox), - validationVbox, - FALSE, - FALSE, - 0); - - - /* Validate button */ - GtkWidget *button = gtk_button_new_from_stock (GTK_STOCK_YES); - gtk_widget_show(button); - gtk_box_pack_end (GTK_BOX(validationVbox), - button, - FALSE, - FALSE, - 0); - - g_signal_connect(G_OBJECT(button), - "clicked", - G_CALLBACK(_textview_yes), - (gpointer) user_param); - - - g_signal_connect(G_OBJECT(button), - "destroy", - G_CALLBACK(_textview_destroy), - (gpointer) user_param); - - g_signal_connect(G_OBJECT(user_param->TextBuffer), - "changed", - G_CALLBACK(_textbuffer_changed), - (gpointer) button); - - gtk_widget_set_sensitive (button, - FALSE); - - return GTK_TEXT_VIEW(textView); -} diff --git a/src/gcompris/board_config.h b/src/gcompris/board_config.h index f1124e5..015ab05 100644 --- a/src/gcompris/board_config.h +++ b/src/gcompris/board_config.h @@ -20,6 +20,18 @@ #ifndef BOARD_CONFIG_H #define BOARD_CONFIG_H +#include "gcompris.h" + +/* the callback type */ +typedef void (*GcomprisConfCallback) (GHashTable *table); + +typedef struct +{ + GtkWindow *conf_window; + GtkVBox *main_conf_box; + GHashTable *hash_conf; + GcomprisConfCallback Confcallback; +} GcomprisBoardConf; void gc_board_config_start(GcomprisBoard *aBoard, GcomprisProfile *aProfile); @@ -31,14 +43,11 @@ void gc_board_config_stop(); /* You can add your own widget if you need */ /* the callback is called wish the hash key, value when the apply button is clicked */ -/* the callback type */ -typedef void (*GcomprisConfCallback) (GHashTable *table); - -GtkVBox *gc_board_config_window_display(gchar *label, GcomprisConfCallback callback); +GcomprisBoardConf *gc_board_config_window_display(gchar *label, GcomprisConfCallback callback); -GtkCheckButton *gc_board_config_boolean_box(const gchar *label, gchar *key, gboolean initial_value); +GtkCheckButton *gc_board_config_boolean_box(GcomprisBoardConf *config, const gchar *label, gchar *key, gboolean initial_value); -GtkComboBox *gc_board_config_combo_box(const gchar *label, GList *strings, gchar *key, gchar *init); +GtkComboBox *gc_board_config_combo_box(GcomprisBoardConf *config, const gchar *label, GList *strings, gchar *key, gchar *init); /* Params: */ /* - Label */ @@ -47,25 +56,25 @@ GtkComboBox *gc_board_config_combo_box(const gchar *label, GList *strings, gchar /* Returns */ /* - g_hash_table (gchar *values, GtkWidget *pointer) */ -GHashTable *gc_board_config_radio_buttons(const gchar *label, +GHashTable *gc_board_config_radio_buttons(GcomprisBoardConf *config, const gchar *label, gchar *key, GHashTable *buttons_label, gchar *init); -GtkSpinButton *gc_board_config_spin_int(const gchar *label, +GtkSpinButton *gc_board_config_spin_int(GcomprisBoardConf *config, const gchar *label, gchar *key, gint min, gint max, gint step, gint init); -GtkHSeparator *gc_board_conf_separator(); +GtkHSeparator *gc_board_conf_separator(GcomprisBoardConf *config); GList *gc_locale_gets_list(); -GtkComboBox *gc_board_config_combo_locales( gchar *init); +GtkComboBox *gc_board_config_combo_locales(GcomprisBoardConf *config, gchar *init); -GtkComboBox *gc_board_config_combo_drag( gint init); +GtkComboBox *gc_board_config_combo_drag( GcomprisBoardConf *config, gint init); void gc_locale_change(gchar *locale); @@ -73,10 +82,8 @@ void gc_locale_reset(); GList *gc_locale_gets_asset_list(const gchar *file); -GtkComboBox *gc_board_config_combo_locales_asset(const gchar *label, gchar *init, - const gchar *file); -#endif - +GtkComboBox *gc_board_config_combo_locales_asset(GcomprisBoardConf *config, + const gchar *label, gchar *init, const gchar *file); /***********************************/ /* TextView facility */ /* Callback is text vaidating function */ @@ -85,8 +92,13 @@ GtkComboBox *gc_board_config_combo_locales_asset(const gchar *label, gchar *init typedef gboolean (*GcomprisTextCallback) (gchar *key, gchar *text, GtkLabel *label); -GtkTextView *gc_board_config_textview(const gchar *label, +GtkTextView *gc_board_config_textview(GcomprisBoardConf *config, const gchar *label, gchar *key, const gchar*description, gchar *init_text, GcomprisTextCallback validate); + +GtkWidget *gc_board_config_wordlist(GcomprisBoardConf *config, const gchar *files); + +#endif + diff --git a/src/gcompris/wordlist.c b/src/gcompris/wordlist.c index 754510d..8230e0b 100644 --- a/src/gcompris/wordlist.c +++ b/src/gcompris/wordlist.c @@ -22,6 +22,8 @@ #include "gcompris.h" +void gc_wordlist_dump(GcomprisWordlist *wl); + /** Load a wordlist formatted xml file. It contains a list of words. * * The xml file format must be like this: @@ -62,13 +64,11 @@ GcomprisWordlist xmlNodePtr wlNode; xmlNodePtr node; xmlNodePtr wordsNode; - int i; - guint number_of_level = 0; + guint level; GcomprisWordlist *wordlist; xmlChar *text; - gchar **wordsArray; GSList *words = NULL; if (!format) @@ -84,19 +84,21 @@ GcomprisWordlist if(!xmlfilename) { g_warning("Couldn't find file %s !", filename); - g_free(xmlfilename); + g_free(filename); return NULL; } g_warning("Wordlist found %s\n", xmlfilename); xmldoc = xmlParseFile(xmlfilename); - g_free(xmlfilename); if(!xmldoc){ g_warning("Couldn't parse file %s !", xmlfilename); + g_free(filename); + g_free(xmlfilename); return NULL; } + g_free(xmlfilename); if(/* if there is no root element */ !xmldoc->children || @@ -106,6 +108,7 @@ GcomprisWordlist g_strcasecmp((gchar *)xmldoc->children->name,(gchar *)"GCompris")!=0) { g_warning("No Gcompris node"); xmlFreeDoc(xmldoc); + g_free(filename); return NULL; } @@ -118,6 +121,7 @@ GcomprisWordlist g_strcasecmp((gchar *)wlNode->name,"Wordlist")!=0) { g_warning("No wordlist node %s", (wlNode == NULL) ? (gchar *)wlNode->name : "NULL node"); xmlFreeDoc(xmldoc); + g_free(filename); return NULL; } @@ -174,48 +178,60 @@ GcomprisWordlist break; } - text = xmlNodeGetContent ( wordsNode); - - wordsArray = g_strsplit_set ((const gchar *) text, - (const gchar *) " \n\t", - 0); - - g_warning("Wordlist read : %s", text); - - xmlFree (text); - - i=0; - while (wordsArray[i] != NULL) { - if (wordsArray[i][0]!='\0') - words = g_slist_append( words, g_strdup( wordsArray[i])); - i++; + level=-1; + text = xmlGetProp ( node, + (const xmlChar *) "value"); + if (text) { + level = atoi((gchar *) text); + xmlFree (text); } + text = xmlNodeGetContent ( wordsNode); + gc_wordlist_set_wordlist(wordlist, level, (const gchar*)text); + xmlFree(text); - g_strfreev ( wordsArray); - - - /* initialise LevelWordlist struct */ - LevelWordlist *level_words = g_malloc0(sizeof(LevelWordlist)); + node = node->next; + } + xmlFreeDoc(xmldoc); + return wordlist; +} - number_of_level++; +void gc_wordlist_dump(GcomprisWordlist *wl) +{ + GSList *level, *words; - text = xmlGetProp ( node, - (const xmlChar *) "value"); - if (text) { - level_words->level = atoi((gchar *) text); - xmlFree (text); - } + printf("Wordlist dump\n"); + printf("filename:%s\n",wl->filename); + printf("number of level:%d\n",wl->number_of_level); - level_words->words = words; + for(level = wl->levels_words; level; level = level->next) + { + printf("Level %d\n", ((LevelWordlist*)level->data)->level); + printf("Words :"); + for(words=((LevelWordlist*)level->data)->words; words; words=words->next) + { + printf(" %s", (char*)words->data); + } + puts(""); + } +} - wordlist->levels_words = g_slist_append( wordlist->levels_words, level_words); +LevelWordlist*gc_wordlist_get_levelwordlist(GcomprisWordlist *wordlist, guint level) +{ + GSList *lev_list, *list; + LevelWordlist *lw; - node = node->next; - } + if(!wordlist) + return NULL; - wordlist->number_of_level = number_of_level; + lev_list = wordlist->levels_words; - return wordlist; + for (list = lev_list; list != NULL; list = list->next) + { + lw = list->data; + if(lw->level == level) + return lw; + } + return NULL; } /** get a random word from the wordlist in the given level @@ -228,36 +244,37 @@ GcomprisWordlist gchar * gc_wordlist_random_word_get(GcomprisWordlist *wordlist, guint level) { - GSList *lev_list, *list; + LevelWordlist *lw; + gchar *word; - if(!wordlist) - return NULL; + if(level>wordlist->number_of_level) + level = wordlist->number_of_level; - lev_list = wordlist->levels_words; + lw = gc_wordlist_get_levelwordlist(wordlist, level); + if(!lw) + return NULL; - /* cap to the number_of_level */ - if(level > wordlist->number_of_level) - level = wordlist->number_of_level; + g_warning("Level : %d", lw->level); - for (list = lev_list; list != NULL; list = list->next) - { - LevelWordlist *lw = list->data; + /* We got the proper level, find a random word */ + word = (gchar *)g_slist_nth_data(lw->words, + RAND(0, g_slist_length(lw->words)) + ); + g_warning("returning random word '%s'", word); + return(g_strdup(word)); +} - if(lw->level == level) - { - gchar *word; - g_warning("Level : %d", lw->level); - - /* We got the proper level, find a random word */ - word = (gchar *)g_slist_nth_data(lw->words, - RAND(0, g_slist_length(lw->words)-1) - ); - g_warning("returning random word '%s'", word); - return(g_strdup(word)); - } - } +static void gc_wordlist_free_level(LevelWordlist *lw) +{ + GSList *words; - return NULL; + if(!lw) + return; + + for (words = lw->words; words !=NULL; words = words->next) + g_free(words->data); + g_slist_free(lw->words); + g_free(lw); } /** call it to free a GcomprisWordlist as returned by gc_wordlist_get_from_file @@ -268,7 +285,7 @@ gc_wordlist_random_word_get(GcomprisWordlist *wordlist, guint level) void gc_wordlist_free(GcomprisWordlist *wordlist) { - GSList *list, *words; + GSList *list; if(!wordlist) return; @@ -280,11 +297,103 @@ gc_wordlist_free(GcomprisWordlist *wordlist) for ( list = wordlist->levels_words; list !=NULL; list=list->next){ LevelWordlist *lw = (LevelWordlist *)list->data; - for ( words = lw->words; words !=NULL; words = words->next) - g_free(words->data); - g_slist_free(lw->words); - g_free(lw); + gc_wordlist_free_level(lw); } g_slist_free ( wordlist->levels_words); g_free (wordlist); } + +void gc_wordlist_set_wordlist(GcomprisWordlist *wordlist, guint level, const gchar*text) +{ + LevelWordlist *lw; + GSList *words=NULL; + gchar **wordsArray; + int i; + + g_warning("wordlist : add level=%d text=%s\n", level, text); + /* remove level */ + if((lw = gc_wordlist_get_levelwordlist(wordlist, level))) + { + g_warning("remove level %d", lw->level); + wordlist->levels_words = g_slist_remove(wordlist->levels_words, lw); + gc_wordlist_free_level(lw); + wordlist->number_of_level--; + } + + /* add new level */ + wordsArray = g_strsplit_set (text, " \n\t", 0); + + i=0; + for(i=0;wordsArray[i] != NULL; i++) + if (wordsArray[i][0]!='\0' && + !g_slist_find_custom(words, wordsArray[i], (GCompareFunc)strcmp)) + words = g_slist_append( words, g_strdup(wordsArray[i])); + + g_strfreev ( wordsArray); + + if(words==NULL) + return; + + /* initialise LevelWordlist struct */ + LevelWordlist *level_words = g_malloc0(sizeof(LevelWordlist)); + + level_words->words = words; + level_words->level = level; + + wordlist->number_of_level++; + wordlist->levels_words = g_slist_append( wordlist->levels_words, level_words); +} + +void gc_wordlist_save(GcomprisWordlist *wordlist) +{ + GSList *listlevel,*listword; + LevelWordlist *level; + gchar *filename, *tmp; + xmlNodePtr wlnode, levelnode, node; + xmlDocPtr doc; + + if(!wordlist) + return; + doc = xmlNewDoc(BAD_CAST XML_DEFAULT_VERSION); + if(!doc) + return; + + node = xmlNewNode(NULL, BAD_CAST "GCompris"); + xmlDocSetRootElement(doc,node); + wlnode = xmlNewChild(node, NULL, BAD_CAST "Wordlist", NULL); + + if(wordlist->name) + xmlSetProp(wlnode, BAD_CAST "name", BAD_CAST wordlist->name); + if(wordlist->description) + xmlSetProp(wlnode, BAD_CAST "description", BAD_CAST wordlist->description); + if(wordlist->locale) + xmlSetProp(wlnode, BAD_CAST "locale", BAD_CAST wordlist->locale); + for(listlevel = wordlist->levels_words; listlevel; listlevel = listlevel->next) + { + level = (LevelWordlist*)listlevel->data; + levelnode = xmlNewChild(wlnode, NULL, BAD_CAST "level", NULL); + if((tmp = g_strdup_printf("%d", level->level))) + { + xmlSetProp(levelnode, BAD_CAST "value", BAD_CAST tmp); + g_free(tmp); + } + for(listword = level->words; listword; listword=listword->next) + { + xmlNodeAddContent(levelnode, BAD_CAST listword->data); + xmlNodeAddContent(levelnode, BAD_CAST " "); + } + } + + filename = gc_file_find_absolute(wordlist->filename); + if(filename) + { + if(xmlSaveFormatFileEnc(filename, doc, NULL, 1)<0) + { + g_warning("Fail to write %s", filename); + g_free(filename); + } + g_free(filename); + } + xmlFreeDoc(doc); +} + diff --git a/src/gcompris/wordlist.h b/src/gcompris/wordlist.h index a53f1a5..a35bb65 100644 --- a/src/gcompris/wordlist.h +++ b/src/gcompris/wordlist.h @@ -35,7 +35,9 @@ typedef struct { } GcomprisWordlist; GcomprisWordlist *gc_wordlist_get_from_file(const gchar *fileformat, ...); +LevelWordlist *gc_wordlist_get_levelwordlist(GcomprisWordlist *wordlist, guint level); void gc_wordlist_free(GcomprisWordlist *wordlist); gchar *gc_wordlist_random_word_get(GcomprisWordlist *wordlist, guint level); - +void gc_wordlist_set_wordlist(GcomprisWordlist *wordlist, guint level, const gchar*words); +void gc_wordlist_save(GcomprisWordlist *wordlist); #endif |