Commit 9ce88612 authored by Bruno Coudoin's avatar Bruno Coudoin Committed by Bruno Coudoin

- 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
parent 26bbbc54
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.
......
This diff is collapsed.
......@@ -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);
......
......@@ -627,8 +627,6 @@ gc_file_find_absolute(const gchar *format, ...)
g_free(filename2);
goto FOUND;
}
g_free(absolute_filename);
g_free(filename2);
}
......
......@@ -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
......
......@@ -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);
......
......@@ -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);
}
......
......@@ -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@
......
......@@ -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);
}
......
/* 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
#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)
{