diff options
author | Bruno Coudoin <bcoudoin@src.gnome.org> | 2009-02-05 00:25:57 (GMT) |
---|---|---|
committer | Bruno Coudoin <bruno.coudoin@free.fr> | 2009-06-20 22:18:43 (GMT) |
commit | 26bbbc542bcfd43f6a753dfea6fbdd2a6c49b6ab (patch) | |
tree | b64faa223b8036aa788b004ff7608a29228890ed | |
parent | 1633c0f7d7fabe97e39eeb3baed7eb0c1c21f5b9 (diff) |
Miguel DE IZARRA added support for online wordlist.
This save custom data in user_dir and make a content.txt (a md5sum
like file) listing custom files. Simply put this files in a web server
to diffuse in classroom.
GCompris clients are launch with --server and --cache-dir
On start, client download content.txt from server.
And when a client need a file:
- first he search in server list (from content.txt)
- if found, he check md5 of file in cache_dir
- if md5 isn't ok, file is download in cache_dir
file in cache_dir is used
- if not found, search in package_dir (like now)
svn path=/trunk/; revision=3720
-rw-r--r-- | ChangeLog | 51 | ||||
-rw-r--r-- | configure.in | 15 | ||||
-rw-r--r-- | src/advanced_colors-activity/advanced_colors.c | 2 | ||||
-rw-r--r-- | src/babymatch-activity/shapegame.c | 2 | ||||
-rw-r--r-- | src/gcompris/board_config_wordlist.c | 28 | ||||
-rw-r--r-- | src/gcompris/dialog.c | 3 | ||||
-rw-r--r-- | src/gcompris/gameutil.c | 35 | ||||
-rw-r--r-- | src/gcompris/gameutil.h | 1 | ||||
-rw-r--r-- | src/gcompris/gc_net.c | 378 | ||||
-rw-r--r-- | src/gcompris/gc_net.h | 12 | ||||
-rw-r--r-- | src/gcompris/gcompris.c | 8 | ||||
-rw-r--r-- | src/gcompris/images_selector.c | 68 | ||||
-rw-r--r-- | src/gcompris/properties.h | 1 | ||||
-rw-r--r-- | src/gcompris/skin.c | 2 | ||||
-rw-r--r-- | src/gcompris/wordlist.c | 2 | ||||
-rw-r--r-- | src/imageid-activity/imageid.c | 2 | ||||
-rw-r--r-- | src/missing_letter-activity/missingletter.c | 2 | ||||
-rw-r--r-- | src/wordprocessor-activity/wordprocessor.c | 2 |
18 files changed, 576 insertions, 38 deletions
@@ -1,5 +1,54 @@ -2009-01-31 Bruno coudoin <bruno.coudoin@free.fr> +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 + like file) listing custom files. Simply put this files in a web server + to diffuse in classroom. + + GCompris clients are launch with --server and --cache-dir + On start, client download content.txt from server. + + And when a client need a file: + - first he search in server list (from content.txt) + - if found, he check md5 of file in cache_dir + - if md5 isn't ok, file is download in cache_dir + file in cache_dir is used + - if not found, search in package_dir (like now) + + * configure.in: + * src/boards/advanced_colors.c: (read_xml_file): + * src/boards/imageid.c: (read_xml_file): + * src/boards/missingletter.c: (read_xml_file): + * src/boards/python/admin/board_list.py: + * src/boards/read_colors.c: (read_xml_file): + * src/boards/shapegame.c: (read_xml_file): + * src/boards/superbrain.c: (mark_pieces): + * src/boards/wordprocessor.c: (load_buffer): + * src/gcompris/Makefile.am: + * src/gcompris/board_config_wordlist.c: (_return_clicked), + (gc_board_config_wordlist): + * src/gcompris/cache.c: + * src/gcompris/config.c: (set_locale_flag): + * src/gcompris/dialog.c: + * src/gcompris/gameutil.c: (gc_pixmap_load), + (gc_file_find_absolute), (gc_file_find_absolute_writeable): + * src/gcompris/gameutil.h: + * src/gcompris/gc_core.h: + * src/gcompris/gc_net.c: (load_md5file), (gc_net_init), + (gc_net_destroy), (gc_net_get_url_from_file), (gc_cache_init), + (gc_cache_get_relative), (gc_cache_add), (gc_cache_remove), + (_table_foreach), (gc_cache_save), (gc_cache_destroy): + * src/gcompris/gc_net.h: + * src/gcompris/gcompris.c: (setup_window), (cleanup), (main): + * src/gcompris/images_selector.c: (gc_selector_images_start), + (read_xml_file): + * src/gcompris/skin.c: (skin_xml_load): + * src/gcompris/wordlist.c: (gc_wordlist_save): +2009-06-20 Bruno coudoin <bruno.coudoin@free.fr> + + From trunk Vitali Perchonok is com gmail from vitali.pe Fixed crash bug when changing level while dragging an item (2 click drag mode) diff --git a/configure.in b/configure.in index 247c8d9..d64f83b 100644 --- a/configure.in +++ b/configure.in @@ -366,6 +366,20 @@ if test x$TETEX = xno; then fi +dnl GNET support +AC_MSG_CHECKING([wether we build with GNET (if not, networking will be disabled)]) +AC_ARG_ENABLE(gnet, + AC_HELP_STRING( + [--disable-gnet], + [Turn on gnet (will let GCompris fetch content from a web server)]), + with_gnet="$enableval", with_gnet="no") +AC_MSG_RESULT($with_gnet) + +if test x$with_gnet = xyes; then + PKG_CHECK_MODULES(GNET, gnet-2.0,, AC_MSG_ERROR([*** GNET not found!])) + AC_DEFINE([USE_GNET], 1,[Networking is enabled]) +fi + dnl SQLITE support AC_MSG_CHECKING([wether we build with SQLITE (if not profile will be disabled)]) AC_ARG_ENABLE(sqlite, @@ -830,6 +844,7 @@ echo "Python plugin = $build_python_plugin" echo "SQLITE database (--enable-sqlite) = $with_sqlite (profiles depend on this)" echo "DBUS Support (OLPC XO Sugar) = $with_dbus" +echo "GNET Networking (--enable-gnet) = $with_gnet (networking depends on this)" echo "BINRELOC (--enable-binreloc) = $br_cv_binreloc" echo "NSBundle (--enable-nsbundle) = $nsbundle" diff --git a/src/advanced_colors-activity/advanced_colors.c b/src/advanced_colors-activity/advanced_colors.c index f03b37f..97f4448 100644 --- a/src/advanced_colors-activity/advanced_colors.c +++ b/src/advanced_colors-activity/advanced_colors.c @@ -520,7 +520,7 @@ static gboolean read_xml_file(char *fname) g_return_val_if_fail(fname!=NULL,FALSE); /* parse the new file and put the result into newdoc */ - doc = gc_net_load_xml(fname); + doc = xmlParseFile(fname); /* in case something went wrong */ if(!doc) diff --git a/src/babymatch-activity/shapegame.c b/src/babymatch-activity/shapegame.c index bc7a4e7..5d60953 100644 --- a/src/babymatch-activity/shapegame.c +++ b/src/babymatch-activity/shapegame.c @@ -1720,7 +1720,7 @@ read_xml_file(char *fname) g_return_val_if_fail(fname!=NULL,FALSE); /* parse the new file and put the result into newdoc */ - doc = gc_net_load_xml(fname); + doc = xmlParseFile(fname); /* in case something went wrong */ if(!doc) return FALSE; diff --git a/src/gcompris/board_config_wordlist.c b/src/gcompris/board_config_wordlist.c index c0dd7c1..b0609ba 100644 --- a/src/gcompris/board_config_wordlist.c +++ b/src/gcompris/board_config_wordlist.c @@ -118,6 +118,22 @@ static void _textview_changed(GtkWidget *w, gpointer data) gtk_widget_set_sensitive(GTK_WIDGET(u->button), TRUE); } +static void _return_clicked(GtkWidget *w, gpointer data) +{ + int level; + user_param_type_wordlist *u = (user_param_type_wordlist*)data; + gchar *filename; + + filename = gc_file_find_absolute_writeable(u->wordlist->filename); + gc_cache_remove(filename); + g_free(filename); + + level = gtk_combo_box_get_active(u->combo_level)+1; + _combo_lang_changed(u->combo_lang, u); + gtk_combo_box_set_active(u->combo_level, level-1); + _combo_level_changed(u->combo_level, u); +} + static void _button_clicked(GtkWidget *w, gpointer data) { user_param_type_wordlist *u = (user_param_type_wordlist*)data; @@ -223,10 +239,18 @@ GtkWidget *gc_board_config_wordlist(GcomprisBoardConf *config, const gchar *file gtk_container_add (GTK_CONTAINER(scroll), textview); /* valid button */ + hbox = gtk_hbox_new(FALSE, 8); + 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")); + gtk_widget_show(b_default); + gtk_box_pack_start(GTK_BOX(hbox), b_default, FALSE, FALSE, 8); + button = gtk_button_new_from_stock(GTK_STOCK_APPLY); gtk_widget_show(button); gtk_widget_set_sensitive(button, FALSE); - gtk_box_pack_start(GTK_BOX(vbox), button, FALSE, FALSE, 8); + gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 8); /* user_data */ user_data = g_malloc0(sizeof(user_param_type_wordlist)); @@ -246,6 +270,8 @@ GtkWidget *gc_board_config_wordlist(GcomprisBoardConf *config, const gchar *file G_CALLBACK(_textview_changed), (gpointer)user_data); g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(_button_clicked), (gpointer)user_data); + g_signal_connect(G_OBJECT(b_default), "clicked", + G_CALLBACK(_return_clicked), (gpointer)user_data); _combo_lang_changed(GTK_COMBO_BOX(combo_lang), user_data); diff --git a/src/gcompris/dialog.c b/src/gcompris/dialog.c index db85b38..2a059e9 100644 --- a/src/gcompris/dialog.c +++ b/src/gcompris/dialog.c @@ -27,9 +27,6 @@ static gboolean item_event_ok (GooCanvasItem *item, GdkEventButton *event, DialogBoxCallBack dbcb); -typedef void (*sighandler_t)(int); - - /* * Close the dialog box if it was open. It not, do nothing. */ diff --git a/src/gcompris/gameutil.c b/src/gcompris/gameutil.c index bd155bd..465ce04 100644 --- a/src/gcompris/gameutil.c +++ b/src/gcompris/gameutil.c @@ -87,7 +87,7 @@ GdkPixbuf *gc_pixmap_load_or_null(const gchar *format, ...) filename = gc_file_find_absolute(pixmapfile); if(filename) - pixmap = gc_net_load_pixmap(filename); + pixmap = gdk_pixbuf_new_from_file(filename,NULL); g_free(pixmapfile); g_free(filename); @@ -582,6 +582,9 @@ gc_file_find_absolute(const gchar *format, ...) * Search it on the file system */ + if(properties->server) + dir_to_search[i++] = ""; + dir_to_search[i++] = properties->user_dir; dir_to_search[i++] = properties->package_data_dir; dir_to_search[i++] = properties->package_skin_dir; dir_to_search[i++] = NULL; @@ -624,6 +627,7 @@ gc_file_find_absolute(const gchar *format, ...) g_free(filename2); goto FOUND; } + g_free(absolute_filename); g_free(filename2); @@ -653,6 +657,35 @@ gc_file_find_absolute(const gchar *format, ...) return abs_name; } +gchar* +gc_file_find_absolute_writeable(const gchar *format, ...) +{ + gchar *filename, *absolute_filename, *dirname; + GcomprisProperties *prop; + va_list args; + + va_start (args, format); + filename = g_strdup_vprintf (format, args); + va_end (args); + + prop = gc_prop_get(); + absolute_filename = g_build_filename(prop->user_dir, filename,NULL); + g_free(filename); + dirname = g_path_get_dirname(absolute_filename); + if(!g_file_test(dirname, G_FILE_TEST_IS_DIR)) + { + if(g_mkdir_with_parents(dirname, 0755)) + { + g_free(absolute_filename); + absolute_filename=NULL; + } + } + g_free(dirname); + if(absolute_filename) + gc_cache_add(absolute_filename); + return absolute_filename; +} + /** Create a directory if needed. * * \param rootdir: the directory to create diff --git a/src/gcompris/gameutil.h b/src/gcompris/gameutil.h index ff9a640..d062c22 100644 --- a/src/gcompris/gameutil.h +++ b/src/gcompris/gameutil.h @@ -85,6 +85,7 @@ void gc_item_rotate_relative_with_center(GooCanvasItem *item, double angle, in /* find the complete filename looking for the file everywhere (printf formatting supported) */ gchar *gc_file_find_absolute(const gchar *filename, ...); +gchar *gc_file_find_absolute_writeable(const gchar *filename, ...); int gc_util_create_rootdir (gchar *rootdir); void gc_activity_intro_play (GcomprisBoard *gcomprisBoard); diff --git a/src/gcompris/gc_net.c b/src/gcompris/gc_net.c index 630a905..ecc7b73 100644 --- a/src/gcompris/gc_net.c +++ b/src/gcompris/gc_net.c @@ -1,4 +1,4 @@ -/* gcompris - gc_net.c +/* gcompris - gameutil_net.c * * Copyright (C) 2006 Bruno Coudoin * @@ -19,39 +19,373 @@ #include "gc_net.h" #include "gc_core.h" #include <string.h> +#ifdef USE_GNET +#include <gnet.h> +#endif +#include <glib/gstdio.h> -static gboolean -path_represents_svg_image (const char *path) +/* FIXME: Should not be needed, a bug in gnet header ? */ +gboolean gnet_http_get (const gchar *url, + gchar **buffer, + gsize *length, + guint *response); + +#ifdef USE_GNET +static GHashTable *server_content = NULL; +static GHashTable *cache_content=NULL; +#define SUPPORT_OR_RETURN(rv) {if(!gc_prop_get()->server) return rv;} +#else +#define SUPPORT_OR_RETURN(rv) { return rv; } +#endif + +#ifdef USE_GNET +static void load_md5file(GHashTable *ht, gchar *content) { - /* Synchronous mime sniffing is a really bad idea here - * since it's only useful for people adding custom icons, - * and if they're doing that, they can behave themselves - * and use a .svg extension. - */ - return path != NULL && (strstr (path, ".svg") != NULL || strstr (path, ".svgz") != NULL); + gchar **lines, **keyval; + int i; + + lines = g_strsplit(content, "\n", 0); + if(lines && lines[0]) + { + for(i=0; lines[i]; i++) + { + keyval = g_strsplit(lines[i], " ", 2); + if(keyval && keyval[0]) + { + g_hash_table_insert(ht, g_strdup(keyval[1]), g_strdup(keyval[0])); + } + g_strfreev(keyval); + } + } + g_strfreev(lines); } +#endif -/** Load a pixmap localy +/** Init the network library, must be called once before using it * - * \param pixmapfile : a full path to the file to load as an image - * \return a GdkPixbuf or NULL */ -GdkPixbuf *gc_net_load_pixmap(const char *file) +void gc_net_init() { - if (path_represents_svg_image (file)) - return(rsvg_pixbuf_from_file (file, NULL)); + SUPPORT_OR_RETURN(); + +#ifdef USE_GNET + GcomprisProperties *properties = gc_prop_get(); + gchar *url; + gchar *buf = NULL; + gsize buflen; + guint response; + + gnet_init(); + + /* + * Get the content.txt file at the root of the http server and store it in a glist + * we then now exactly which files we have there + * warning, do not use gc_net_get_url_from_file() since we are in fact buildind the list of file + * for it. + */ + url = g_strdup_printf("%s/%s", properties->server, "/content.txt"); + + if(gnet_http_get(url, &buf, &buflen, &response) && response == 200) + { + server_content = g_hash_table_new(g_str_hash, g_str_equal); + load_md5file(server_content, buf); + } else - return(gdk_pixbuf_new_from_file (file, NULL)); + { + /* We did not get the content list, disable network now */ + g_free(properties->server); + properties->server = NULL; + g_warning("Failed to initialize networked GCompris because '%s' is not found", url); + } + + g_free(buf); + g_free(url); +#endif +} + +void gc_net_destroy(void) +{ + SUPPORT_OR_RETURN(); + +#ifdef USE_GNET + if(server_content) + g_hash_table_destroy(server_content); + server_content = NULL; +#endif } -/** Load an xml file from the network +/** return an absolute URL if the given file is part of the file available on our server * - * \param xmlfile : a full URL to the xml file to load as an xmlDocPtr - * in case a local file is given, it will be loaded. - * \return a xmlDocPtr or NULL + * \param file: the file to check + * \return: a newly allocated URL or NULL */ -xmlDocPtr gc_net_load_xml(const char *url) +gchar * +gc_net_get_url_from_file(const gchar *format, ...) +{ + SUPPORT_OR_RETURN(NULL); + +#ifdef USE_GNET + GcomprisProperties *properties = gc_prop_get(); + gchar *file, *cache=NULL, *value; + va_list args; + gboolean cache_ok=FALSE; + + va_start (args, format); + file = g_strdup_vprintf (format, args); + va_end (args); + + g_warning("gc_net_get_url_from_file '%s'", file); + + value = g_hash_table_lookup(server_content, (gpointer) file); + if(value) + { + cache = g_strconcat(properties->cache_dir, "/", file, NULL); + if(g_file_test(cache, G_FILE_TEST_IS_REGULAR)) + { + gchar * content; + gsize length; + GMD5 *md5cache, *md5serv; + + /* calc md5 of cache file */ + g_file_get_contents(cache, &content, &length, NULL); + md5cache = gnet_md5_new(content, length); + g_free(content); + + md5serv = gnet_md5_new_string(value); + + cache_ok = gnet_md5_equal(md5serv, md5cache); + + gnet_md5_delete(md5serv); + gnet_md5_delete(md5cache); + } + if(cache_ok==0) + { + gchar *url; + gchar *buf = NULL; + gsize buflen; + guint response; + + url = g_strconcat(properties->server, "/", file, NULL); + if(gnet_http_get(url, &buf, &buflen, &response) && response == 200) + { + gchar *dirname; + + dirname = g_path_get_dirname(cache); + g_mkdir_with_parents(dirname, 0755); + g_free(dirname); + g_file_set_contents(cache, buf, buflen, NULL); + g_free(buf); + } + else + { /* file is in content.txt but not in server */ + g_free(cache); + cache = NULL; + } + } + } + g_free(file); + + return cache; +#endif + } + +#if 0 +/** return a glist with the content of the files in the given directory + * + * \param dir: the directory to scan + * \param ext: optional extention filter. e.g. ".xml" to get only *.xml files. + * + * \return: a new allocated glist that points to internal elements. Do not free the list + * data itself. + */ +GSList *gc_net_dir_read_name(const gchar* dir, const gchar *ext) +{ + SUPPORT_OR_RETURN(NULL); + +#ifdef USE_GNET + GSList *filelist = NULL; + GSList *i = NULL; + + g_return_val_if_fail(dir!=NULL, NULL); + + for (i = server_content_list; i != NULL; i = g_slist_next (i)) + { + if(strncmp(dir, (gchar *)i->data, strlen(dir)) == 0) + if(ext == NULL || + g_str_has_suffix ((gchar *)i->data, ext)) + filelist = g_slist_prepend(filelist, i->data); + } + + return(filelist); +#endif + } +#endif + + +#define CONTENT_FILENAME "content.txt" + +void gc_cache_init(void) +{ +#ifdef USE_GNET + gchar *filename; + gchar *buf; + gsize buflen; + + cache_content = g_hash_table_new(g_str_hash, g_str_equal); + filename = gc_file_find_absolute_writeable(CONTENT_FILENAME); + + if(g_file_get_contents(filename, &buf, &buflen,NULL)) + { + load_md5file(cache_content, buf); + g_free(buf); + } + g_free(filename); +#endif +} + +#ifdef USE_GNET +static gchar *gc_cache_get_relative(gchar *filename) +{ + gchar *filename_content, *dirname; + + filename_content = gc_file_find_absolute_writeable(CONTENT_FILENAME); + dirname = g_path_get_dirname(filename_content); + if(g_str_has_prefix(filename, dirname)) + filename = filename + strlen(dirname) + 1; + g_free(filename_content); + g_free(dirname); + return filename; +} +#endif + +void gc_cache_add(gchar *filename) +{ +#ifdef USE_GNET + if(cache_content==NULL) + return; + if(g_str_has_suffix(filename, CONTENT_FILENAME)) + return; + + filename = gc_cache_get_relative(filename); + g_hash_table_insert(cache_content, g_strdup(filename), g_strdup("0")); +#endif +} + +gchar* gc_cache_import_pixmap(gchar *filename, gchar *boarddir, gint width, gint height) +{ +#ifdef USE_GNET + GdkPixbuf *pixmap; + gchar *basename, *file, *ext, *name, *abs; + + if(!g_path_is_absolute(filename)) + return g_strdup(filename); + basename = g_path_get_basename(filename); + name = g_build_filename(boarddir, basename,NULL); + abs = gc_file_find_absolute(name); + if(abs && strcmp(abs,filename)==0) + { + g_free(basename); + g_free(abs); + return name; + } + pixmap = gdk_pixbuf_new_from_file_at_size(filename, width, height,NULL); + if(!pixmap) + { + g_free(abs); + g_free(basename); + g_free(name); + return NULL; + } + + file = gc_file_find_absolute_writeable(name); + ext = strchr(basename, '.')+1; + if(strcmp(ext, "jpg")==0) + ext ="jpeg"; + + gdk_pixbuf_save(pixmap, file, ext, NULL,NULL); + + g_free(abs); + g_free(basename); + g_free(file); + return name; +#else + return NULL; +#endif +} + +void gc_cache_remove(gchar *filename) +{ +#ifdef USE_GNET + g_remove(filename); + filename = gc_cache_get_relative(filename); + g_hash_table_remove(cache_content, filename); +#endif +} + +struct _table_data + { + FILE *pf; + gchar *path; + }; + +#ifdef USE_GNET +static void _table_foreach(gpointer key, gpointer value, gpointer user_data) +{ + struct _table_data *data = (struct _table_data*)user_data; + gchar * content, *filename; + gsize length; + GMD5 *md5; + + if(strcmp(value, "0")==0) + { + filename = g_build_filename(data->path, (gchar*)key, NULL); + if(g_file_get_contents(filename, &content, &length, NULL)) + { + md5 = gnet_md5_new(content, length); + value = gnet_md5_get_string(md5); + gnet_md5_delete(md5); + g_free(content); + } + g_free(filename); + } + if(strcmp(value, "0")) + { + fprintf(data->pf, "%s %s\n", (gchar*)value, (gchar*)key); + } +} +#endif + +void gc_cache_save(void) +{ +#ifdef USE_GNET + struct _table_data data; + FILE *pf; + gchar *filename; + + filename = gc_file_find_absolute_writeable(CONTENT_FILENAME); + pf = fopen(filename, "w"); + if(!pf) + { + g_warning("Couldn't save %s\n", filename); + return; + } + + data.pf = pf; + data.path = g_path_get_dirname(filename); + g_hash_table_foreach(cache_content, _table_foreach, &data); + + g_free(filename); + g_free(data.path); + fclose(pf); +#endif +} + +void gc_cache_destroy(void) { - return(xmlParseFile(url)); +#ifdef USE_GNET + gc_cache_save(); + g_hash_table_destroy(cache_content); + cache_content = NULL; +#endif } diff --git a/src/gcompris/gc_net.h b/src/gcompris/gc_net.h index 598b6d8..c377748 100644 --- a/src/gcompris/gc_net.h +++ b/src/gcompris/gc_net.h @@ -31,7 +31,15 @@ #include "gcompris.h" -GdkPixbuf *gc_net_load_pixmap(const char *url); -xmlDocPtr gc_net_load_xml(const char *url); +void gc_net_init(); +gchar *gc_net_get_url_from_file(const gchar *format, ...); +GSList *gc_net_dir_read_name(const gchar* dir, const gchar *ext); +void gc_net_destroy(); + +void gc_cache_init(void); +void gc_cache_add(gchar *filename); +void gc_cache_remove(gchar *filename); +void gc_cache_save(void); +void gc_cache_destroy(void); #endif diff --git a/src/gcompris/gcompris.c b/src/gcompris/gcompris.c index 72ede83..efbe124 100644 --- a/src/gcompris/gcompris.c +++ b/src/gcompris/gcompris.c @@ -730,7 +730,7 @@ static void setup_window () NULL); if(iconfile) { - icon_pixbuf = gc_pixmap_load(iconfile); + icon_pixbuf = gdk_pixbuf_new_from_file(iconfile, NULL); g_free(iconfile); if (icon_pixbuf) @@ -1060,6 +1060,8 @@ static void cleanup() gc_db_exit(); gc_fullscreen_set(FALSE); gc_menu_destroy(); + gc_net_destroy(); + gc_cache_destroy(); gc_prop_destroy(gc_prop_get()); } @@ -1718,6 +1720,10 @@ main (int argc, char *argv[]) single_instance_check(); + /* networking init */ + gc_net_init(); + gc_cache_init(); + gc_skin_load(properties->skin); if(properties->music || properties->fx) diff --git a/src/gcompris/images_selector.c b/src/gcompris/images_selector.c index 4926bc3..7516b53 100644 --- a/src/gcompris/images_selector.c +++ b/src/gcompris/images_selector.c @@ -41,6 +41,7 @@ static gint item_event_imageset_selector(GooCanvasItem *item, gpointer data); static void item_event_scroll(GtkAdjustment *adj, GooCanvas *canvas); +static gboolean read_xml_file(gchar *fname); static gboolean read_dataset_directory(gchar *dataset_dir); static void display_image(gchar *imagename, GooCanvasItem *rootitem); static void free_stuff (GSList *data); @@ -262,6 +263,34 @@ gc_selector_images_start (GcomprisBoard *gcomprisBoard, gchar *dataset, read_dataset_directory(dataseturl); } + else if(dataseturl) + { + /* Read the given data set file, local or net */ + read_xml_file(dataseturl); + } + else + { + /* Network code for dataset directory */ + GSList *filelist = NULL; + GSList *i = NULL; + + g_free(dataseturl); + dataseturl = g_strconcat("boards/", dataset, NULL); + /* TODO */ + filelist = NULL; //gc_net_dir_read_name(dataseturl, ".xml"); + + for (i = filelist; i != NULL; i = g_slist_next (i)) + { + gchar *url = gc_file_find_absolute(i->data, + NULL); + g_warning("processing dataset=%s\n", (char *)i->data); + read_xml_file(url); + g_free(url); + } + + g_slist_free(filelist); + + } g_free(dataseturl); /* @@ -721,6 +750,45 @@ parse_doc(xmlDocPtr doc) { } +/* 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 + * + * \param fname is an absolute file name + * + */ +static gboolean +read_xml_file(gchar *fname) +{ + /* pointer to the new doc */ + xmlDocPtr doc; + + g_return_val_if_fail(fname!=NULL, FALSE); + + 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 the good node */ + g_strcasecmp((gchar *)doc->children->name, "ImageSetRoot")!=0) { + xmlFreeDoc(doc); + return FALSE; + } + + /* parse our document and replace old data */ + parse_doc(doc); + + xmlFreeDoc(doc); + + return TRUE; +} + + /** 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 * diff --git a/src/gcompris/properties.h b/src/gcompris/properties.h index 46c723b..1eb995c 100644 --- a/src/gcompris/properties.h +++ b/src/gcompris/properties.h @@ -63,6 +63,7 @@ typedef struct { GtkIMContext *context; gchar *default_context; gint experimental; + gchar *server; gint drag_mode; } GcomprisProperties; diff --git a/src/gcompris/skin.c b/src/gcompris/skin.c index ba4154d..276e724 100644 --- a/src/gcompris/skin.c +++ b/src/gcompris/skin.c @@ -308,7 +308,7 @@ skin_xml_load (gchar* skin) return; } - xmldoc = gc_net_load_xml(xmlfilename); + xmldoc = xmlParseFile(xmlfilename); g_free(xmlfilename); if(!xmldoc) diff --git a/src/gcompris/wordlist.c b/src/gcompris/wordlist.c index b8410c3..8c56080 100644 --- a/src/gcompris/wordlist.c +++ b/src/gcompris/wordlist.c @@ -384,7 +384,7 @@ void gc_wordlist_save(GcomprisWordlist *wordlist) } } - filename = gc_file_find_absolute(wordlist->filename); + filename = gc_file_find_absolute_writeable(wordlist->filename); if(filename) { if(xmlSaveFormatFileEnc(filename, doc, NULL, 1)<0) diff --git a/src/imageid-activity/imageid.c b/src/imageid-activity/imageid.c index 978a646..7f13402 100644 --- a/src/imageid-activity/imageid.c +++ b/src/imageid-activity/imageid.c @@ -590,7 +590,7 @@ read_xml_file(char *fname) g_return_val_if_fail(fname!=NULL, FALSE); /* parse the new file and put the result into newdoc */ - doc = gc_net_load_xml(fname); + doc = xmlParseFile(fname); /* in case something went wrong */ if(!doc) diff --git a/src/missing_letter-activity/missingletter.c b/src/missing_letter-activity/missingletter.c index 1b14640..80a3f79 100644 --- a/src/missing_letter-activity/missingletter.c +++ b/src/missing_letter-activity/missingletter.c @@ -639,7 +639,7 @@ read_xml_file(char *fname) g_return_val_if_fail(fname!=NULL,FALSE); /* parse the new file and put the result into newdoc */ - doc = gc_net_load_xml(fname); + doc = xmlParseFile(fname); /* in case something went wrong */ if(!doc) diff --git a/src/wordprocessor-activity/wordprocessor.c b/src/wordprocessor-activity/wordprocessor.c index 2f8dbae..172e858 100644 --- a/src/wordprocessor-activity/wordprocessor.c +++ b/src/wordprocessor-activity/wordprocessor.c @@ -1012,7 +1012,7 @@ load_buffer(gchar *file, gchar *file_type) GtkTextIter iter_start, iter_end; /* parse the new file and put the result into newdoc */ - doc = gc_net_load_xml(file); + doc = xmlParseFile(file); /* in case something went wrong */ if(!doc) |