[gcompris: 3/9] Sugar sharing and additional Journal integration (GC part)



commit d292f9e83c13064411326d802c7fad6063dc69c5
Author: Aleksey Lim <alsroot sugarlabs org>
Date:   Sat Mar 10 05:16:59 2012 +0000

    Sugar sharing and additional Journal integration (GC part)
    
    The following features will be activated if GC was built with Sugar support
    and sugar is detected in current runtime session:
    
    * toolbar buttons for Journal and sharing (with sugar-administration activity)
    * Journal save/restore for anim and wordprocessor activities
    * use boards configuration from connected sugar-administration activity

 po/POTFILES.in                             |    3 +
 src/anim-activity/anim.py                  |   28 +++++++++---
 src/boards/menu2.c                         |    2 +-
 src/boards/py-mod-gcompris.c               |   65 ++++++++++++++++++++++++++++
 src/gcompris/about.c                       |    4 ++
 src/gcompris/bar.c                         |    4 ++
 src/gcompris/config.c                      |    3 +
 src/gcompris/gameutil.c                    |    3 +
 src/gcompris/gcompris.c                    |   46 ++++++++++---------
 src/gcompris/gcompris.h                    |    2 +
 src/gcompris/gcompris_db.c                 |   33 ++++++++++++++
 src/gcompris/help.c                        |    3 +
 src/gcompris/images_selector.c             |    7 +++
 src/gcompris/log.c                         |   20 ++++++--
 src/gcompris/menu.c                        |   60 ++++++++++++++++++-------
 src/gcompris/profile.c                     |   15 ++++++
 src/gcompris/profile.h                     |    8 +++
 src/wordprocessor-activity/wordprocessor.c |   31 +++++++++++++-
 18 files changed, 285 insertions(+), 52 deletions(-)
---
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 25da07c..1c7baba 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -449,3 +449,6 @@ src/wordprocessor-activity/wordprocessor.c
 src/wordprocessor-activity/wordprocessor.xml.in
 src/wordsgame-activity/wordsgame.c
 src/wordsgame-activity/wordsgame.xml.in
+src/gcompris/sugar_cli.c
+src/gcompris/sugar_gc.c
+src/gcompris/sugar_srv.c
diff --git a/src/anim-activity/anim.py b/src/anim-activity/anim.py
index 773edf8..73ff571 100644
--- a/src/anim-activity/anim.py
+++ b/src/anim-activity/anim.py
@@ -259,9 +259,14 @@ class Gcompris_anim:
     self.draw_drawing_area()
     self.draw_playing_area()
 
-    gcompris.bar_set(0)
+    gcompris.bar_set(gcompris.BAR_JOURNAL)
     gcompris.bar_location(10, -1, 0.6)
 
+    if gcompris.sugar_detected():
+      journal_file = gcompris.sugar_load()
+      if journal_file:
+        fles.doc.file_to_anim(journal_file)
+
   def end(self):
     # stop the animation
     if self.running:
@@ -271,6 +276,13 @@ class Gcompris_anim:
       gobject.source_remove(self.timeout)
     self.timeout = 0
 
+    if gcompris.sugar_detected():
+      fd, tmp_file = tempfile.mkstemp(dir='/tmp')
+      os.close(fd)
+      os.chmod(tmp_file, 0644)
+      fles.doc.anim_to_file(tmp_file)
+      gcompris.sugar_save(tmp_file)
+
     # Remove the root item removes all the others inside it
     gcompris.set_cursor(gcompris.CURSOR_DEFAULT);
     self.rootitem.remove()
@@ -294,13 +306,13 @@ class Gcompris_anim:
     codec = sys.stdin.encoding
 
     # keyboard shortcuts
-    if ( (keyval == gtk.keysyms.F1)
-         or (keyval == gtk.keysyms.l) ):
+    if ( ((keyval == gtk.keysyms.F1)
+         or (keyval == gtk.keysyms.l)) and not gcompris.sugar_detected() ):
       gcompris.file_selector_save( self.gcomprisBoard,
                                    self.selector_section, self.file_type,
                                    general_save, self)
-    elif ( (keyval == gtk.keysyms.F2)
-           or (keyval == gtk.keysyms.s) ):
+    elif ( ((keyval == gtk.keysyms.F2)
+           or (keyval == gtk.keysyms.s)) and not gcompris.sugar_detected() ):
       gcompris.file_selector_load( self.gcomprisBoard,
                                    self.selector_section, self.file_type,
                                    general_restore, self)
@@ -354,9 +366,13 @@ class Gcompris_anim:
     x2 = 56.0
     y = 11.0
     stepy = 45
+    start_tool = 0
+
+    if gcompris.sugar_detected():
+        start_tool = 2
 
     # Display the tools
-    for i in range(0,len(self.tools)):
+    for i in range(start_tool,len(self.tools)):
 
       # Exclude the anim specific buttons
       if self.gcomprisBoard.mode == 'draw':
diff --git a/src/boards/menu2.c b/src/boards/menu2.c
index d19fb25..ed46b10 100644
--- a/src/boards/menu2.c
+++ b/src/boards/menu2.c
@@ -226,7 +226,7 @@ static void menu_start (GcomprisBoard *agcomprisBoard)
       gcomprisBoard->maxlevel=1;
 
       /* Set back the bar to it's original location */
-      gc_bar_set(GC_BAR_CONFIG|GC_BAR_ABOUT);
+      gc_bar_set(GC_BAR_CONFIG|GC_BAR_ABOUT|GC_BAR_JOURNAL|GC_BAR_SHARE);
 
       menuitems = g_new(MenuItems, 1);
 
diff --git a/src/boards/py-mod-gcompris.c b/src/boards/py-mod-gcompris.c
index a8eb32f..e2f6d47 100644
--- a/src/boards/py-mod-gcompris.c
+++ b/src/boards/py-mod-gcompris.c
@@ -42,6 +42,8 @@ typedef int Py_ssize_t;
 #include "py-mod-anim.h"
 #include "py-mod-admin.h"
 
+#include "gcompris/sugar_gc.h"
+
 void initgoocanvas (void);
 
 void pair_in_dict(gpointer key,
@@ -1598,6 +1600,63 @@ py_gc_im_reset (PyObject* self, PyObject* args)
   return Py_None;
 }
 
+static PyObject*
+py_sugar_detected (PyObject* self, PyObject* args)
+{
+  long result;
+  /* Parse arguments */
+  if(!PyArg_ParseTuple(args, ":gcompris.sugar_detected"))
+    return NULL;
+
+  /* Call the corresponding C function */
+  result = sugar_detected ();
+  return PyBool_FromLong(result);
+}
+
+static PyObject*
+py_sugar_load (PyObject* self, PyObject* args)
+{
+  const gchar *result;
+  /* Parse arguments */
+  if(!PyArg_ParseTuple(args, ":gcompris.sugar_load"))
+    return NULL;
+
+  /* Call the corresponding C function */
+  result = sugar_load ();
+  if (result != NULL)
+    return PyString_FromString(result);
+  else {
+    Py_INCREF(Py_None);
+    return Py_None;
+  }
+}
+
+static PyObject*
+py_sugar_save (PyObject* self, PyObject* args)
+{
+  gchar *filename;
+  /* Parse arguments */
+  if(!PyArg_ParseTuple(args, "s:gcompris.sugar_save", &filename))
+    return NULL;
+
+  /* Call the corresponding C function */
+  sugar_save (filename);
+  Py_INCREF(Py_None);
+  return Py_None;
+}
+
+static PyObject*
+py_sugar_get_profile_id (PyObject* self, PyObject* args)
+{
+  long result;
+  /* Parse arguments */
+  if(!PyArg_ParseTuple(args, ":gcompris.sugar_get_profile_id"))
+    return NULL;
+
+  /* Call the corresponding C function */
+  result = sugar_get_profile_id ();
+  return PyInt_FromLong(result);
+}
 
 
 /****************************************************/
@@ -1657,6 +1716,10 @@ static PyMethodDef PythonGcomprisModule[] = {
   { "get_wordlist",  py_gcompris_wordlist_get_from_file, METH_VARARGS, "gc_wordlist_get_from_file" },
   { "get_random_word",  py_gcompris_wordlist_get_random_word, METH_VARARGS, "gc_wordlist_random_word_get" },
   { "im_reset",  py_gc_im_reset, METH_VARARGS, "gc_im_reset" },
+  { "sugar_detected",  py_sugar_detected, METH_VARARGS, "sugar_detected" },
+  { "sugar_load",  py_sugar_load, METH_VARARGS, "sugar_load" },
+  { "sugar_save",  py_sugar_save, METH_VARARGS, "sugar_save" },
+  { "sugar_get_profile_id",  py_sugar_get_profile_id, METH_VARARGS, "sugar_get_profile_id" },
   { NULL, NULL, 0, NULL}
 };
 
@@ -1678,6 +1741,8 @@ void python_gcompris_module_init(void)
   PyModule_AddIntConstant(gcomprisModule, "BAR_REPEAT_ICON", GC_BAR_REPEAT_ICON);
   PyModule_AddIntConstant(gcomprisModule, "BAR_CONFIG",      GC_BAR_CONFIG);
   PyModule_AddIntConstant(gcomprisModule, "BAR_ABOUT",       GC_BAR_ABOUT);
+  PyModule_AddIntConstant(gcomprisModule, "BAR_JOURNAL",     GC_BAR_JOURNAL);
+  PyModule_AddIntConstant(gcomprisModule, "BAR_SHARE",       GC_BAR_SHARE);
 
   /* Colors constants */
   PyModule_AddIntConstant(gcomprisModule, "COLOR_TITLE",       COLOR_TITLE);
diff --git a/src/gcompris/about.c b/src/gcompris/about.c
index f938900..af217d9 100644
--- a/src/gcompris/about.c
+++ b/src/gcompris/about.c
@@ -33,6 +33,7 @@ static gboolean item_event_ok (GooCanvasItem  *item,
 			       GooCanvasItem  *target,
 			       GdkEventButton *event,
 			       gchar *data);
+void gc_about_stop (void);
 
 /*
  * Do all the bar display and register the events
@@ -59,7 +60,10 @@ void gc_about_start ()
   gc_board_pause(TRUE);
 
   if(rootitem)
+  {
+    gc_about_stop();
     return;
+  }
 
   gc_bar_hide (TRUE);
 
diff --git a/src/gcompris/bar.c b/src/gcompris/bar.c
index 85131dd..2121349 100644
--- a/src/gcompris/bar.c
+++ b/src/gcompris/bar.c
@@ -515,6 +515,10 @@ static gchar *bar_flags_to_name(GComprisBarFlags flag)
     case GC_BAR_HELP:
       result = "help";
       break;
+    case GC_BAR_JOURNAL:
+    case GC_BAR_SHARE:
+      g_error("GC_BAR_JOURNAL and GC_BAR_SHARE can't be used in goocanvas");
+      break;
     }
   return result;
 }
diff --git a/src/gcompris/config.c b/src/gcompris/config.c
index 48fd833..4b5867c 100644
--- a/src/gcompris/config.c
+++ b/src/gcompris/config.c
@@ -164,7 +164,10 @@ gc_config_start ()
   gc_board_pause(TRUE);
 
   if(rootitem)
+  {
+    gc_config_stop();
     return;
+  }
 
   gc_bar_hide(TRUE);
 
diff --git a/src/gcompris/gameutil.c b/src/gcompris/gameutil.c
index 7ecfb61..23e09cb 100644
--- a/src/gcompris/gameutil.c
+++ b/src/gcompris/gameutil.c
@@ -30,6 +30,7 @@
 #include <libxml/parserInternals.h>
 
 #include "gcompris.h"
+#include "sugar_gc.h"
 
 extern GooCanvas *canvas;
 
@@ -119,6 +120,8 @@ GdkPixbuf *gc_pixmap_load(const gchar *format, ...)
   pixmapfile = g_strdup_vprintf (format, args);
   va_end (args);
 
+  pixmapfile = sugar_get_journal_file(pixmapfile);
+
   /* Search */
   filename = gc_file_find_absolute(pixmapfile);
 
diff --git a/src/gcompris/gcompris.c b/src/gcompris/gcompris.c
index 6df719e..616769b 100644
--- a/src/gcompris/gcompris.c
+++ b/src/gcompris/gcompris.c
@@ -47,6 +47,7 @@
 #include "gcompris_config.h"
 #include "about.h"
 #include "bar.h"
+#include "sugar_gc.h"
 #include "status.h"
 #include <locale.h>
 
@@ -144,7 +145,6 @@ static gchar *popt_server          = NULL;
 static gint  *popt_web_only        = NULL;
 static gchar *popt_cache_dir       = NULL;
 static gchar *popt_drag_mode       = NULL;
-static gint popt_sugar_look        = FALSE;
 static gint popt_no_zoom           = FALSE;
 static gint popt_test              = FALSE;
 static gdouble popt_timing_base    = 1.0;
@@ -253,9 +253,6 @@ static GOptionEntry options[] = {
   {"nolockcheck", '\0', 0, G_OPTION_ARG_NONE, &popt_nolockcheck,
    N_("Do not avoid the execution of multiple instances of GCompris."), NULL},
 
-  {"sugar",'\0', 0, G_OPTION_ARG_NONE, &popt_sugar_look,
-   ("Use Sugar DE look&feel"), NULL},
-
   {"no-zoom",'\0', 0, G_OPTION_ARG_NONE, &popt_no_zoom,
    N_("Disable maximization zoom"), NULL},
 
@@ -1105,7 +1102,7 @@ void _set_geometry_hints(gboolean state)
   gint geom_mask = GDK_HINT_RESIZE_INC |
                    GDK_HINT_MIN_SIZE |
                    GDK_HINT_BASE_SIZE;
-  if (!popt_sugar_look)
+  if (!sugar_detected())
       geom_mask |= GDK_HINT_ASPECT;
   gtk_window_set_geometry_hints (GTK_WINDOW (window), NULL, &hints, geom_mask);
 }
@@ -1140,7 +1137,7 @@ void gc_fullscreen_set(gboolean state)
       gtk_window_set_decorated ( GTK_WINDOW ( window ), FALSE );
       gtk_window_set_type_hint ( GTK_WINDOW ( window ),
 				 GDK_WINDOW_TYPE_HINT_DESKTOP );
-      if (popt_sugar_look)
+      if (sugar_detected())
 	gtk_window_maximize ( GTK_WINDOW( window ) );
       else
         gtk_window_fullscreen ( GTK_WINDOW ( window ) );
@@ -1195,6 +1192,7 @@ static void cleanup()
   single_instance_release(); /* Must be done before property destroy */
   gc_board_stop();
   gc_db_exit();
+  sugar_cleanup();
   gc_fullscreen_set(FALSE);
   gc_menu_destroy();
   gc_net_destroy();
@@ -1254,18 +1252,22 @@ static void map_cb (GtkWidget *widget, gpointer data)
 
       gc_fullscreen_set(properties->fullscreen);
 
-      gc_status_init("");
+      gc_bar_start(GTK_CONTAINER(workspace), GOO_CANVAS(canvas));
 
       gc_board_init();
+
+      if (sugar_delayed_start())
+        gc_status_init(_("Retrieving remote data..."));
+      else
+      {
+      gc_status_init("");
       /* Load all the menu once */
       gc_menu_load();
       /* Save the root_menu */
       properties->menu_board = gc_menu_section_get(properties->root_menu);
-
-      gc_bar_start(GTK_CONTAINER(workspace), GOO_CANVAS(canvas));
-
       gc_status_close();
 
+
       board_to_start = get_board_to_start();
 
       if(!board_to_start) {
@@ -1283,6 +1285,8 @@ static void map_cb (GtkWidget *widget, gpointer data)
       }
 
     }
+  }
+
   g_message("gcompris window is now mapped");
 }
 
@@ -1627,6 +1631,7 @@ main (int argc, char *argv[])
   popt_difficulty_filter = -1;
 
   gtk_init (&argc, &argv);
+  sugar_setup(&argc, &argv);
 
   /* Argument parsing */
   context = g_option_context_new("GCompris");
@@ -1640,6 +1645,10 @@ main (int argc, char *argv[])
 		     | G_LOG_FLAG_RECURSION, gc_log_handler, NULL);
 
   /*------------------------------------------------------------*/
+
+  if (sugar_jobject_root_menu())
+    popt_root_menu = (gchar*)sugar_jobject_root_menu();
+
   if (popt_debug)
     {
       gc_debug = TRUE;
@@ -1919,7 +1928,8 @@ main (int argc, char *argv[])
     properties->music = FALSE;
     properties->fx = FALSE;
     g_message("Fullscreen and cursor is disabled");
-    properties->fullscreen = FALSE;
+    if (!sugar_detected())
+      properties->fullscreen = FALSE;
     properties->defaultcursor = GDK_LEFT_PTR;
   }
 
@@ -1984,6 +1994,8 @@ main (int argc, char *argv[])
     else
       gc_db_init(FALSE /* ENABLE DATABASE */);
 
+  sugar_setup_profile(popt_root_menu, popt_administration);
+
   /* An alternate profile is requested, check it does exists */
   if (popt_profile){
     properties->profile = gc_db_profile_from_name_get(popt_profile);
@@ -2015,17 +2027,6 @@ main (int argc, char *argv[])
     exit(0);
   }
 
-  if (popt_sugar_look){
-    #ifdef USE_SUGAR
-      extern Bar sugar_bar;
-      gc_bar_register(&sugar_bar);
-      extern Score sugar_score;
-      gc_score_register(&sugar_score);
-    #else
-	  printf("GCompris was not built with Sugar DE support.\n");
-      popt_sugar_look = FALSE;
-    #endif
-  }
 
   if (popt_no_zoom){
     g_message("Zoom disabled");
@@ -2055,6 +2056,7 @@ main (int argc, char *argv[])
 #endif
 
   setup_window ();
+  sugar_setup_x11();
 
   gtk_widget_show_all (window);
 
diff --git a/src/gcompris/gcompris.h b/src/gcompris/gcompris.h
index 736eb2a..2c0f30e 100644
--- a/src/gcompris/gcompris.h
+++ b/src/gcompris/gcompris.h
@@ -135,6 +135,8 @@ typedef enum
   GC_BAR_EXIT	   = 1 << 6,
   GC_BAR_LEVEL_DOWN = 1 << 7,
   GC_BAR_HELP      = 1 << 8,
+  GC_BAR_JOURNAL   = 1 << 9,
+  GC_BAR_SHARE     = 1 << 10,
 } GComprisBarFlags;
 
 /* Difficulty filtering */
diff --git a/src/gcompris/gcompris_db.c b/src/gcompris/gcompris_db.c
index 7fef100..393824f 100644
--- a/src/gcompris/gcompris_db.c
+++ b/src/gcompris/gcompris_db.c
@@ -1244,6 +1244,14 @@ GcomprisProfile *gc_db_get_profile()
 
 GList *gc_db_users_from_group_get(gint group_id)
 {
+  GcomprisProfile *profile = gc_profile_get_current();
+
+  if (profile && profile->groups)
+  {
+    GcomprisGroup *group = g_hash_table_lookup(profile->groups, GINT_TO_POINTER(group_id));
+    return group ? group->user_ids : NULL;
+  }
+
   SUPPORT_OR_RETURN(NULL);
 
 #ifdef USE_SQLITE
@@ -1535,9 +1543,24 @@ gc_db_set_board_conf(GcomprisProfile *profile,
 #define GET_CONF(p, b)							\
   "SELECT conf_key, conf_value FROM board_profile_conf WHERE profile_id=%d AND board_id=%d;", p, b
 
+static void merge_config(gchar *key, gchar *value, GHashTable *merge_to)
+{
+  g_hash_table_replace (merge_to, g_strdup(key), g_strdup(value));
+}
+
 GHashTable *gc_db_conf_with_table_get(int profile_id, int board_id,
 				      GHashTable *table )
 {
+  GcomprisProfile *profile = gc_profile_get_current();
+  if (profile && profile_id == profile->profile_id && profile->config)
+  {
+    GHashTable *config_table = g_hash_table_lookup(profile->config,
+            GINT_TO_POINTER(board_id));
+    if (config_table)
+      g_hash_table_foreach(config_table, (GHFunc)merge_config, table);
+    return table;
+  }
+
   GHashTable *hash_conf = table;
 
   SUPPORT_OR_RETURN(hash_conf);
@@ -1759,6 +1782,11 @@ GList *gc_db_profiles_list_get()
 
 GcomprisGroup *gc_db_get_group_from_id(int group_id)
 {
+  GcomprisProfile *profile = gc_profile_get_current();
+
+  if (profile && profile->groups)
+    return g_hash_table_lookup(profile->groups, GINT_TO_POINTER(group_id));
+
   SUPPORT_OR_RETURN(NULL);
 
 #ifdef USE_SQLITE
@@ -1814,6 +1842,11 @@ GcomprisGroup *gc_db_get_group_from_id(int group_id)
 
 GList *gc_db_get_groups_list()
 {
+  GcomprisProfile *profile = gc_profile_get_current();
+
+  if (profile && profile->groups)
+    return g_hash_table_get_values(profile->groups);
+
   SUPPORT_OR_RETURN(NULL);
 
 #ifdef USE_SQLITE
diff --git a/src/gcompris/help.c b/src/gcompris/help.c
index d33441c..cdb6f6e 100644
--- a/src/gcompris/help.c
+++ b/src/gcompris/help.c
@@ -100,7 +100,10 @@ void gc_help_start (GcomprisBoard *gcomprisBoard)
   gchar   *text_to_display = NULL;
 
   if(rootitem)
+  {
+    gc_help_stop();
     return;
+  }
 
   gc_board_pause(TRUE);
 
diff --git a/src/gcompris/images_selector.c b/src/gcompris/images_selector.c
index 890b935..600d969 100644
--- a/src/gcompris/images_selector.c
+++ b/src/gcompris/images_selector.c
@@ -29,6 +29,7 @@
 
 #include "gcompris.h"
 #include "gc_core.h"
+#include "sugar_gc.h"
 
 #define SOUNDLISTFILE PACKAGE
 
@@ -113,6 +114,12 @@ gc_selector_images_start (GcomprisBoard *gcomprisBoard, gchar *dataset,
 
   GtkWidget	*w;
 
+  if(sugar_detected())
+  {
+    sugar_choose_image(iscb, user_context);
+    return;
+  }
+
   if(rootitem)
     return;
 
diff --git a/src/gcompris/log.c b/src/gcompris/log.c
index a08aee1..5994246 100644
--- a/src/gcompris/log.c
+++ b/src/gcompris/log.c
@@ -33,6 +33,7 @@
 #include <gcompris.h>
 #include "gcompris_db.h"
 #include "profile.h"
+#include "sugar_gc.h"
 
 #define KEYLOG_MAX 256
 
@@ -103,7 +104,13 @@ void gc_log_end (GcomprisBoard *gcomprisBoard, GCBonusStatusList status) {
 
   struct tm *tp;
 
+  int user_id = -1;
+  const gchar *user_login = "";
   GcomprisUser *gcomprisUser = gc_profile_get_current_user();
+  if (gcomprisUser) {
+    user_id = gcomprisUser->user_id;
+    user_login = gcomprisUser->login;
+  }
 
   /* A board change in between doesn't make sense */
   if(gcomprisBoard_set != gcomprisBoard)
@@ -118,11 +125,14 @@ void gc_log_end (GcomprisBoard *gcomprisBoard, GCBonusStatusList status) {
   /* convert the time to a string according to the format specification in fmt */
   strftime(buf, sizeof(buf), fmt, tp);
 
-
-  gc_db_log(buf, (guint)duration,
-	    gcomprisUser->user_id, gcomprisBoard->board_id,
-	    gcomprisBoard->level, gcomprisBoard->sublevel,
-	    status, comment_set);
+  if (sugar_detected())
+    sugar_report(buf, (guint)duration, user_login, gcomprisBoard, status,
+            comment_set);
+  else
+    gc_db_log(buf, (guint)duration,
+          user_id, gcomprisBoard->board_id,
+          gcomprisBoard->level, gcomprisBoard->sublevel,
+          status, comment_set);
 
   g_free(comment_set);
 }
diff --git a/src/gcompris/menu.c b/src/gcompris/menu.c
index be393c1..bddeed5 100644
--- a/src/gcompris/menu.c
+++ b/src/gcompris/menu.c
@@ -28,6 +28,8 @@
 #include "gcompris.h"
 #include "status.h"
 
+static GcomprisBoard *gc_menu_load_board(const gchar*, const gchar*, gboolean);
+
 GcomprisBoard	*_read_xml_file(GcomprisBoard *gcomprisBoard, char *fname, gboolean db);
 
 /* List of all available boards  */
@@ -522,7 +524,6 @@ static gboolean compare_id(gconstpointer data1, gconstpointer data2)
 void gc_menu_load_dir(char *dirname, gboolean db){
   const gchar   *one_dirent;
   GDir          *dir;
-  GcomprisProperties	*properties = gc_prop_get();
   GList *list_old_boards_id = NULL;
 
   if (!g_file_test(dirname, G_FILE_TEST_IS_DIR)) {
@@ -539,8 +540,36 @@ void gc_menu_load_dir(char *dirname, gboolean db){
     if (db)
       list_old_boards_id = gc_db_get_board_id(list_old_boards_id);
 
+    int new_board_id = 1;
+
     while((one_dirent = g_dir_read_name(dir)) != NULL) {
       /* add the board to the list */
+      GcomprisBoard *board = gc_menu_load_board(dirname, one_dirent, db);
+      if (board) {
+        board->board_id = new_board_id++;
+	    list_old_boards_id = suppress_int_from_list(list_old_boards_id, board->board_id);
+      }
+    }
+  }
+
+  if (db){
+    /* remove suppressed boards from db */
+    while (list_old_boards_id != NULL){
+      int *data=list_old_boards_id->data;
+      gc_db_remove_board(*data);
+      list_old_boards_id=g_list_remove(list_old_boards_id, data);
+      g_free(data);
+    }
+  }
+
+  g_dir_close(dir);
+}
+
+static GcomprisBoard *gc_menu_load_board(const gchar *dirname,
+        const gchar *one_dirent, gboolean db)
+{
+      GcomprisProperties	*properties = gc_prop_get();
+      GcomprisBoard *board_read = NULL;
       GcomprisBoard *gcomprisBoard = NULL;
       gchar *filename;
 
@@ -549,7 +578,7 @@ void gc_menu_load_dir(char *dirname, gboolean db){
 
       if(!g_file_test(filename, G_FILE_TEST_IS_REGULAR)) {
 	g_free(filename);
-	continue;
+	return NULL;
       }
 
       if(file_end_with_xml(one_dirent)) {
@@ -561,9 +590,8 @@ void gc_menu_load_dir(char *dirname, gboolean db){
 	gcomprisBoard->plugin=NULL;
 	gcomprisBoard->previous_board=NULL;
 
-	GcomprisBoard *board_read = _read_xml_file(gcomprisBoard, filename, db);
+	board_read = _read_xml_file(gcomprisBoard, filename, db);
 	if (board_read) {
-	  list_old_boards_id = suppress_int_from_list(list_old_boards_id, board_read->board_id);
 	  if (properties->administration)
 	    boards_list = g_list_append(boards_list, board_read);
 	  else {
@@ -587,21 +615,16 @@ void gc_menu_load_dir(char *dirname, gboolean db){
         gc_menu_board_free(gcomprisBoard);
 	}
       g_free(filename);
-    }
-  }
-
-  if (db){
-    /* remove suppressed boards from db */
-    while (list_old_boards_id != NULL){
-      int *data=list_old_boards_id->data;
-      gc_db_remove_board(*data);
-      list_old_boards_id=g_list_remove(list_old_boards_id, data);
-      g_free(data);
-    }
 
-  }
+  return board_read;
+}
 
-  g_dir_close(dir);
+static void load_board(gpointer board_id, gchar *filename)
+{
+  GcomprisBoard *board = gc_menu_load_board(
+          gc_prop_get()->menu_dir, filename, FALSE);
+  if (board)
+    board->board_id = GPOINTER_TO_INT(board_id);
 }
 
 
@@ -618,6 +641,9 @@ void gc_menu_load()
       return;
     }
 
+  if (properties->profile && properties->profile->boards)
+    g_hash_table_foreach(properties->profile->boards, (GHFunc)load_board, NULL);
+  else
   if ((!properties->reread_menu) && gc_db_check_boards())
     {
       boards_list = gc_menu_load_db(boards_list);
diff --git a/src/gcompris/profile.c b/src/gcompris/profile.c
index 04d3e00..19c6ef5 100644
--- a/src/gcompris/profile.c
+++ b/src/gcompris/profile.c
@@ -101,6 +101,21 @@ void gc_user_destroy(GcomprisUser*user)
   g_free(user);
 }
 
+void gc_group_destroy(GcomprisGroup *group)
+{
+  if(!group)
+    return;
+
+  GList *i;
+  for (i = group->user_ids; i != NULL; i = i->next)
+    gc_user_destroy(i->data);
+  g_list_free(group->user_ids);
+  g_free(group->name);
+  g_free(group->description);
+  g_free(group->description);
+  g_free(group);
+}
+
 GcomprisUser*
 gc_profile_get_current_user()
 {
diff --git a/src/gcompris/profile.h b/src/gcompris/profile.h
index 1b69a97..ff6f9f7 100644
--- a/src/gcompris/profile.h
+++ b/src/gcompris/profile.h
@@ -130,6 +130,13 @@ typedef struct {
   /* list of activities to play -- gchar section/name */
   GList             *activities;
 
+  /* board_id:xml-filename list of boards bundled to sugar objects */
+  GHashTable        *boards;
+  /* group_id:GcomprisGroup list of user groups bundled to sugar objects */
+  GHashTable        *groups;
+  /* board_id:GHashTable board configs bundled to sugar objects */
+  GHashTable        *config;
+
 } GcomprisProfile;
 
 
@@ -137,6 +144,7 @@ typedef struct {
 GcomprisProfile     *gc_profile_get_current();
 void gc_profile_destroy(GcomprisProfile *prof);
 void gc_user_destroy(GcomprisUser *user);
+void gc_group_destroy(GcomprisGroup *group);
 
 /* List of Gcomprisusers */
 void                 gc_profile_set_current_user(GcomprisUser *user);
diff --git a/src/wordprocessor-activity/wordprocessor.c b/src/wordprocessor-activity/wordprocessor.c
index 71db76b..8e5d532 100644
--- a/src/wordprocessor-activity/wordprocessor.c
+++ b/src/wordprocessor-activity/wordprocessor.c
@@ -16,11 +16,13 @@
  *   along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
+#include <unistd.h>
 #include <string.h>
 #include <glib/gstdio.h>
 #include <libxml/HTMLparser.h>
 
 #include "gcompris/gcompris.h"
+#include "gcompris/sugar_gc.h"
 
 /*
  * Predefined styles
@@ -162,6 +164,8 @@ static gint		 get_color_style_current_index();
 static GtkTextTag       *get_tag_from_name(gchar *name);
 static void		 apply_style(int style_index);
 static void		 apply_color_style(int style_index);
+static void      load_buffer(gchar *file, gchar *file_type, void *unused);
+static void      save_buffer(gchar *file, gchar *file_type, void *unused);
 
 #define word_area_x1 120
 #define word_area_y1 20
@@ -252,13 +256,20 @@ static void start_board (GcomprisBoard *agcomprisBoard)
       gcomprisBoard->maxlevel=1;
       gcomprisBoard->sublevel=1;
       gcomprisBoard->number_of_sublevel=1; /* Go to next level after this number of 'play' */
-      gc_bar_set(0);
+      gc_bar_set(GC_BAR_JOURNAL);
       gc_bar_location(10, -1, 0.6);
 
       gc_set_default_background(goo_canvas_get_root_item(gcomprisBoard->canvas));
 
       wordprocessor_create();
 
+      if (sugar_detected())
+      {
+        const char *file_to_load = sugar_load();
+        if (file_to_load)
+          load_buffer((char*)file_to_load, NULL, NULL);
+      }
+
       pause_board(FALSE);
 
     }
@@ -269,6 +280,22 @@ static void end_board ()
   if(gcomprisBoard!=NULL)
     {
       pause_board(TRUE);
+
+      if (sugar_detected())
+      {
+        char tmp_file[] = "/tmp/GComprisXXXXXX";
+        int fd = mkstemp(tmp_file);
+        if (fd == -1)
+          g_warning("Cannot create temporary file to save");
+        else
+        {
+          fchmod(fd, 0644);
+          close(fd);
+          save_buffer(tmp_file, NULL, NULL);
+          sugar_save(tmp_file);
+        }
+      }
+
       wordprocessor_destroy_all_items();
     }
   gcomprisBoard = NULL;
@@ -354,6 +381,7 @@ static GooCanvasItem *wordprocessor_create()
   doctype_list[4] = &type_big;
 
   y = 20.0;
+  if (!sugar_detected()) {
   /*
    * The save button
    */
@@ -395,6 +423,7 @@ static GooCanvasItem *wordprocessor_create()
 
 
   y += 45;
+  }
   /*
    * Display the style buttons
    */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]