[gcompris/gcomprixogoo] - Miquel DE IZARRA Added support for editing the content of the missing
- From: Bruno Coudoin <bcoudoin src gnome org>
- To: svn-commits-list gnome org
- Subject: [gcompris/gcomprixogoo] - Miquel DE IZARRA Added support for editing the content of the missing
- Date: Sat, 20 Jun 2009 22:07:10 -0400 (EDT)
commit 9ce88612e358e4d0f7eda5cc03ae68c7363197c2
Author: Bruno Coudoin <bcoudoin src gnome org>
Date: Mon Feb 16 23:32:03 2009 +0000
- Miquel DE IZARRA Added support for editing the content of the missing
- Miquel DE IZARRA Added support for editing the content
of the missing letter activity.
svn path=/trunk/; revision=3722
ChangeLog | 29 +
src/boards/missingletter.c | 796 ++++++++++++++++++++
src/gcompris/board_config_wordlist.c | 12 +-
src/gcompris/gameutil.c | 2 -
src/gcompris/gc_net.c | 3 +-
src/gcompris/gc_net.h | 1 +
src/gcompris/gcompris.c | 45 ++-
src/missing_letter-activity/Makefile.am | 2 +-
src/missing_letter-activity/missingletter.c | 186 +++---
src/missing_letter-activity/missingletter.h | 36 +
src/missing_letter-activity/missingletter_config.c | 592 +++++++++++++++
src/readingh-activity/reading.c | 17 +-
12 files changed, 1611 insertions(+), 110 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 3b491c5..07261df 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,34 @@
2009-06-20 Bruno coudoin <bruno coudoin free fr>
+ From trunk
+ - Miquel DE IZARRA Added support for editing the content
+ of the missing letter activity.
+
+ * boards/missing_letter/Makefile.am:
+ * boards/missing_letter/board1.xml.in:
+ * boards/missing_letter/board2.xml.in:
+ * boards/missing_letter/board3.xml.in:
+ * boards/missing_letter/board4.xml.in:
+ * src/boards/Makefile.am:
+ * src/boards/missingletter.c: (pause_board), (start_board),
+ (end_board), (set_level), (missing_letter_next_level),
+ (missing_letter_create_item), (game_won), (init_xml),
+ (add_xml_data), (missing_read_xml_file),
+ (missing_destroy_board_list), (conf_ok), (config_start):
+ * src/boards/missingletter_config.c: (new_clicked),
+ (delete_clicked), (valid_entry), (apply_clicked), (up_clicked),
+ (down_clicked), (_save), (save_clicked), (level_changed),
+ (text_changed), (selection_changed), (destroy_conf_data),
+ (configure_colummns), (config_missing_letter):
+ * src/boards/reading.c: (reading_create_item), (get_random_word):
+ * src/gcompris/board_config_wordlist.c: (gc_board_config_wordlist):
+ * src/gcompris/gc_net.c: (gc_net_get_url_from_file),
+ (gc_cache_import_pixmap):
+ * src/gcompris/gc_net.h:
+ * src/gcompris/gcompris.c: (main):
+
+2009-06-20 Bruno coudoin <bruno coudoin free fr>
+
From trunk.
Miguel DE IZARRA added support for online wordlist.
This save custom data in user_dir and make a content.txt (a md5sum
diff --git a/src/boards/missingletter.c b/src/boards/missingletter.c
new file mode 100644
index 0000000..476044a
--- /dev/null
+++ b/src/boards/missingletter.c
@@ -0,0 +1,796 @@
+/* gcompris - missingletter.c
+ *
+ * Copyright (C) 2001 Pascal Georges
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#include <string.h>
+
+#include "gcompris/gcompris.h"
+
+/* libxml includes */
+#include <libxml/tree.h>
+#include <libxml/parser.h>
+
+#define SOUNDLISTFILE PACKAGE
+
+GcomprisBoard *gcomprisBoard_missing = NULL;
+static gboolean board_paused = TRUE;
+
+static void start_board (GcomprisBoard *agcomprisBoard);
+static void pause_board (gboolean pause);
+static void end_board (void);
+static gboolean is_our_board (GcomprisBoard *gcomprisBoard);
+static void set_level (guint level);
+static int gamewon;
+static void process_ok(void);
+static void highlight_selected(GnomeCanvasItem *);
+static void game_won(void);
+static void config_start(GcomprisBoard *agcomprisBoard,
+ GcomprisProfile *aProfile);
+static void config_stop(void);
+
+/* from missingletter_config.c */
+void config_missing_letter(GcomprisBoardConf *config);
+
+typedef struct _Board Board;
+struct _Board {
+ char *pixmapfile;
+ char *question;
+ char *answer;
+ char *l1;
+ char *l2;
+ char *l3;
+};
+
+static Board * board;
+
+/* XML */
+static void init_xml(void);
+static void add_xml_data(xmlDocPtr, xmlNodePtr, GList**);
+gboolean missing_read_xml_file(char *fname, GList**);
+void missing_destroy_board_list(GList *);
+static void destroy_board(Board * board);
+
+/* This is the list of boards */
+static GList *board_list = NULL;
+
+#define VERTICAL_SEPARATION 30
+#define HORIZONTAL_SEPARATION 30
+
+/* ================================================================ */
+static int right_word; // between 1 and 3, indicates which choice is the right one (the player clicks on it
+
+static GnomeCanvasGroup *boardRootItem = NULL;
+
+static GnomeCanvasItem *image_item = NULL;
+static GnomeCanvasItem *l1_item = NULL;
+static GnomeCanvasItem *l2_item = NULL;
+static GnomeCanvasItem *l3_item = NULL;
+static GnomeCanvasItem *text = NULL;
+static GnomeCanvasItem *text_s = NULL;
+static GnomeCanvasItem *button1 = NULL, *button2 = NULL, *button3 = NULL, *selected_button = NULL;
+
+static GnomeCanvasItem *missing_letter_create_item(GnomeCanvasGroup *parent);
+static void missing_letter_destroy_all_items(void);
+static void missing_letter_next_level(void);
+static gint item_event(GnomeCanvasItem *item, GdkEvent *event, gpointer data);
+
+/* Description of this plugin */
+static BoardPlugin menu_bp =
+ {
+ NULL,
+ NULL,
+ N_("Reading"),
+ N_("Learn how to read"),
+ "Pascal Georges pascal georges1 free fr>",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ start_board,
+ pause_board,
+ end_board,
+ is_our_board,
+ NULL,
+ process_ok,
+ set_level,
+ NULL,
+ NULL,
+ config_start,
+ config_stop
+ };
+
+/*
+ * Main entry point mandatory for each Gcompris's game
+ * ---------------------------------------------------
+ *
+ */
+
+GET_BPLUGIN_INFO(missingletter)
+
+/*
+ * in : boolean TRUE = PAUSE : FALSE = CONTINUE
+ *
+ */
+static void pause_board (gboolean pause)
+{
+ if(gcomprisBoard_missing==NULL)
+ return;
+
+ gc_bar_hide(FALSE);
+
+ if(gamewon == TRUE && pause == FALSE) /* the game is won */
+ {
+ game_won();
+ }
+
+ board_paused = pause;
+}
+
+/*
+ */
+static void start_board (GcomprisBoard *agcomprisBoard)
+{
+ GHashTable *config = gc_db_get_board_conf();
+ gchar * filename;
+
+ gc_locale_set(g_hash_table_lookup( config, "locale"));
+
+ g_hash_table_destroy(config);
+
+ if(agcomprisBoard!=NULL)
+ {
+ gcomprisBoard_missing=agcomprisBoard;
+ gc_set_background(gnome_canvas_root(gcomprisBoard_missing->canvas),
+ "opt/missingletter-bg.jpg");
+ gcomprisBoard_missing->level=1;
+
+ /* Calculate the maxlevel based on the available data file for this board */
+ gcomprisBoard_missing->maxlevel = 1;
+ while((filename = gc_file_find_absolute("%s/board%d.xml",
+ gcomprisBoard_missing->boarddir, ++gcomprisBoard_missing->maxlevel)))
+ g_free(filename);
+
+ gcomprisBoard_missing->maxlevel--;
+
+ gcomprisBoard_missing->sublevel=1;
+ gcomprisBoard_missing->number_of_sublevel=G_MAXINT;
+
+ init_xml();
+ gc_bar_set(GC_BAR_CONFIG | GC_BAR_LEVEL);
+
+ missing_letter_next_level();
+
+ gamewon = FALSE;
+ pause_board(FALSE);
+ }
+}
+
+static void end_board ()
+{
+
+ if(gcomprisBoard_missing!=NULL)
+ {
+ pause_board(TRUE);
+ gc_score_end();
+ missing_letter_destroy_all_items();
+ missing_destroy_board_list(board_list);
+ board_list = NULL;
+ }
+
+ gc_locale_reset();
+
+ gcomprisBoard_missing = NULL;
+}
+
+static void
+set_level (guint level)
+{
+
+ if(gcomprisBoard_missing!=NULL)
+ {
+ gcomprisBoard_missing->level=level;
+ gcomprisBoard_missing->sublevel=1;
+ init_xml();
+ missing_letter_next_level();
+ }
+}
+
+static gboolean
+is_our_board (GcomprisBoard *gcomprisBoard)
+{
+ if (gcomprisBoard)
+ {
+ if(g_strcasecmp(gcomprisBoard->type, "missingletter")==0)
+ {
+ /* Set the plugin entry */
+ gcomprisBoard->plugin=&menu_bp;
+
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/*-------------------------------------------------------------------------------*/
+/*-------------------------------------------------------------------------------*/
+/* set initial values for the next level */
+static void missing_letter_next_level()
+{
+ gc_bar_set_level(gcomprisBoard_missing);
+
+ missing_letter_destroy_all_items();
+ selected_button = NULL;
+ gamewon = FALSE;
+
+ gc_score_set(gcomprisBoard_missing->sublevel);
+
+ /* Try the next level */
+ missing_letter_create_item(gnome_canvas_root(gcomprisBoard_missing->canvas));
+
+}
+/* ==================================== */
+/* Destroy all the items */
+static void missing_letter_destroy_all_items()
+{
+ if(boardRootItem!=NULL)
+ gtk_object_destroy (GTK_OBJECT(boardRootItem));
+
+ boardRootItem = NULL;
+}
+/* ==================================== */
+static GnomeCanvasItem *missing_letter_create_item(GnomeCanvasGroup *parent)
+{
+ char *buf[3];
+ int xOffset,yOffset,place;
+ double dx1, dy1, dx2, dy2;
+ GdkPixbuf *button_pixmap = NULL;
+ GdkPixbuf *pixmap = NULL;
+
+ /* This are the values of the area in which we must display the image */
+ gint img_area_x = 290;
+ gint img_area_y = 80;
+ gint img_area_w = 440;
+ gint img_area_h = 310;
+
+ /* this is the coordinate of the text to find */
+ gint txt_area_x = 515;
+ gint txt_area_y = 435;
+
+ place = g_random_int_range( 0, 3);
+ g_assert(place >= 0 && place < 3);
+
+ right_word = place+1;
+
+ boardRootItem = GNOME_CANVAS_GROUP(
+ gnome_canvas_item_new (gnome_canvas_root(gcomprisBoard_missing->canvas),
+ gnome_canvas_group_get_type (),
+ "x", (double) 0,
+ "y", (double) 0,
+ NULL));
+ button_pixmap = gc_skin_pixmap_load("button.png");
+ /* display the image */
+ board = g_list_nth_data(board_list, gcomprisBoard_missing->sublevel-1);
+ g_assert(board != NULL);
+ pixmap = gc_pixmap_load(board->pixmapfile);
+
+ yOffset = (gcomprisBoard_missing->height - gdk_pixbuf_get_height(button_pixmap) - gdk_pixbuf_get_height(pixmap) - 2*VERTICAL_SEPARATION)/2;
+
+ text_s = gnome_canvas_item_new (boardRootItem,
+ gnome_canvas_text_get_type (),
+ "text", _(board->question),
+ "font", gc_skin_font_board_huge_bold,
+ "x", (double) txt_area_x + 1.0,
+ "y", (double) txt_area_y + 1.0,
+ "anchor", GTK_ANCHOR_CENTER,
+ "fill_color_rgba", gc_skin_get_color("missingletter/shadow"),
+ NULL);
+ text = gnome_canvas_item_new (boardRootItem,
+ gnome_canvas_text_get_type (),
+ "text", _(board->question),
+ "font", gc_skin_font_board_huge_bold,
+ "x", (double) txt_area_x,
+ "y", (double) txt_area_y,
+ "anchor", GTK_ANCHOR_CENTER,
+ "fill_color_rgba", gc_skin_get_color("missingletter/question"),
+ NULL);
+
+ gnome_canvas_item_get_bounds(text, &dx1, &dy1, &dx2, &dy2);
+ yOffset += VERTICAL_SEPARATION + dy2-dy1;
+
+ image_item = gnome_canvas_item_new (boardRootItem,
+ gnome_canvas_pixbuf_get_type (),
+ "pixbuf", pixmap,
+ "x", (double) img_area_x+(img_area_w - gdk_pixbuf_get_width(pixmap))/2,
+ "y", (double) img_area_y+(img_area_h - gdk_pixbuf_get_height(pixmap))/2,
+ "width", (double) gdk_pixbuf_get_width(pixmap),
+ "height", (double) gdk_pixbuf_get_height(pixmap),
+ "width_set", TRUE,
+ "height_set", TRUE,
+ NULL);
+ gdk_pixbuf_unref(pixmap);
+
+ /* display the 3 words */
+ /* the right word is at position 0 : it is swapped with any position depending of place value */
+
+ switch (place) {
+ case 1 :
+ buf[0] = board->l2;
+ buf[1] = board->l1;
+ buf[2] = board->l3;
+ break;
+ case 2 :
+ buf[0] = board->l3;
+ buf[1] = board->l2;
+ buf[2] = board->l1;
+ break;
+ default :
+ buf[0] = board->l1;
+ buf[1] = board->l2;
+ buf[2] = board->l3;
+ break;
+ }
+
+ yOffset = ( gcomprisBoard_missing->height - 3*gdk_pixbuf_get_height(button_pixmap) - 2*VERTICAL_SEPARATION) / 2;
+ xOffset = (img_area_x-gdk_pixbuf_get_width(button_pixmap))/2;
+ button1 = gnome_canvas_item_new (boardRootItem,
+ gnome_canvas_pixbuf_get_type (),
+ "pixbuf", button_pixmap,
+ "x", (double) xOffset,
+ "y", (double) yOffset,
+ NULL);
+ gnome_canvas_item_new (boardRootItem,
+ gnome_canvas_text_get_type (),
+ "text", buf[0],
+ "font", gc_skin_font_board_huge_bold,
+ "x", (double) xOffset + gdk_pixbuf_get_width(button_pixmap)/2 + 1.0,
+ "y", (double) yOffset + gdk_pixbuf_get_height(button_pixmap)/2 + 1.0,
+ "anchor", GTK_ANCHOR_CENTER,
+ "fill_color_rgba", gc_skin_color_shadow,
+ NULL);
+ l1_item = gnome_canvas_item_new (boardRootItem,
+ gnome_canvas_text_get_type (),
+ "text", buf[0],
+ "font", gc_skin_font_board_huge_bold,
+ "x", (double) xOffset + gdk_pixbuf_get_width(button_pixmap)/2,
+ "y", (double) yOffset + gdk_pixbuf_get_height(button_pixmap)/2,
+ "anchor", GTK_ANCHOR_CENTER,
+ "fill_color_rgba", gc_skin_color_text_button,
+ NULL);
+
+ yOffset += HORIZONTAL_SEPARATION + gdk_pixbuf_get_height(button_pixmap);
+ button2 = gnome_canvas_item_new (boardRootItem,
+ gnome_canvas_pixbuf_get_type (),
+ "pixbuf", button_pixmap,
+ "x", (double) xOffset,
+ "y", (double) yOffset,
+ NULL);
+ gnome_canvas_item_new (boardRootItem,
+ gnome_canvas_text_get_type (),
+ "text", buf[1],
+ "font", gc_skin_font_board_huge_bold,
+ "x", (double) xOffset + gdk_pixbuf_get_width(button_pixmap)/2 + 1.0,
+ "y", (double) yOffset + gdk_pixbuf_get_height(button_pixmap)/2 + 1.0,
+ "anchor", GTK_ANCHOR_CENTER,
+ "fill_color_rgba", gc_skin_color_shadow,
+ NULL);
+ l2_item = gnome_canvas_item_new (boardRootItem,
+ gnome_canvas_text_get_type (),
+ "text", buf[1],
+ "font", gc_skin_font_board_huge_bold,
+ "x", (double) xOffset + gdk_pixbuf_get_width(button_pixmap)/2,
+ "y", (double) yOffset + gdk_pixbuf_get_height(button_pixmap)/2,
+ "anchor", GTK_ANCHOR_CENTER,
+ "fill_color_rgba", gc_skin_color_text_button,
+ NULL);
+
+ yOffset += HORIZONTAL_SEPARATION + gdk_pixbuf_get_height(button_pixmap);
+
+ button3 = gnome_canvas_item_new (boardRootItem,
+ gnome_canvas_pixbuf_get_type (),
+ "pixbuf", button_pixmap,
+ "x", (double) xOffset,
+ "y", (double) yOffset,
+ NULL);
+ gnome_canvas_item_new (boardRootItem,
+ gnome_canvas_text_get_type (),
+ "text", buf[2],
+ "font", gc_skin_font_board_huge_bold,
+ "x", (double) xOffset + gdk_pixbuf_get_width(button_pixmap)/2 + 1.0,
+ "y", (double) yOffset + gdk_pixbuf_get_height(button_pixmap)/2 + 1.0,
+ "anchor", GTK_ANCHOR_CENTER,
+ "fill_color_rgba", gc_skin_color_shadow,
+ NULL);
+ l3_item = gnome_canvas_item_new (boardRootItem,
+ gnome_canvas_text_get_type (),
+ "text", buf[2],
+ "font", gc_skin_font_board_huge_bold,
+ "x", (double) xOffset + gdk_pixbuf_get_width(button_pixmap)/2,
+ "y", (double) yOffset + gdk_pixbuf_get_height(button_pixmap)/2,
+ "anchor", GTK_ANCHOR_CENTER,
+ "fill_color_rgba", gc_skin_color_text_button,
+ NULL);
+
+ gdk_pixbuf_unref(button_pixmap);
+
+ gtk_signal_connect(GTK_OBJECT(l1_item), "event", (GtkSignalFunc) item_event, NULL);
+ gtk_signal_connect(GTK_OBJECT(l2_item), "event", (GtkSignalFunc) item_event, NULL);
+ gtk_signal_connect(GTK_OBJECT(l3_item), "event", (GtkSignalFunc) item_event, NULL);
+
+ gtk_signal_connect(GTK_OBJECT(button1), "event", (GtkSignalFunc) item_event, NULL);
+ gtk_signal_connect(GTK_OBJECT(button2), "event", (GtkSignalFunc) item_event, NULL);
+ gtk_signal_connect(GTK_OBJECT(button3), "event", (GtkSignalFunc) item_event, NULL);
+ return NULL;
+}
+/* ==================================== */
+static void game_won() {
+ gcomprisBoard_missing->sublevel++;
+
+ if(gcomprisBoard_missing->sublevel>gcomprisBoard_missing->number_of_sublevel) {
+ /* Try the next level */
+ gcomprisBoard_missing->sublevel=1;
+ gcomprisBoard_missing->level++;
+ init_xml();
+
+ if(gcomprisBoard_missing->level>gcomprisBoard_missing->maxlevel) {
+ gc_bonus_end_display(GC_BOARD_FINISHED_TUXPLANE);
+ return;
+ }
+ }
+ missing_letter_next_level();
+}
+
+/* ==================================== */
+static gboolean process_ok_timeout() {
+ gc_bonus_display(gamewon, GC_BONUS_FLOWER);
+ return FALSE;
+}
+
+static void process_ok() {
+ if (gamewon) {
+ gnome_canvas_item_set(text, "text", board->answer, NULL);
+ gnome_canvas_item_set(text_s, "text", board->answer, NULL);
+ }
+ // leave time to display the right answer
+ gc_bar_hide(TRUE);
+ g_timeout_add(TIME_CLICK_TO_BONUS, process_ok_timeout, NULL);
+}
+
+/* ==================================== */
+static gint
+item_event(GnomeCanvasItem *item, GdkEvent *event, gpointer data)
+{
+ double item_x, item_y;
+ GnomeCanvasItem * temp = NULL;
+ item_x = event->button.x;
+ item_y = event->button.y;
+ gnome_canvas_item_w2i(item->parent, &item_x, &item_y);
+
+ if(board_paused)
+ return FALSE;
+
+ switch (event->type)
+ {
+ case GDK_BUTTON_PRESS:
+ board_paused = TRUE;
+ temp = item;
+ if (item == l1_item)
+ temp = button1;
+ if (item == l2_item)
+ temp = button2;
+ if (item == l3_item)
+ temp = button3;
+
+ g_assert(temp == button1 || temp == button2 || temp == button3);
+
+ if ( ( temp == button1 && right_word == 1) ||
+ ( temp == button2 && right_word == 2) ||
+ ( temp == button3 && right_word == 3) ) {
+ gamewon = TRUE;
+ } else {
+ gamewon = FALSE;
+ }
+ highlight_selected(temp);
+ process_ok();
+ break;
+
+ default:
+ break;
+ }
+ return FALSE;
+}
+/* ==================================== */
+static void highlight_selected(GnomeCanvasItem * item) {
+ GdkPixbuf *button_pixmap_selected = NULL, *button_pixmap = NULL;
+ GnomeCanvasItem *button;
+
+ /* Replace text item by button item */
+ button = item;
+ if ( button == l1_item ) {
+ button = button1;
+ } else if ( item == l2_item ) {
+ button = button2;
+ } else if ( item == l3_item ) {
+ button = button3;
+ }
+
+ if (selected_button != NULL && selected_button != button) {
+ button_pixmap = gc_skin_pixmap_load("button.png");
+ gnome_canvas_item_set(selected_button, "pixbuf", button_pixmap, NULL);
+ gdk_pixbuf_unref(button_pixmap);
+ }
+
+ if (selected_button != button) {
+ button_pixmap_selected = gc_skin_pixmap_load("button_selected.png");
+ gnome_canvas_item_set(button, "pixbuf", button_pixmap_selected, NULL);
+ selected_button = button;
+ gdk_pixbuf_unref(button_pixmap_selected);
+ }
+
+}
+
+/* ===================================
+ * XML stuff
+ * Ref : shapegame.c
+ * ==================================== */
+/* ====== for DEBUG ======== */
+#if 0
+static void dump_xml() {
+ GList *list;
+ g_warning("XML lentgh = %d\n", g_list_length(board_list));
+
+ for(list = board_list; list != NULL; list = list->next) {
+ Board * board = list->data;
+ g_warning("xml = %s %s %s %s %s %s\n", board->pixmapfile, board->answer, board->question, board->l1, board->l2, board->l3);
+ }
+}
+#endif
+
+/* ==================================== */
+static void init_xml()
+{
+ char *filename;
+
+ if(board_list)
+ {
+ missing_destroy_board_list(board_list);
+ board_list = NULL;
+ }
+ filename = gc_file_find_absolute("%s/board%d.xml",
+ gcomprisBoard_missing->boarddir,
+ gcomprisBoard_missing->level);
+ missing_read_xml_file(filename, &board_list);
+ gcomprisBoard_missing->number_of_sublevel = g_list_length(board_list);
+ g_free(filename);
+
+ gc_score_end();
+ gc_score_start(SCORESTYLE_NOTE,
+ 50,
+ gcomprisBoard_missing->height - 50,
+ gcomprisBoard_missing->number_of_sublevel);
+}
+
+/* ==================================== */
+static void add_xml_data(xmlDocPtr doc, xmlNodePtr xmlnode, GList **list)
+{
+ gchar *pixmapfile = NULL;
+ gchar *question = NULL, *answer = NULL;
+ gchar *l1 = NULL, *l2 = NULL, *l3 = NULL;
+ gchar *data = NULL;
+ Board * board = g_new(Board,1);
+ gboolean found = FALSE;
+
+ xmlnode = xmlnode->xmlChildrenNode;
+
+ xmlnode = xmlnode->next;
+
+ while (xmlnode != NULL && !found) {
+
+ if (!strcmp((char *)xmlnode->name, "pixmapfile"))
+ pixmapfile = (gchar *)xmlNodeListGetString(doc, xmlnode->xmlChildrenNode, 1);
+
+ if (!found && !strcmp((char *)xmlnode->name, "data"))
+ {
+ if(data==NULL)
+ {
+ gchar *tmp;
+ tmp = (gchar *)xmlNodeListGetString(doc, xmlnode->xmlChildrenNode, 1);
+ data = g_strdup(gettext(tmp));
+ g_free(tmp);
+ }
+ }
+ xmlnode = xmlnode->next;
+ }
+
+ gchar **all_answer = g_strsplit(data, "/", 5);
+ g_free(data);
+
+ answer = all_answer[0];
+ question = all_answer[1];
+ l1 = all_answer[2];
+ l2 = all_answer[3];
+ l3 = all_answer[4];
+
+ g_assert(l1 != NULL && l2 != NULL && l3 != NULL && answer != NULL && question != NULL);
+
+ board->pixmapfile = pixmapfile;
+ board->question = g_strdup(question);
+ board->answer = g_strdup(answer);
+ board->l1 = g_strdup(l1);
+ board->l2 = g_strdup(l2);
+ board->l3 = g_strdup(l3);
+
+ g_strfreev(all_answer);
+
+ *list = g_list_append (*list, board);
+}
+
+
+/* ==================================== */
+/* read an xml file into our memory structures and update our view,
+ dump any old data we have in memory if we can load a new set */
+gboolean missing_read_xml_file(char *fname, GList **list)
+{
+ /* pointer to the new doc */
+ xmlDocPtr doc;
+ xmlNodePtr node;
+
+ g_return_val_if_fail(fname!=NULL,FALSE);
+
+ /* parse the new file and put the result into newdoc */
+ doc = xmlParseFile(fname);
+
+ /* in case something went wrong */
+ if(!doc)
+ return FALSE;
+
+ if(/* if there is no root element */
+ !doc->children ||
+ /* if it doesn't have a name */
+ !doc->children->name ||
+ /* if it isn't a ImageId node */
+ g_strcasecmp((char *)doc->children->name,"missing_letter")!=0) {
+ xmlFreeDoc(doc);
+ return FALSE;
+ }
+
+ for(node = doc->children->children; node != NULL; node = node->next) {
+ if ( g_strcasecmp((gchar *)node->name, "Board") == 0 )
+ add_xml_data(doc, node, list);
+ }
+ xmlFreeDoc(doc);
+ return TRUE;
+}
+
+/* ======================================= */
+void missing_destroy_board_list(GList *list) {
+ Board *board;
+ while(g_list_length(list)>0)
+ {
+ board = g_list_nth_data(list, 0);
+ list = g_list_remove (list, board);
+ destroy_board(board);
+ }
+}
+
+/* ======================================= */
+static void destroy_board(Board * board) {
+ g_free(board->pixmapfile);
+ g_free(board->answer);
+ g_free(board->question);
+ g_free(board->l1);
+ g_free(board->l2);
+ g_free(board->l3);
+ g_free(board);
+}
+
+/* ************************************* */
+/* * Configuration * */
+/* ************************************* */
+
+
+/* ======================= */
+/* = config_start = */
+/* ======================= */
+
+static GcomprisProfile *profile_conf;
+static GcomprisBoard *board_conf;
+
+/* GHFunc */
+static void save_table (gpointer key,
+ gpointer value,
+ gpointer user_data)
+{
+ gc_db_set_board_conf ( profile_conf,
+ board_conf,
+ (gchar *) key,
+ (gchar *) value);
+}
+
+static GcomprisConfCallback conf_ok(GHashTable *table)
+{
+ if (!table){
+ if (gcomprisBoard_missing)
+ pause_board(FALSE);
+ return NULL;
+ }
+
+ g_hash_table_foreach(table, (GHFunc) save_table, NULL);
+
+ if (gcomprisBoard_missing){
+ gc_locale_reset();
+
+ GHashTable *config;
+
+ if (profile_conf)
+ config = gc_db_get_board_conf();
+ else
+ config = table;
+
+ gc_locale_set(g_hash_table_lookup( config, "locale"));
+
+ if (profile_conf)
+ g_hash_table_destroy(config);
+
+ init_xml();
+
+ missing_letter_next_level();
+
+ }
+
+ board_conf = NULL;
+ profile_conf = NULL;
+ pause_board(FALSE);
+
+ return NULL;
+}
+
+static void
+config_start(GcomprisBoard *agcomprisBoard,
+ GcomprisProfile *aProfile)
+{
+ board_conf = agcomprisBoard;
+ profile_conf = aProfile;
+
+ if (gcomprisBoard_missing)
+ pause_board(TRUE);
+
+ gchar *label = g_strdup_printf(_("<b>%s</b> configuration\n for profile <b>%s</b>"),
+ agcomprisBoard->name,
+ aProfile ? aProfile->name : "");
+ GcomprisBoardConf *bconf;
+ bconf = gc_board_config_window_display( label,
+ (GcomprisConfCallback )conf_ok);
+
+ g_free(label);
+
+ /* init the combo to previously saved value */
+ GHashTable *config = gc_db_get_conf( profile_conf, board_conf);
+
+ gchar *locale = g_hash_table_lookup( config, "locale");
+
+ gc_board_config_combo_locales(bconf, locale);
+ config_missing_letter(bconf);
+}
+
+
+/* ======================= */
+/* = config_stop = */
+/* ======================= */
+static void
+config_stop()
+{
+}
diff --git a/src/gcompris/board_config_wordlist.c b/src/gcompris/board_config_wordlist.c
index b0609ba..a6364b2 100644
--- a/src/gcompris/board_config_wordlist.c
+++ b/src/gcompris/board_config_wordlist.c
@@ -49,7 +49,7 @@ static void _combo_level_changed(GtkComboBox *combo_level, gpointer user_data)
}
wordsArray = g_malloc0(sizeof(gpointer)*(g_slist_length(lw->words)+1));
-
+
for(i=0, list = lw->words; list; list=list->next)
{
wordsArray[i]=(gchar*)list->data;
@@ -159,7 +159,7 @@ static void _button_clicked(GtkWidget *w, gpointer data)
static void _destroy(GtkWidget *w, gpointer data)
{
user_param_type_wordlist *u = (user_param_type_wordlist*)data;
-
+
gc_wordlist_free(u->wordlist);
g_free(u);
}
@@ -177,7 +177,7 @@ GtkWidget *gc_board_config_wordlist(GcomprisBoardConf *config, const gchar *file
const gchar *locale;
/* frame */
- frame = gtk_frame_new("Change wordlist");
+ frame = gtk_frame_new(_("Configure the list of words"));
gtk_widget_show(frame);
gtk_box_pack_start(GTK_BOX(config->main_conf_box), frame, FALSE, FALSE, 8);
@@ -206,7 +206,7 @@ GtkWidget *gc_board_config_wordlist(GcomprisBoardConf *config, const gchar *file
gtk_widget_show(combo_lang);
hbox = gtk_hbox_new(FALSE, 8);
- label = gtk_label_new(_("Choice language"));
+ label = gtk_label_new(_("Choice of the language"));
gtk_widget_show(label);
gtk_widget_show(hbox);
gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 8);
@@ -218,7 +218,7 @@ GtkWidget *gc_board_config_wordlist(GcomprisBoardConf *config, const gchar *file
gtk_widget_show(combo_level);
hbox = gtk_hbox_new(FALSE, 8);
- label = gtk_label_new(_("Choice level"));
+ label = gtk_label_new(_("Choice of the level"));
gtk_widget_show(label);
gtk_widget_show(hbox);
gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 8);
@@ -243,7 +243,7 @@ GtkWidget *gc_board_config_wordlist(GcomprisBoardConf *config, const gchar *file
gtk_widget_show(hbox);
gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 8);
- GtkWidget * b_default = gtk_button_new_with_label(_("Return to default"));
+ GtkWidget * b_default = gtk_button_new_with_label(_("Back to default"));
gtk_widget_show(b_default);
gtk_box_pack_start(GTK_BOX(hbox), b_default, FALSE, FALSE, 8);
diff --git a/src/gcompris/gameutil.c b/src/gcompris/gameutil.c
index 465ce04..d7a6edb 100644
--- a/src/gcompris/gameutil.c
+++ b/src/gcompris/gameutil.c
@@ -627,8 +627,6 @@ gc_file_find_absolute(const gchar *format, ...)
g_free(filename2);
goto FOUND;
}
- g_free(absolute_filename);
-
g_free(filename2);
}
diff --git a/src/gcompris/gc_net.c b/src/gcompris/gc_net.c
index ecc7b73..106ec1c 100644
--- a/src/gcompris/gc_net.c
+++ b/src/gcompris/gc_net.c
@@ -187,7 +187,8 @@ gc_net_get_url_from_file(const gchar *format, ...)
return cache;
#endif
- }
+}
+
#if 0
/** return a glist with the content of the files in the given directory
diff --git a/src/gcompris/gc_net.h b/src/gcompris/gc_net.h
index c377748..1b162cd 100644
--- a/src/gcompris/gc_net.h
+++ b/src/gcompris/gc_net.h
@@ -38,6 +38,7 @@ void gc_net_destroy();
void gc_cache_init(void);
void gc_cache_add(gchar *filename);
+gchar* gc_cache_import_pixmap(gchar *filename, gchar *boarddir, gint width, gint height);
void gc_cache_remove(gchar *filename);
void gc_cache_save(void);
void gc_cache_destroy(void);
diff --git a/src/gcompris/gcompris.c b/src/gcompris/gcompris.c
index efbe124..5c1ec19 100644
--- a/src/gcompris/gcompris.c
+++ b/src/gcompris/gcompris.c
@@ -136,6 +136,9 @@ static gchar *popt_user_dir = NULL;
static gint popt_experimental = FALSE;
static gint popt_no_quit = FALSE;
static gint popt_no_config = FALSE;
+static gchar *popt_server = NULL;
+static gint *popt_web_only = NULL;
+static gchar *popt_cache_dir = NULL;
static gchar *popt_drag_mode = NULL;
static gchar *sugarBundleId = NULL;
static gchar *sugarActivityId = NULL;
@@ -221,6 +224,16 @@ static GOptionEntry options[] = {
{"disable-config",'\0', 0, G_OPTION_ARG_NONE, &popt_no_config,
N_("Disable the config button"), NULL},
+ {"server", '\0', 0, G_OPTION_ARG_STRING, &popt_server,
+ N_("GCompris will get images, sounds and activity data from this server if not found locally."), NULL},
+
+ {"web-only", '\0', 0, G_OPTION_ARG_NONE, &popt_web_only,
+ N_("Only when --server is provided, disable check for local resource first."
+ " Data are always taken from the web server."), NULL},
+
+ {"cache-dir", '\0', 0, G_OPTION_ARG_STRING, &popt_cache_dir,
+ N_("In server mode, specify the cache directory used to avoid useless downloads."), NULL},
+
{"drag-mode", 'g', 0, G_OPTION_ARG_STRING, &popt_drag_mode,
N_("Global drag and drop mode: normal, 2clicks, both. Default mode is normal."), NULL},
@@ -1602,7 +1615,7 @@ main (int argc, char *argv[])
{
if (g_access(properties->database, R_OK)==-1)
{
- printf("%s exists but is not readable or writable", properties->database);
+ printf(_("%s exists but is not readable or writable"), properties->database);
exit(0);
}
}
@@ -1660,6 +1673,33 @@ main (int argc, char *argv[])
properties->reread_menu = TRUE;
}
+ if (popt_server){
+#ifdef USE_GNET
+ properties->server = g_strdup(popt_server);
+ printf(" Server '%s'\n", properties->server);
+#else
+ printf(_("The --server option cannot be used because"
+ "GCompris has been compiled without network support!"));
+ exit(1);
+#endif
+ }
+
+ if(popt_web_only) {
+ g_free(properties->package_data_dir);
+ properties->package_data_dir = g_strdup("");
+
+ g_free(properties->system_icon_dir);
+ properties->system_icon_dir = g_strdup("");
+ }
+
+ if (popt_server){
+ if(popt_cache_dir)
+ properties->cache_dir = g_strdup(popt_cache_dir);
+ else
+ properties->cache_dir = g_build_filename(g_get_user_cache_dir(), "gcompris", NULL);
+ printf(" Cache dir '%s'\n",properties->cache_dir);
+ }
+
if (popt_drag_mode){
if (strcmp(popt_drag_mode, "default") == 0)
properties->drag_mode = GC_DRAG_MODE_GRAB;
@@ -1692,7 +1732,8 @@ main (int argc, char *argv[])
if(properties->profile == NULL)
{
- printf("ERROR: Profile '%s' is not found. Run 'gcompris --profile-list' to list available ones\n",
+ printf(_("ERROR: Profile '%s' is not found."
+ " Run 'gcompris --profile-list' to list available ones\n"),
popt_profile);
exit(1);
}
diff --git a/src/missing_letter-activity/Makefile.am b/src/missing_letter-activity/Makefile.am
index e59e8d1..5c1cdec 100644
--- a/src/missing_letter-activity/Makefile.am
+++ b/src/missing_letter-activity/Makefile.am
@@ -25,7 +25,7 @@ INCLUDES = -I$(top_srcdir)/src \
libmissingletter_la_LDFLAGS = $(shared) $(no_undefined) -module -avoid-version $(gc_libs)
libmissingletter_la_LIBADD =
-libmissingletter_la_SOURCES = missingletter.c
+libmissingletter_la_SOURCES = missingletter.c missingletter_config.c missingletter.h
xmldir = $(pkgdatadir)/@PACKAGE_DATA_DIR@
diff --git a/src/missing_letter-activity/missingletter.c b/src/missing_letter-activity/missingletter.c
index 80a3f79..cb9bfaf 100644
--- a/src/missing_letter-activity/missingletter.c
+++ b/src/missing_letter-activity/missingletter.c
@@ -24,18 +24,11 @@
#include <libxml/tree.h>
#include <libxml/parser.h>
-#define SOUNDLISTFILE PACKAGE
+#include "missingletter.h"
-#define MAX_PROPOSAL 6
-typedef struct _Board {
- gchar *pixmapfile;
- gchar *question;
- gchar *answer;
- gchar *text[MAX_PROPOSAL + 1];
- guint solution;
-} Board;
+#define SOUNDLISTFILE PACKAGE
-static GcomprisBoard *gcomprisBoard = NULL;
+GcomprisBoard *gcomprisBoard_missing = NULL;
static gboolean board_paused = TRUE;
static void start_board (GcomprisBoard *agcomprisBoard);
@@ -43,6 +36,7 @@ static void pause_board (gboolean pause);
static void end_board (void);
static gboolean is_our_board (GcomprisBoard *gcomprisBoard);
static void set_level (guint level);
+static int gamewon;
static void process_ok(gchar *answer);
static void highlight_selected(GooCanvasItem *);
static void game_won(void);
@@ -50,15 +44,14 @@ static void config_start(GcomprisBoard *agcomprisBoard,
GcomprisProfile *aProfile);
static void config_stop(void);
-static int gamewon;
+/* from missingletter_config.c */
+void config_missing_letter(GcomprisBoardConf *config);
/* XML */
-static gboolean read_xml_file(char *fname);
static void init_xml(guint level);
-static void add_xml_data(xmlDocPtr, xmlNodePtr, GNode *);
-static void parse_doc(xmlDocPtr doc);
-static gboolean read_xml_file(char *fname);
-static void destroy_board_list();
+static void add_xml_data(xmlDocPtr, xmlNodePtr, GList **list);
+gboolean missing_read_xml_file(char *fname, GList **list);
+void missing_destroy_board_list(GList *);
static void destroy_board(Board * board);
/* This is the list of boards */
@@ -122,7 +115,7 @@ GET_BPLUGIN_INFO(missingletter)
*/
static void pause_board (gboolean pause)
{
- if(gcomprisBoard==NULL)
+ if(gcomprisBoard_missing==NULL)
return;
gc_bar_hide(FALSE);
@@ -135,12 +128,31 @@ static void pause_board (gboolean pause)
board_paused = pause;
}
+static void _init(GcomprisBoard *agcomprisBoard)
+{
+ gchar * filename;
+ gcomprisBoard_missing->level=1;
+
+ /* Calculate the maxlevel based on the available data file for this board */
+ gcomprisBoard_missing->maxlevel = 1;
+ while((filename = gc_file_find_absolute("%s/board%d.xml",
+ gcomprisBoard_missing->boarddir,
+ ++gcomprisBoard_missing->maxlevel)))
+ g_free(filename);
+
+ gcomprisBoard_missing->maxlevel--;
+
+ gcomprisBoard_missing->sublevel=1;
+ gcomprisBoard_missing->number_of_sublevel=G_MAXINT;
+
+ init_xml(gcomprisBoard_missing->level);
+}
+
/*
*/
static void
start_board (GcomprisBoard *agcomprisBoard)
{
- gchar *filename = NULL;
GHashTable *config = gc_db_get_board_conf();
gc_locale_set(g_hash_table_lookup( config, "locale"));
@@ -149,27 +161,10 @@ start_board (GcomprisBoard *agcomprisBoard)
if(agcomprisBoard!=NULL)
{
- gcomprisBoard=agcomprisBoard;
- gc_set_background(goo_canvas_get_root_item(gcomprisBoard->canvas),
+ gcomprisBoard_missing=agcomprisBoard;
+ gc_set_background(goo_canvas_get_root_item(gcomprisBoard_missing->canvas),
"missing_letter/missingletter-bg.jpg");
- gcomprisBoard->level=1;
- gcomprisBoard->sublevel=1;
-
- /* Calculate the maxlevel based on the available data file for this board */
- gcomprisBoard->maxlevel=1;
-
- while( (filename = gc_file_find_absolute("%s/board%d.xml",
- gcomprisBoard->boarddir,
- gcomprisBoard->maxlevel++,
- NULL)) )
- {
- g_free(filename);
-
- }
- g_free(filename);
-
- gcomprisBoard->maxlevel -= 2;
-
+ _init(agcomprisBoard);
gc_bar_set(GC_BAR_CONFIG | GC_BAR_LEVEL);
gc_bar_location(10, -1, 0.9);
@@ -183,27 +178,29 @@ start_board (GcomprisBoard *agcomprisBoard)
static void end_board ()
{
- if(gcomprisBoard!=NULL)
+ if(gcomprisBoard_missing!=NULL)
{
pause_board(TRUE);
gc_score_end();
missing_letter_destroy_all_items();
- destroy_board_list();
+ missing_destroy_board_list(board_list);
+ board_list = NULL;
}
gc_locale_reset();
- gcomprisBoard = NULL;
+ gcomprisBoard_missing = NULL;
}
static void
set_level (guint level)
{
- if(gcomprisBoard!=NULL)
+ if(gcomprisBoard_missing!=NULL)
{
- gcomprisBoard->level=level;
- gcomprisBoard->sublevel=1;
+ gcomprisBoard_missing->level=level;
+ gcomprisBoard_missing->sublevel=1;
+ init_xml(gcomprisBoard_missing->level);
missing_letter_next_level();
}
}
@@ -230,28 +227,26 @@ is_our_board (GcomprisBoard *gcomprisBoard)
static void
missing_letter_next_level()
{
- gc_bar_set_level(gcomprisBoard);
+ gc_bar_set_level(gcomprisBoard_missing);
missing_letter_destroy_all_items();
selected_button = NULL;
gamewon = FALSE;
- destroy_board_list();
- init_xml(gcomprisBoard->level);
-
- gcomprisBoard->number_of_sublevel = g_list_length(board_list);
+ init_xml(gcomprisBoard_missing->level);
+ gcomprisBoard_missing->number_of_sublevel = g_list_length(board_list);
gc_score_end();
gc_score_start(SCORESTYLE_NOTE,
BOARDWIDTH - 195,
BOARDHEIGHT - 30,
- gcomprisBoard->number_of_sublevel);
+ gcomprisBoard_missing->number_of_sublevel);
- gc_score_set(gcomprisBoard->sublevel);
+ gc_score_set(gcomprisBoard_missing->sublevel);
/* Try the next level */
- missing_letter_create_item(goo_canvas_get_root_item(gcomprisBoard->canvas));
+ missing_letter_create_item(goo_canvas_get_root_item(gcomprisBoard_missing->canvas));
}
static void
@@ -261,10 +256,10 @@ missing_letter_next_sublevel()
selected_button = NULL;
gamewon = FALSE;
- gc_score_set(gcomprisBoard->sublevel);
+ gc_score_set(gcomprisBoard_missing->sublevel);
/* Try the next level */
- missing_letter_create_item(goo_canvas_get_root_item(gcomprisBoard->canvas));
+ missing_letter_create_item(goo_canvas_get_root_item(gcomprisBoard_missing->canvas));
}
/* ==================================== */
@@ -299,12 +294,12 @@ missing_letter_create_item(GooCanvasItem *parent)
guint vertical_separation;
gint i;
- board_number = gcomprisBoard->sublevel-1;
+ board_number = gcomprisBoard_missing->sublevel-1;
g_assert(board_number >= 0 && board_number < g_list_length(board_list));
boardRootItem = \
- goo_canvas_group_new (goo_canvas_get_root_item(gcomprisBoard->canvas),
+ goo_canvas_group_new (goo_canvas_get_root_item(gcomprisBoard_missing->canvas),
NULL);
button_pixmap = gc_pixmap_load("missing_letter/button.png");
@@ -417,15 +412,15 @@ missing_letter_create_item(GooCanvasItem *parent)
/* ==================================== */
static void game_won() {
- gcomprisBoard->sublevel++;
+ gcomprisBoard_missing->sublevel++;
- if(gcomprisBoard->sublevel>gcomprisBoard->number_of_sublevel)
+ if(gcomprisBoard_missing->sublevel>gcomprisBoard_missing->number_of_sublevel)
{
/* Try the next level */
- gcomprisBoard->sublevel=1;
- gcomprisBoard->level++;
- if(gcomprisBoard->level>gcomprisBoard->maxlevel)
- gcomprisBoard->level = gcomprisBoard->maxlevel;
+ gcomprisBoard_missing->sublevel=1;
+ gcomprisBoard_missing->level++;
+ if(gcomprisBoard_missing->level>gcomprisBoard_missing->maxlevel)
+ gcomprisBoard_missing->level = gcomprisBoard_missing->maxlevel;
missing_letter_next_level();
}
@@ -526,17 +521,22 @@ init_xml(guint level)
{
gchar *filename;
+ if(board_list)
+ {
+ missing_destroy_board_list(board_list);
+ board_list = NULL;
+ }
filename = gc_file_find_absolute("%s/board%d.xml",
- gcomprisBoard->boarddir,
+ gcomprisBoard_missing->boarddir,
level);
-
- g_assert(read_xml_file(filename)== TRUE);
+ missing_read_xml_file(filename, &board_list);
+ gcomprisBoard_missing->number_of_sublevel = g_list_length(board_list);
g_free(filename);
}
/* ==================================== */
static void
-add_xml_data(xmlDocPtr doc, xmlNodePtr xmlnode, GNode * child)
+add_xml_data(xmlDocPtr doc, xmlNodePtr xmlnode, GList **list)
{
Board * board = g_new0(Board,1);
guint text_index = 0;
@@ -582,6 +582,7 @@ add_xml_data(xmlDocPtr doc, xmlNodePtr xmlnode, GNode * child)
gc_dialog(_("Data file for this level is not properly formatted."),
gc_board_stop);
g_free(board);
+ *list = NULL;
return;
}
@@ -609,33 +610,21 @@ add_xml_data(xmlDocPtr doc, xmlNodePtr xmlnode, GNode * child)
/* Insert boards randomly in the list */
if(g_random_int_range(0, 2))
- board_list = g_list_append (board_list, board);
+ *list = g_list_append (*list, board);
else
- board_list = g_list_prepend (board_list, board);
-}
-
-/* ==================================== */
-static void
-parse_doc(xmlDocPtr doc)
-{
- xmlNodePtr node;
-
- for(node = doc->children->children; node != NULL; node = node->next) {
- if ( g_strcasecmp((gchar *)node->name, "Board") == 0 )
- add_xml_data(doc, node,NULL);
- }
-
+ *list = g_list_prepend (*list, board);
}
/* ==================================== */
/* read an xml file into our memory structures and update our view,
dump any old data we have in memory if we can load a new set */
-static gboolean
-read_xml_file(char *fname)
+gboolean missing_read_xml_file(char *fname, GList **list)
{
/* pointer to the new doc */
xmlDocPtr doc;
+ xmlNodePtr node;
+ *list = NULL;
g_return_val_if_fail(fname!=NULL,FALSE);
/* parse the new file and put the result into newdoc */
@@ -649,26 +638,28 @@ read_xml_file(char *fname)
!doc->children ||
/* if it doesn't have a name */
!doc->children->name ||
- /* if it isn't a ImageId node */
+ /* if it isn't a missing letter node */
g_strcasecmp((char *)doc->children->name,"missing_letter")!=0) {
xmlFreeDoc(doc);
return FALSE;
}
- parse_doc(doc);
+ for(node = doc->children->children; node != NULL; node = node->next) {
+ if ( g_strcasecmp((gchar *)node->name, "Board") == 0 )
+ add_xml_data(doc, node, list);
+ }
xmlFreeDoc(doc);
return TRUE;
}
/* ======================================= */
-static void
-destroy_board_list()
+void
+missing_destroy_board_list(GList *list)
{
Board *board;
-
- while(g_list_length(board_list)>0)
+ while(g_list_length(list)>0)
{
- board = g_list_nth_data(board_list, 0);
- board_list = g_list_remove (board_list, board);
+ board = g_list_nth_data(list, 0);
+ list = g_list_remove (list, board);
destroy_board(board);
}
}
@@ -715,14 +706,14 @@ static GcomprisConfCallback
conf_ok(GHashTable *table)
{
if (!table){
- if (gcomprisBoard)
+ if (gcomprisBoard_missing)
pause_board(FALSE);
return NULL;
}
g_hash_table_foreach(table, (GHFunc) save_table, NULL);
- if (gcomprisBoard){
+ if (gcomprisBoard_missing){
gc_locale_reset();
GHashTable *config;
@@ -737,9 +728,9 @@ conf_ok(GHashTable *table)
if (profile_conf)
g_hash_table_destroy(config);
- destroy_board_list();
+ missing_destroy_board_list(board_list);
- init_xml(gcomprisBoard->level);
+ init_xml(gcomprisBoard_missing->level);
missing_letter_next_level();
@@ -747,6 +738,7 @@ conf_ok(GHashTable *table)
board_conf = NULL;
profile_conf = NULL;
+ pause_board(FALSE);
return NULL;
}
@@ -758,7 +750,7 @@ config_start(GcomprisBoard *agcomprisBoard,
board_conf = agcomprisBoard;
profile_conf = aProfile;
- if (gcomprisBoard)
+ if (gcomprisBoard_missing)
pause_board(TRUE);
gchar *label = g_strdup_printf(_("<b>%s</b> configuration\n for profile <b>%s</b>"),
@@ -776,7 +768,7 @@ config_start(GcomprisBoard *agcomprisBoard,
gchar *locale = g_hash_table_lookup( config, "locale");
gc_board_config_combo_locales(bconf, locale);
-
+ config_missing_letter(bconf);
}
diff --git a/src/missing_letter-activity/missingletter.h b/src/missing_letter-activity/missingletter.h
new file mode 100644
index 0000000..c56d779
--- /dev/null
+++ b/src/missing_letter-activity/missingletter.h
@@ -0,0 +1,36 @@
+/* gcompris - missingletter.h
+ *
+ * Copyright (C) 2009 Bruno Coudoin
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _MISSINGLETTER_H_
+#define _MISSINGLETTER_H_
+
+extern GcomprisBoard *gcomprisBoard_missing;
+
+gboolean missing_read_xml_file(char *fname, GList**);
+void missing_destroy_board_list(GList *);
+
+#define MAX_PROPOSAL 6
+typedef struct _Board {
+ gchar *pixmapfile;
+ gchar *question;
+ gchar *answer;
+ gchar *text[MAX_PROPOSAL + 1];
+ guint solution;
+} Board;
+
+#endif
diff --git a/src/missing_letter-activity/missingletter_config.c b/src/missing_letter-activity/missingletter_config.c
new file mode 100644
index 0000000..6bfe3d9
--- /dev/null
+++ b/src/missing_letter-activity/missingletter_config.c
@@ -0,0 +1,592 @@
+#include "gcompris/gcompris.h"
+#include <string.h>
+
+#include "missingletter.h"
+
+
+typedef struct
+ {
+ GtkComboBox *combo_level;
+ GtkTreeView *view;
+
+ GtkFileChooserButton *pixmap;
+ GtkEntry *question, *answer, *choice;
+ gboolean changed;
+ } _config_missing;
+
+enum
+ {
+ QUESTION_COLUMN,
+ ANSWER_COLUMN,
+ CHOICE_COLUMN,
+ PIXMAP_COLUMN,
+ PIXBUF_COLUMN,
+ N_COLUMNS
+ };
+
+#define ICON_SIZE 32
+
+static void new_clicked(GtkButton *b, gpointer data)
+{
+ _config_missing *u = (_config_missing*)data;
+ GtkListStore *ls;
+ GtkTreeIter iter;
+
+ ls = GTK_LIST_STORE(gtk_tree_view_get_model(u->view));
+ gtk_list_store_append(ls, &iter);
+ gtk_list_store_set(ls, &iter,
+ QUESTION_COLUMN, "",
+ ANSWER_COLUMN, "",
+ CHOICE_COLUMN, "",
+ PIXMAP_COLUMN, "",
+ PIXBUF_COLUMN, NULL,
+ -1);
+ GtkTreeSelection* sel = gtk_tree_view_get_selection(u->view);
+ gtk_tree_selection_select_iter(sel , &iter);
+}
+
+static void delete_clicked(GtkButton *b, gpointer data)
+{
+ _config_missing *u = (_config_missing*)data;
+ GtkTreeSelection *selection = gtk_tree_view_get_selection(u->view);
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+
+ if (gtk_tree_selection_get_selected (selection, &model, &iter))
+ {
+ gtk_list_store_remove(GTK_LIST_STORE(model), &iter);
+ u->changed = TRUE;
+ }
+}
+
+static gboolean valid_entry(gchar *question, gchar *answer,
+ gchar *choice, gchar *pixmap)
+{
+ gboolean result=FALSE;
+ gchar **split;
+
+ if(choice && question && answer && pixmap &&
+ strlen(choice)==3 && strlen(question) && strlen(answer)
+ && strchr(question, '_'))
+ {
+ split = g_strsplit(question, "_", 2);
+ if(g_str_has_prefix(answer, split[0]) &&
+ g_str_has_suffix(answer, split[1]) &&
+ answer[strlen(split[0])] == choice[0])
+ result = TRUE;
+ g_strfreev(split);
+ }
+ return result;
+}
+
+static void apply_clicked(GtkButton *b, gpointer data)
+{
+ _config_missing *u = (_config_missing*)data;
+ const gchar *question, *answer, *choice;
+ gchar *pixmap, *pixfile;
+ GtkTreeSelection *selection = gtk_tree_view_get_selection(u->view);
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+
+ question = gtk_entry_get_text(u->question);
+ answer = gtk_entry_get_text(u->answer);
+ choice = gtk_entry_get_text(u->choice);
+ pixmap = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(u->pixmap));
+
+ if(valid_entry((gchar*)question, (gchar*) answer, (gchar*)choice, pixmap))
+ {
+ if (gtk_tree_selection_get_selected (selection, &model, &iter))
+ {
+ pixfile = gc_cache_import_pixmap(pixmap, "missingletter", 300, 300);
+ GdkPixbuf *pixbuf =
+ gdk_pixbuf_new_from_file_at_size(pixmap, ICON_SIZE,
+ ICON_SIZE, NULL);
+
+ gtk_list_store_set(GTK_LIST_STORE(model),&iter,
+ QUESTION_COLUMN, question,
+ ANSWER_COLUMN, answer,
+ CHOICE_COLUMN, choice,
+ PIXMAP_COLUMN, pixfile,
+ PIXBUF_COLUMN, pixbuf,
+ -1);
+ u->changed = TRUE;
+ g_free(pixfile);
+ g_object_unref(pixbuf);
+ }
+ }
+ g_free(pixmap);
+}
+
+static void up_clicked(GtkButton *b, gpointer data)
+{
+ _config_missing *u = (_config_missing*)data;
+ GtkTreeSelection *selection = gtk_tree_view_get_selection(u->view);
+ GtkTreeIter itera, iterb;
+ GtkTreeModel *model;
+ GtkTreePath *tpa, *tpb;
+ gchar *pa, *pb;
+
+ if (gtk_tree_selection_get_selected (selection, &model, &itera))
+ {
+ pa = gtk_tree_model_get_string_from_iter(model, &itera);
+ tpa = gtk_tree_path_new_from_string(pa);
+ tpb = gtk_tree_path_copy(tpa);
+ gtk_tree_path_prev(tpb);
+ pb = gtk_tree_path_to_string(tpb);
+ gtk_tree_model_get_iter_from_string(model, &iterb, pb);
+ gtk_list_store_swap(GTK_LIST_STORE(model), &itera, &iterb);
+ gtk_tree_path_free(tpa);
+ gtk_tree_path_free(tpb);
+ g_free(pa);
+ g_free(pb);
+ u->changed = TRUE;
+ }
+}
+
+static void down_clicked(GtkButton *b, gpointer data)
+{
+ _config_missing *u = (_config_missing*)data;
+ GtkTreeSelection *selection = gtk_tree_view_get_selection(u->view);
+ GtkTreeIter itera, iterb;
+ GtkTreeModel *model;
+ GtkTreePath *tpa, *tpb;
+ gchar *pa, *pb;
+
+ if (gtk_tree_selection_get_selected (selection, &model, &itera))
+ {
+ pa = gtk_tree_model_get_string_from_iter(model, &itera);
+ tpa = gtk_tree_path_new_from_string(pa);
+ tpb = gtk_tree_path_copy(tpa);
+ gtk_tree_path_next(tpb);
+ pb = gtk_tree_path_to_string(tpb);
+ if(gtk_tree_model_get_iter_from_string(model, &iterb, pb))
+ gtk_list_store_swap(GTK_LIST_STORE(model), &itera, &iterb);
+ gtk_tree_path_free(tpa);
+ gtk_tree_path_free(tpb);
+ g_free(pa);
+ g_free(pb);
+ u->changed = TRUE;
+ }
+}
+
+static gboolean _save(GtkTreeModel *model, GtkTreePath *path,
+ GtkTreeIter *iter, gpointer data)
+{
+ gchar *question, *answer, *choice, *pixmap;
+ gchar *tmp = NULL;
+ xmlNodePtr root, node;
+
+ gtk_tree_model_get (model, iter,
+ QUESTION_COLUMN, &question,
+ ANSWER_COLUMN, &answer,
+ CHOICE_COLUMN, &choice,
+ PIXMAP_COLUMN, &pixmap,
+ -1);
+ if(valid_entry(question, answer, choice, pixmap))
+ {
+ tmp = g_strdup_printf("%s/%s/%c/%c/%c",
+ answer, question,
+ choice[0], choice[1], choice[2]);
+
+ root =(xmlNodePtr)data;
+ node = xmlNewChild(root, NULL, BAD_CAST "Board", NULL);
+ xmlNewChild(node, NULL,BAD_CAST "pixmapfile", BAD_CAST pixmap);
+ xmlNewChild(node, NULL, BAD_CAST "data", BAD_CAST tmp);
+ }
+ g_free(tmp);
+ g_free(question);
+ g_free(answer);
+ g_free(choice);
+ return FALSE;
+}
+
+static void save_clicked(GtkButton *b, gpointer data)
+{
+ _config_missing *u = (_config_missing*)data;
+ GtkTreeModel *model;
+ gchar *filename;
+ xmlNodePtr root;
+ xmlDocPtr doc;
+ int level;
+
+ level = gtk_combo_box_get_active(u->combo_level)+1;
+ if(level==0)
+ return;
+ if(! u->changed)
+ return;
+ model = gtk_tree_view_get_model(u->view);
+ doc = xmlNewDoc(BAD_CAST XML_DEFAULT_VERSION);
+ root = xmlNewNode(NULL, BAD_CAST "missing_letter");
+ xmlDocSetRootElement(doc,root);
+
+ gtk_tree_model_foreach(model, _save, root);
+
+ filename =
+ gc_file_find_absolute_writeable("%s/board%d.xml",
+ gcomprisBoard_missing->boarddir, level);
+ if(xmlSaveFormatFileEnc(filename, doc, NULL, 1)<0)
+ g_warning("Fail to write %s", filename);
+ g_free(filename);
+ xmlFreeDoc(doc);
+ u->changed = FALSE;
+}
+
+static void level_changed(GtkComboBox *combo, gpointer data)
+{
+ _config_missing *u = (_config_missing*)data;
+ GtkListStore *ls;
+ GtkTreeIter iter;
+ gchar *filename;
+ GList *list=NULL, *l;
+ int level, result;
+
+ level = gtk_combo_box_get_active(u->combo_level)+1;
+ if(level==0)
+ return;
+ if(u->changed)
+ {
+ GtkWidget *dialog;
+
+ dialog = gtk_dialog_new_with_buttons("Save changes ?",
+ NULL,
+ GTK_DIALOG_MODAL,
+ GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
+ NULL);
+ result = gtk_dialog_run(GTK_DIALOG(dialog));
+ switch(result)
+ {
+ case GTK_RESPONSE_ACCEPT:
+ save_clicked(NULL, data);
+ break;
+ default:
+ u->changed=FALSE;
+ break;
+ }
+ gtk_widget_destroy (dialog);
+ }
+ ls = GTK_LIST_STORE(gtk_tree_view_get_model(u->view));
+ filename = gc_file_find_absolute("%s/board%d.xml",
+ gcomprisBoard_missing->boarddir, level);
+ missing_read_xml_file(filename,&list);
+ g_free(filename);
+ gtk_list_store_clear(ls);
+
+ for(l=list; l; l=l->next)
+ {
+ Board *b = l->data;
+ gchar *pixfile = gc_file_find_absolute(b->pixmapfile);
+ GdkPixbuf *pixbuf;
+ gchar tmp[MAX_PROPOSAL+1];
+ int i = 0;
+
+ pixbuf =
+ gdk_pixbuf_new_from_file_at_size(pixfile, ICON_SIZE, ICON_SIZE,
+ NULL);
+
+ while(b->text[i])
+ {
+ tmp[i] = b->text[i][0];
+ i++;
+ }
+ tmp[i] = '\0';
+
+ gtk_list_store_append(ls, &iter);
+ gtk_list_store_set(ls, &iter,
+ QUESTION_COLUMN, b->question,
+ ANSWER_COLUMN, b->answer,
+ CHOICE_COLUMN, tmp,
+ PIXMAP_COLUMN, b->pixmapfile,
+ PIXBUF_COLUMN, pixbuf,
+ -1);
+ g_free(pixfile);
+ g_object_unref(pixbuf);
+ }
+ missing_destroy_board_list(list);
+}
+
+static void text_changed(GtkWidget *widget, gpointer data)
+{
+ _config_missing *u = (_config_missing*)data;
+
+ const gchar *question, *answer, *choice;
+
+ question = gtk_entry_get_text(u->question);
+ answer = gtk_entry_get_text(u->answer);
+ choice = gtk_entry_get_text(u->choice);
+
+ if(widget == (GtkWidget*)u->answer)
+ {
+ if(g_str_has_prefix(answer,question))
+ {
+ gtk_entry_set_text(u->question,answer);
+ }
+ }
+ else if(widget ==(GtkWidget*) u->question)
+ {
+ if(strchr(question, '_'))
+ {
+ gchar ** split = g_strsplit(question,"_",2);
+ if(answer[strlen(split[0])]!= choice[0])
+ {
+ gchar *tmp;
+ tmp = g_new0(gchar, 4);
+ tmp[0]= answer[strlen(split[0])];
+ gtk_entry_set_text(u->choice, tmp);
+ g_free(tmp);
+ }
+ g_strfreev(split);
+ }
+ }
+}
+
+void selection_changed (GtkTreeSelection *selection,gpointer data)
+{
+ _config_missing *u = (_config_missing*)data;
+ gchar *question, *answer, *choice, *pixmap, *pixfile;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+
+ if (gtk_tree_selection_get_selected (selection, &model, &iter))
+ {
+ gtk_tree_model_get (model, &iter,
+ QUESTION_COLUMN, &question,
+ ANSWER_COLUMN, &answer,
+ CHOICE_COLUMN, &choice,
+ PIXMAP_COLUMN, &pixmap,
+ -1);
+ gtk_entry_set_text(u->question, question);
+ gtk_entry_set_text(u->answer, answer);
+ gtk_entry_set_text(u->choice, choice);
+ pixfile = gc_file_find_absolute(pixmap);
+ gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(u->pixmap), pixfile);
+
+ g_free(question);
+ g_free(answer);
+ g_free(choice);
+ g_free(pixmap);
+ g_free(pixfile);
+ }
+}
+
+void destroy_conf_data(void *not_used, gpointer *data)
+{
+ g_free(data);
+}
+
+static void configure_colummns(GtkTreeView *treeview)
+{
+ GtkCellRenderer *renderer;
+ GtkTreeViewColumn *column;
+
+ /* pixbuf column */
+ renderer = gtk_cell_renderer_pixbuf_new();
+ column = gtk_tree_view_column_new_with_attributes(_("Picture"),
+ renderer, "pixbuf", PIXBUF_COLUMN, NULL);
+ gtk_tree_view_append_column(treeview, column);
+
+ /* Answer column */
+ renderer = gtk_cell_renderer_text_new();
+ column = gtk_tree_view_column_new_with_attributes(_("Answer"),
+ renderer, "text", ANSWER_COLUMN, NULL);
+ gtk_tree_view_append_column(treeview, column);
+
+ /* Question column */
+ renderer = gtk_cell_renderer_text_new();
+ column = gtk_tree_view_column_new_with_attributes(_("Question"),
+ renderer, "text", QUESTION_COLUMN, NULL);
+ gtk_tree_view_append_column(treeview, column);
+
+ /* Choice column */
+ renderer = gtk_cell_renderer_text_new();
+ column = gtk_tree_view_column_new_with_attributes(_("Choice"),
+ renderer, "text", CHOICE_COLUMN, NULL);
+ gtk_tree_view_append_column(treeview, column);
+#if 0
+ /* pixmap column (debug only)*/
+ renderer = gtk_cell_renderer_text_new();
+ column = gtk_tree_view_column_new_with_attributes("File"),
+ renderer, "text", PIXMAP_COLUMN, NULL);
+ gtk_tree_view_append_column(treeview, column);
+#endif
+}
+
+ void config_missing_letter(GcomprisBoardConf *config)
+ {
+ GtkWidget *frame, *view, *pixmap, *question, *answer, *choice;
+ GtkWidget *level, *vbox, *hbox, *label;
+ GtkWidget *bbox, *button, *table;
+ GtkFileFilter *file_filter;
+ _config_missing *conf_data;
+ int i;
+
+ conf_data = g_new0(_config_missing,1);
+
+ /* frame */
+ frame = gtk_frame_new("");
+ gtk_widget_show(frame);
+ gtk_box_pack_start(GTK_BOX(config->main_conf_box), frame, TRUE, TRUE, 8);
+
+ vbox = gtk_vbox_new(FALSE, 8);
+ gtk_widget_show(vbox);
+ gtk_container_add(GTK_CONTAINER(frame), vbox);
+
+ /* hbox */
+ hbox = gtk_hbox_new(FALSE, 8);
+ gtk_widget_show(hbox);
+ gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 8);
+
+ /* combo level */
+ label = gtk_label_new(_("Level:"));
+ gtk_widget_show(label);
+ gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 8);
+
+ level = gtk_combo_box_new_text();
+ for(i=1; i< gcomprisBoard_missing->maxlevel; i++)
+ {
+ gchar *tmp;
+ tmp = g_strdup_printf(_("Level %d"), i);
+ gtk_combo_box_append_text(GTK_COMBO_BOX(level), tmp);
+ g_free(tmp);
+ }
+ gtk_widget_show(level);
+ gtk_box_pack_start(GTK_BOX(hbox), level, FALSE, FALSE, 8);
+
+ /* list view */
+ GtkListStore *list = gtk_list_store_new(N_COLUMNS,
+ G_TYPE_STRING, /*Question */
+ G_TYPE_STRING, /* Answer */
+ G_TYPE_STRING, /* Choice */
+ G_TYPE_STRING, /* pixmap */
+ GDK_TYPE_PIXBUF /* pixbuf */
+ );
+
+ view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(list));
+ configure_colummns(GTK_TREE_VIEW(view));
+ gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (view), TRUE);
+ gtk_tree_view_set_search_column (GTK_TREE_VIEW (view), ANSWER_COLUMN);
+ gtk_widget_set_size_request(view, -1, 200);
+ gtk_widget_show(view);
+
+ GtkScrolledWindow *scroll = GTK_SCROLLED_WINDOW(gtk_scrolled_window_new(NULL,NULL));
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
+ GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
+ gtk_widget_show(GTK_WIDGET(scroll));
+ gtk_container_add(GTK_CONTAINER(scroll), view);
+
+ gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(scroll), TRUE, TRUE, 10);
+
+ /* button box */
+ bbox = gtk_hbutton_box_new();
+ gtk_widget_show(bbox);
+ gtk_box_pack_start(GTK_BOX(vbox), bbox, FALSE, FALSE, 8);
+ button = gtk_button_new_from_stock(GTK_STOCK_NEW);
+ gtk_widget_show(button);
+ gtk_container_add(GTK_CONTAINER(bbox), button);
+ g_signal_connect(G_OBJECT(button), "clicked",
+ G_CALLBACK(new_clicked), (gpointer) conf_data);
+
+ button = gtk_button_new_from_stock(GTK_STOCK_DELETE);
+ gtk_widget_show(button);
+ gtk_container_add(GTK_CONTAINER(bbox), button);
+ g_signal_connect(G_OBJECT(button), "clicked",
+ G_CALLBACK(delete_clicked), (gpointer) conf_data);
+
+ button = gtk_button_new_from_stock(GTK_STOCK_APPLY);
+ gtk_widget_show(button);
+ gtk_container_add(GTK_CONTAINER(bbox), button);
+ g_signal_connect(G_OBJECT(button), "clicked",
+ G_CALLBACK(apply_clicked), (gpointer) conf_data);
+
+ button = gtk_button_new_from_stock(GTK_STOCK_GO_UP);
+ gtk_widget_show(button);
+ gtk_container_add(GTK_CONTAINER(bbox), button);
+ g_signal_connect(G_OBJECT(button), "clicked",
+ G_CALLBACK(up_clicked), (gpointer) conf_data);
+
+ button = gtk_button_new_from_stock(GTK_STOCK_GO_DOWN);
+ gtk_widget_show(button);
+ gtk_container_add(GTK_CONTAINER(bbox), button);
+ g_signal_connect(G_OBJECT(button), "clicked",
+ G_CALLBACK(down_clicked), (gpointer) conf_data);
+
+ button = gtk_button_new_from_stock(GTK_STOCK_SAVE);
+ gtk_widget_show(button);
+ gtk_container_add(GTK_CONTAINER(bbox), button);
+ g_signal_connect(G_OBJECT(button), "clicked",
+ G_CALLBACK(save_clicked), (gpointer) conf_data);
+
+ /* table */
+ table = gtk_table_new(2, 4, FALSE);
+ gtk_widget_show(table);
+ gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 8);
+
+ /* answer */
+ label = gtk_label_new(_("Answer"));
+ gtk_widget_show(label);
+ gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 0, 1);
+
+ answer = gtk_entry_new();
+ gtk_widget_show(answer);
+ gtk_table_attach_defaults(GTK_TABLE(table), answer, 1, 2, 0, 1);
+
+ /* pixmap */
+ label = gtk_label_new(_("Picture"));
+ gtk_widget_show(label);
+ gtk_table_attach_defaults(GTK_TABLE(table), label, 2, 3, 0, 1);
+
+ pixmap = gtk_file_chooser_button_new(_("Filename:"),
+ GTK_FILE_CHOOSER_ACTION_OPEN);
+
+ file_filter = gtk_file_filter_new();
+ gtk_file_filter_add_pixbuf_formats(file_filter);
+ gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(pixmap), file_filter);
+ gtk_widget_show(pixmap);
+ gtk_table_attach_defaults(GTK_TABLE(table), pixmap, 3, 4, 0, 1);
+
+ /* question */
+ label = gtk_label_new(_("Question"));
+ gtk_widget_show(label);
+ gtk_table_attach_defaults(GTK_TABLE(table), label, 0, 1, 1, 2);
+
+ question = gtk_entry_new();
+ gtk_widget_show(question);
+ gtk_table_attach_defaults(GTK_TABLE(table), question, 1, 2, 1, 2);
+
+ /* choice */
+ label = gtk_label_new(_("Choice"));
+ gtk_widget_show(label);
+ gtk_table_attach_defaults(GTK_TABLE(table), label, 2, 3, 1, 2);
+
+ choice = gtk_entry_new();
+ gtk_entry_set_max_length(GTK_ENTRY(choice), 3);
+ gtk_widget_show(choice);
+ gtk_table_attach_defaults(GTK_TABLE(table), choice, 3, 4, 1, 2);
+
+ conf_data -> combo_level = GTK_COMBO_BOX(level);
+ conf_data -> view = GTK_TREE_VIEW(view);
+ conf_data -> pixmap = GTK_FILE_CHOOSER_BUTTON(pixmap);
+ conf_data -> question = GTK_ENTRY(question);
+ conf_data -> answer = GTK_ENTRY(answer);
+ conf_data -> choice = GTK_ENTRY(choice);
+
+ GtkTreeSelection *selection;
+ selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
+ gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
+
+ g_signal_connect(G_OBJECT(selection),
+ "changed",
+ G_CALLBACK(selection_changed),
+ (gpointer) conf_data);
+ g_signal_connect(G_OBJECT(frame), "destroy",
+ G_CALLBACK(destroy_conf_data), (gpointer) conf_data);
+ g_signal_connect(G_OBJECT(level), "changed",
+ G_CALLBACK(level_changed), (gpointer) conf_data);
+ g_signal_connect(G_OBJECT(question), "changed",
+ G_CALLBACK(text_changed), (gpointer) conf_data);
+ g_signal_connect(G_OBJECT(answer), "changed",
+ G_CALLBACK(text_changed), (gpointer) conf_data);
+
+ gtk_combo_box_set_active(GTK_COMBO_BOX(level), 0);
+ }
+
diff --git a/src/readingh-activity/reading.c b/src/readingh-activity/reading.c
index ac4fafa..8e28a73 100644
--- a/src/readingh-activity/reading.c
+++ b/src/readingh-activity/reading.c
@@ -451,7 +451,15 @@ reading_create_item(GooCanvasItem *parent)
word = g_strdup(textToFind);
}
- g_assert(word!=NULL);
+ if(word==NULL)
+ {
+ gc_dialog(_("Skip this level. Not enough word in the list !"),
+ (DialogBoxCallBack)reading_next_level);
+ gcomprisBoard->level++;
+ if(gcomprisBoard->level>gcomprisBoard->maxlevel)
+ gcomprisBoard->level = gcomprisBoard->maxlevel;
+ return FALSE;
+ }
if(textToFindIndex>=0)
textToFindIndex--;
@@ -780,6 +788,7 @@ static gchar *
get_random_word(const gchar* except)
{
gchar *word;
+ int count=0;
word = gc_wordlist_random_word_get(gc_wordlist, gcomprisBoard->level);
@@ -787,6 +796,12 @@ get_random_word(const gchar* except)
while(strcmp(except, word)==0)
{
g_free(word);
+
+ if(count++>100)
+ {
+ word = NULL;
+ break;
+ }
word = gc_wordlist_random_word_get(gc_wordlist, gcomprisBoard->level);
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]