Back to index

gcompris  8.2.2
images_selector.c
Go to the documentation of this file.
00001 /* gcompris - images_selector.c
00002  *
00003  * Time-stamp: <2006/08/21 23:26:43 bruno>
00004  *
00005  * Copyright (C) 2000 Bruno Coudoin
00006  *
00007  *   This program is free software; you can redistribute it and/or modify
00008  *   it under the terms of the GNU General Public License as published by
00009  *   the Free Software Foundation; either version 2 of the License, or
00010  *   (at your option) any later version.
00011  *
00012  *   This program is distributed in the hope that it will be useful,
00013  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  *   GNU General Public License for more details.
00016  *
00017  *   You should have received a copy of the GNU General Public License
00018  *   along with this program; if not, write to the Free Software
00019  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020  */
00021 
00027 #include "string.h"
00028 
00029 /* libxml includes */
00030 #include <libxml/tree.h>
00031 #include <libxml/parser.h>
00032 
00033 #include "gcompris.h"
00034 
00035 #define SOUNDLISTFILE PACKAGE
00036 
00037 static gint           item_event_images_selector(GnomeCanvasItem *item,
00038                                               GdkEvent *event,
00039                                               gpointer data);
00040 static gint           item_event_imageset_selector(GnomeCanvasItem *item,
00041                                                 GdkEvent *event,
00042                                                 gpointer data);
00043 static gint           item_event_scroll(GnomeCanvasItem *item,
00044                                       GdkEvent *event,
00045                                       GnomeCanvas *canvas);
00046 static gboolean              read_xml_file(gchar *fname);
00047 static gboolean              read_dataset_directory(gchar *dataset_dir);
00048 static void           display_image(gchar *imagename, GnomeCanvasItem *rootitem);
00049 static void           free_stuff (GtkObject *obj, GSList *data);
00050 
00051 static gboolean              images_selector_displayed = FALSE;
00052 
00053 static GnomeCanvasItem      *rootitem = NULL;
00054 static GnomeCanvasItem      *current_root_set = NULL;
00055 
00056 static GnomeCanvas   *canvas_list_selector; /* The scrolled left part */
00057 static GnomeCanvasItem  *list_bg_item;
00058 
00059 static GnomeCanvas   *canvas_image_selector; /* The scrolled right part */
00060 static GnomeCanvasItem  *image_bg_item;
00061 
00062 static ImageSelectorCallBack imageSelectorCallBack = NULL;
00063 
00064 static gboolean              display_in_progress;
00065 
00066 /* Represent the limits of the image area */
00067 #define       DRAWING_AREA_X1      111.0
00068 #define DRAWING_AREA_Y1     14.0
00069 #define DRAWING_AREA_X2     774.0
00070 #define DRAWING_AREA_Y2     500.0
00071 
00072 /* Represent the limits of list area */
00073 #define       LIST_AREA_X1  18.0
00074 #define       LIST_AREA_Y1  16.0
00075 #define       LIST_AREA_X2  80.0
00076 #define       LIST_AREA_Y2  500.0
00077 #define VERTICAL_NUMBER_OF_LIST_IMAGE     6
00078 
00079 #define HORIZONTAL_NUMBER_OF_IMAGE 8
00080 #define VERTICAL_NUMBER_OF_IMAGE   4
00081 #define IMAGE_GAP                  10
00082 
00083 #define IMAGE_WIDTH  (DRAWING_AREA_X2-DRAWING_AREA_X1)/HORIZONTAL_NUMBER_OF_IMAGE-IMAGE_GAP
00084 #define IMAGE_HEIGHT (DRAWING_AREA_Y2-DRAWING_AREA_Y1)/VERTICAL_NUMBER_OF_IMAGE-IMAGE_GAP
00085 
00086 #define LIST_IMAGE_WIDTH  LIST_AREA_X2-LIST_AREA_X1-IMAGE_GAP
00087 #define LIST_IMAGE_HEIGHT (LIST_AREA_Y2-LIST_AREA_Y1)/VERTICAL_NUMBER_OF_LIST_IMAGE-IMAGE_GAP
00088 
00089 static guint          ix;
00090 static guint          iy;
00091 static guint          isy;
00092 
00093 /*
00094  * Main entry point
00095  * ----------------
00096  *
00097  */
00098 
00099 /*
00100  * Do all the images_selector display and register the events
00101  */
00102 
00103 void
00104 gc_selector_images_start (GcomprisBoard *gcomprisBoard, gchar *dataset,
00105                             ImageSelectorCallBack iscb)
00106 {
00107 
00108   GnomeCanvasItem *item, *item2;
00109   GdkPixbuf   *pixmap = NULL;
00110   gint         y = 0;
00111   gint         y_start = 0;
00112   gint         x_start = 0;
00113   gchar              *dataseturl = NULL;
00114 
00115   GtkWidget     *w;
00116 
00117   if(rootitem)
00118     return;
00119 
00120   gc_bar_hide(TRUE);
00121 
00122   gc_board_pause(TRUE);
00123 
00124   imageSelectorCallBack=iscb;
00125 
00126   rootitem = \
00127     gnome_canvas_item_new (gnome_canvas_root(gc_get_canvas()),
00128                         gnome_canvas_group_get_type (),
00129                         "x", (double)0,
00130                         "y", (double)0,
00131                         NULL);
00132 
00133   images_selector_displayed = TRUE;
00134 
00135   pixmap = gc_skin_pixmap_load("images_selector_bg.png");
00136   y_start = (BOARDHEIGHT - gdk_pixbuf_get_height(pixmap))/2;
00137   x_start = (BOARDWIDTH - gdk_pixbuf_get_width(pixmap))/2;
00138   item = gnome_canvas_item_new (GNOME_CANVAS_GROUP(rootitem),
00139                             gnome_canvas_pixbuf_get_type (),
00140                             "pixbuf", pixmap,
00141                             "x", (double) x_start,
00142                             "y", (double) y_start,
00143                             NULL);
00144   y = BOARDHEIGHT - (BOARDHEIGHT - gdk_pixbuf_get_height(pixmap))/2;
00145   gdk_pixbuf_unref(pixmap);
00146 
00147   y_start += 110;
00148 
00149   pixmap = gc_skin_pixmap_load("button_large.png");
00150 
00151   /*
00152    * Create the list scrollbar
00153    * -------------------------
00154    */
00155   canvas_list_selector     = GNOME_CANVAS(gnome_canvas_new ());
00156 
00157   gnome_canvas_item_new (GNOME_CANVAS_GROUP(rootitem),
00158                       gnome_canvas_widget_get_type (),
00159                       "widget", GTK_WIDGET(canvas_list_selector),
00160                       "x", (double) LIST_AREA_X1,
00161                       "y", (double) LIST_AREA_Y1,
00162                       "width",  LIST_AREA_X2 - LIST_AREA_X1,
00163                       "height", LIST_AREA_Y2 - LIST_AREA_Y1 - 35.0,
00164                       NULL);
00165 
00166   gtk_widget_show (GTK_WIDGET(canvas_list_selector));
00167 
00168   /* Set the new canvas to the background color or it's white */
00169   list_bg_item = gnome_canvas_item_new (gnome_canvas_root(canvas_list_selector),
00170                                    gnome_canvas_rect_get_type (),
00171                                    "x1", (double) 0,
00172                                    "y1", (double) 0,
00173                                    "x2", (double) LIST_AREA_X2 - LIST_AREA_X1,
00174                                    "y2", (double) LIST_AREA_Y2 - LIST_AREA_Y1,
00175                                    "fill_color_rgba", gc_skin_get_color("gcompris/imageselectbg"),
00176                                    NULL);
00177 
00178 
00179   w = gtk_vscrollbar_new (GTK_LAYOUT(canvas_list_selector)->vadjustment);
00180 
00181   gnome_canvas_item_new (GNOME_CANVAS_GROUP(rootitem),
00182                       gnome_canvas_widget_get_type (),
00183                       "widget", GTK_WIDGET(w),
00184                       "x", (double) LIST_AREA_X2 - 5.0,
00185                       "y", (double) LIST_AREA_Y1,
00186                       "width", 30.0,
00187                       "height", LIST_AREA_Y2 - LIST_AREA_Y1 - 20.0,
00188                       NULL);
00189   gtk_widget_show (w);
00190   gnome_canvas_set_center_scroll_region (GNOME_CANVAS (canvas_list_selector), FALSE);
00191 
00192   /* Set the scrollwheel event */
00193   gtk_signal_connect(GTK_OBJECT(canvas_list_selector), "event",
00194                    (GtkSignalFunc) item_event_scroll,
00195                    GNOME_CANVAS(canvas_list_selector));
00196 
00197   /*
00198    * Create the image scrollbar
00199    * --------------------------
00200    */
00201   canvas_image_selector     = GNOME_CANVAS(gnome_canvas_new ());
00202 
00203   gnome_canvas_item_new (GNOME_CANVAS_GROUP(rootitem),
00204                       gnome_canvas_widget_get_type (),
00205                       "widget", GTK_WIDGET(canvas_image_selector),
00206                       "x", (double) DRAWING_AREA_X1,
00207                       "y", (double) DRAWING_AREA_Y1,
00208                       "width",  DRAWING_AREA_X2 - DRAWING_AREA_X1,
00209                       "height", DRAWING_AREA_Y2 - DRAWING_AREA_Y1 - 35.0,
00210                       NULL);
00211 
00212   gtk_widget_show (GTK_WIDGET(canvas_image_selector));
00213 
00214   /* Set the new canvas to the background color or it's white */
00215   image_bg_item = gnome_canvas_item_new (gnome_canvas_root(canvas_image_selector),
00216                                    gnome_canvas_rect_get_type (),
00217                                    "x1", (double) 0,
00218                                    "y1", (double) 0,
00219                                    "x2", (double) DRAWING_AREA_X2 - DRAWING_AREA_X1,
00220                                    "y2", (double) DRAWING_AREA_Y2 - DRAWING_AREA_Y1,
00221                                     "fill_color_rgba", gc_skin_get_color("gcompris/imageselectbg"),
00222                                    NULL);
00223 
00224 
00225   w = gtk_vscrollbar_new (GTK_LAYOUT(canvas_image_selector)->vadjustment);
00226 
00227   gnome_canvas_item_new (GNOME_CANVAS_GROUP(rootitem),
00228                       gnome_canvas_widget_get_type (),
00229                       "widget", GTK_WIDGET(w),
00230                       "x", (double) DRAWING_AREA_X2 - 5.0,
00231                       "y", (double) DRAWING_AREA_Y1,
00232                       "width", 30.0,
00233                       "height", DRAWING_AREA_Y2 - DRAWING_AREA_Y1 - 20.0,
00234                       NULL);
00235   gtk_widget_show (w);
00236   gnome_canvas_set_center_scroll_region (GNOME_CANVAS (canvas_image_selector), FALSE);
00237 
00238   /* Set the scrollwheel event */
00239   gtk_signal_connect(GTK_OBJECT(canvas_image_selector), "event",
00240                    (GtkSignalFunc) item_event_scroll,
00241                    GNOME_CANVAS(canvas_image_selector));
00242 
00243   /*
00244    * DISPLAY IMAGES
00245    */
00246 
00247   /* Initial image position */
00248   ix  = 0;
00249   iy  = 0;
00250   isy = 0;
00251 
00252   /* I need  the following :
00253      -> if dataset is a file read it.
00254      -> if dataset is a directory, read all xml file in it.
00255   */
00256   dataseturl = \
00257     gc_file_find_absolute(dataset,
00258                                 NULL);
00259 
00260   /* if the file doesn't exist */
00261   if(g_file_test ((dataseturl), G_FILE_TEST_IS_DIR) )
00262     {
00263       g_warning("dataset %s is a directory. Trying to read xml", dataseturl);
00264 
00265       read_dataset_directory(dataseturl);
00266     }
00267   else if(dataseturl)
00268     {
00269       /* Read the given data set file, local or net */
00270       read_xml_file(dataseturl);
00271     }
00272   else
00273     {
00274       /* Network code for dataset directory */
00275       GSList *filelist = NULL;
00276       GSList *i = NULL;
00277 
00278       g_free(dataseturl);
00279       dataseturl = g_strconcat("boards/", dataset, NULL);
00280 
00281       filelist = gc_net_dir_read_name(dataseturl, ".xml");
00282 
00283       for (i = filelist; i != NULL; i = g_slist_next (i))
00284        {
00285          gchar *url = gc_file_find_absolute(i->data,
00286                                         NULL);
00287          g_warning("processing dataset=%s\n", (char *)i->data);
00288          read_xml_file(url);
00289          g_free(url);
00290        }
00291 
00292       g_slist_free(filelist);
00293 
00294     }
00295   g_free(dataseturl);
00296 
00297   /*
00298    * OK Button
00299    * ---------
00300    */
00301   item = gnome_canvas_item_new (GNOME_CANVAS_GROUP(rootitem),
00302                             gnome_canvas_pixbuf_get_type (),
00303                             "pixbuf", pixmap,
00304                             "x", (double) (BOARDWIDTH*0.5) - gdk_pixbuf_get_width(pixmap)/2,
00305                             "y", (double) y - gdk_pixbuf_get_height(pixmap) - 10,
00306                             NULL);
00307 
00308   gtk_signal_connect(GTK_OBJECT(item), "event",
00309                    (GtkSignalFunc) item_event_images_selector,
00310                    "/ok/");
00311   gtk_signal_connect(GTK_OBJECT(item), "event",
00312                    (GtkSignalFunc) gc_item_focus_event,
00313                    NULL);
00314 
00315   item2 = gnome_canvas_item_new (GNOME_CANVAS_GROUP(rootitem),
00316                             gnome_canvas_text_get_type (),
00317                             "text", _("OK"),
00318                             "font", gc_skin_font_title,
00319                             "x", (double)  BOARDWIDTH*0.5,
00320                             "y", (double)  y - gdk_pixbuf_get_height(pixmap) + 15,
00321                             "anchor", GTK_ANCHOR_CENTER,
00322                             "fill_color_rgba", gc_skin_color_text_button,
00323                             NULL);
00324   gtk_signal_connect(GTK_OBJECT(item2), "event",
00325                    (GtkSignalFunc) item_event_images_selector,
00326                    "/ok/");
00327   gtk_signal_connect(GTK_OBJECT(item2), "event",
00328                    (GtkSignalFunc) gc_item_focus_event,
00329                    item);
00330   gdk_pixbuf_unref(pixmap);
00331 
00332 }
00333 
00334 /*
00335  * Remove the displayed images_selector.
00336  * Do nothing if none is currently being dislayed
00337  */
00338 void gc_selector_images_stop ()
00339 {
00340   GcomprisBoard *gcomprisBoard = gc_board_get_current();
00341 
00342   if(gcomprisBoard!=NULL && images_selector_displayed)
00343     {
00344       gc_board_pause(FALSE);
00345     }
00346 
00347   // Destroy the images_selector box
00348   if(rootitem!=NULL)
00349     {
00350       gtk_object_destroy(GTK_OBJECT(rootitem));
00351     }
00352   rootitem = NULL;
00353   current_root_set = NULL;
00354 
00355   gc_bar_hide(FALSE);
00356   images_selector_displayed = FALSE;
00357 }
00358 
00359 
00360 
00361 /*-------------------------------------------------------------------------------*/
00362 /*-------------------------------------------------------------------------------*/
00363 /*-------------------------------------------------------------------------------*/
00364 /*-------------------------------------------------------------------------------*/
00365 
00366 static void
00367 display_image(gchar *imagename, GnomeCanvasItem *root_item)
00368 {
00369 
00370   GdkPixbuf *pixmap = NULL;
00371   GnomeCanvasItem *item;
00372   double xratio, yratio;
00373   double iw, ih;
00374 
00375   if (imagename==NULL || !images_selector_displayed)
00376     return;
00377 
00378   pixmap = gc_pixmap_load(imagename);
00379 
00380   /* Sad, the image is not found */
00381   if(!pixmap)
00382     return;
00383 
00384   iw = IMAGE_WIDTH;
00385   ih = IMAGE_HEIGHT;
00386 
00387   /* Calc the max to resize width or height */
00388   xratio = (double) (((double)gdk_pixbuf_get_width(pixmap))/iw);
00389   yratio = (double) (((double)gdk_pixbuf_get_height(pixmap))/ih);
00390   xratio = MAX(yratio,xratio);
00391 
00392   item = gnome_canvas_item_new (GNOME_CANVAS_GROUP(root_item),
00393                             gnome_canvas_pixbuf_get_type (),
00394                             "pixbuf", pixmap,
00395                             "x", (double)ix,
00396                             "y", (double)iy,
00397                             "width", (double) gdk_pixbuf_get_width(pixmap)/xratio,
00398                             "height", (double) gdk_pixbuf_get_height(pixmap)/xratio,
00399                             "width_set", TRUE,
00400                             "height_set", TRUE,
00401                             NULL);
00402   gdk_pixbuf_unref(pixmap);
00403 
00404   gtk_signal_connect(GTK_OBJECT(item), "event",
00405                    (GtkSignalFunc) item_event_images_selector,
00406                    imagename);
00407   gtk_signal_connect(GTK_OBJECT(item), "event",
00408                    (GtkSignalFunc) gc_item_focus_event,
00409                    NULL);
00410 
00411   ix+=IMAGE_WIDTH + IMAGE_GAP;
00412   if(ix>=DRAWING_AREA_X2-DRAWING_AREA_X1-IMAGE_GAP)
00413     {
00414       guint iy_calc;
00415       ix=0;
00416       iy+=IMAGE_HEIGHT + IMAGE_GAP;
00417 
00418       /* Cannot use GINT_TO_POINTER with a constant calculation */
00419       iy_calc = iy + IMAGE_HEIGHT + IMAGE_GAP;
00420       g_object_set_data (G_OBJECT (root_item), "iy", GINT_TO_POINTER (iy_calc));
00421 
00422       if(iy>=DRAWING_AREA_Y2-DRAWING_AREA_Y1) {
00423        gnome_canvas_item_set(image_bg_item,
00424                            "y2", (double) iy + IMAGE_HEIGHT + IMAGE_GAP,
00425                            NULL);
00426       }
00427     }
00428 }
00429 
00430 /*
00431  * Same as display_image but for the dataset
00432  * The imagelist contains the list of images to be displayed when this dataset is selected
00433  */
00434 static void
00435 display_image_set(gchar *imagename, GSList *imagelist)
00436 {
00437   GdkPixbuf *pixmap = NULL;
00438   GnomeCanvasItem *item;
00439   GnomeCanvasItem *rootitem_set;
00440   double xratio, yratio;
00441   double iw, ih;
00442 
00443   if (imagename==NULL || !images_selector_displayed)
00444     return;
00445 
00446   pixmap = gc_pixmap_load(imagename);
00447 
00448   iw = LIST_IMAGE_WIDTH;
00449   ih = LIST_IMAGE_HEIGHT;
00450 
00451   /* Calc the max to resize width or height */
00452   xratio = (double) (((double)gdk_pixbuf_get_width(pixmap))/iw);
00453   yratio = (double) (((double)gdk_pixbuf_get_height(pixmap))/ih);
00454   xratio = MAX(yratio,xratio);
00455 
00456   item = gnome_canvas_item_new (gnome_canvas_root(canvas_list_selector),
00457                             gnome_canvas_pixbuf_get_type (),
00458                             "pixbuf", pixmap,
00459                             "x", (double)5,
00460                             "y", (double)isy,
00461                             "width", (double) gdk_pixbuf_get_width(pixmap)/xratio,
00462                             "height", (double) gdk_pixbuf_get_height(pixmap)/xratio,
00463                             "width_set", TRUE,
00464                             "height_set", TRUE,
00465                             NULL);
00466   gdk_pixbuf_unref(pixmap);
00467   g_object_set_data (G_OBJECT (item), "imagelist", imagelist);
00468 
00469   gtk_signal_connect(GTK_OBJECT(item), "event",
00470                    (GtkSignalFunc) item_event_imageset_selector,
00471                    imagename);
00472   gtk_signal_connect(GTK_OBJECT(item), "event",
00473                    (GtkSignalFunc) gc_item_focus_event,
00474                    NULL);
00475 
00476   isy+=LIST_IMAGE_HEIGHT + IMAGE_GAP;
00477 
00478   gnome_canvas_set_scroll_region (GNOME_CANVAS (canvas_list_selector), 0, 0,
00479                               LIST_AREA_X2- LIST_AREA_X1,
00480                               isy - IMAGE_GAP);
00481 
00482   if(isy>=LIST_AREA_Y2-LIST_AREA_Y1) {
00483     gnome_canvas_item_set(list_bg_item,
00484                        "y2", (double)isy + LIST_IMAGE_HEIGHT + IMAGE_GAP,
00485                        NULL);
00486   }
00487 
00488   /* Create a root item to put the image list in it */
00489   rootitem_set = \
00490     gnome_canvas_item_new (gnome_canvas_root(canvas_image_selector),
00491                         gnome_canvas_group_get_type (),
00492                         "x", (double)0,
00493                         "y", (double)0,
00494                         NULL);
00495 
00496   g_object_set_data (G_OBJECT (item), "rootitem", rootitem_set);
00497   g_object_set_data (G_OBJECT (item), "imageset_done", GINT_TO_POINTER (0));
00498   g_signal_connect (item, "destroy",
00499                   G_CALLBACK (free_stuff),
00500                   imagelist);
00501 
00502 }
00503 
00504 static void
00505 free_stuff (GtkObject *obj, GSList *list)
00506 {
00507   while (g_slist_length(list) > 0) {
00508     g_free(g_slist_nth_data(list,0));
00509     list = g_slist_remove(list, g_slist_nth_data(list,0));
00510   }
00511   g_slist_free(list);
00512 }
00513 
00514 
00515 /* Callback when an image set is selected */
00516 static gint
00517 item_event_imageset_selector(GnomeCanvasItem *item, GdkEvent *event, gpointer data)
00518 {
00519   GSList *image_list;
00520   GnomeCanvasItem *rootitem_set;
00521   guint imageset_done;
00522 
00523   if(display_in_progress)
00524     return TRUE;
00525 
00526   switch (event->type)
00527     {
00528     case GDK_ENTER_NOTIFY:
00529       break;
00530     case GDK_LEAVE_NOTIFY:
00531       break;
00532     case GDK_BUTTON_PRESS:
00533        {
00534          guint last_iy;
00535 
00536          display_in_progress = TRUE;
00537 
00538          /* We must display the list of images for this set */
00539          image_list = (GSList *)g_object_get_data (G_OBJECT (item), "imagelist");
00540          g_return_val_if_fail (image_list != NULL, FALSE);
00541 
00542          /* We must display the list of images for this set */
00543          rootitem_set = (GnomeCanvasItem *)g_object_get_data (G_OBJECT (item), "rootitem");
00544          g_return_val_if_fail (rootitem_set != NULL, FALSE);
00545 
00546          imageset_done = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (item), "imageset_done"));
00547 
00548          /* Hide the previous image set if any */
00549          if (current_root_set != NULL) {
00550            gnome_canvas_item_hide(current_root_set);
00551          }
00552          /* Not yet displayed this set */
00553          if(!imageset_done) {
00554            guint iy_calc;
00555            /* Cannot use GINT_TO_POINTER with a constant calculation */
00556            /* Set the initial iy value                               */
00557            iy_calc = IMAGE_HEIGHT + IMAGE_GAP;
00558            g_object_set_data (G_OBJECT (rootitem_set), "iy", GINT_TO_POINTER (iy_calc));
00559 
00560            g_slist_foreach (image_list, (GFunc) display_image, rootitem_set);
00561            g_object_set_data (G_OBJECT (item), "imageset_done", GINT_TO_POINTER (1));
00562          }
00563 
00564          /* Set the image scrollbar back to its max position */
00565          last_iy = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (rootitem_set), "iy"));
00566          gnome_canvas_set_scroll_region (GNOME_CANVAS (canvas_image_selector), 0, 0,
00567                                      DRAWING_AREA_X2- DRAWING_AREA_X1,
00568                                      last_iy - IMAGE_GAP);
00569          if(last_iy>=DRAWING_AREA_Y2-DRAWING_AREA_Y1) {
00570            gnome_canvas_item_set(image_bg_item,
00571                               "y2", (double) last_iy + IMAGE_HEIGHT + IMAGE_GAP,
00572                               NULL);
00573          }
00574 
00575          gnome_canvas_item_show(rootitem_set);
00576          current_root_set = rootitem_set;
00577 
00578          /* Back to the initial image position */
00579          ix  = 0;
00580          iy  = 0;
00581 
00582          display_in_progress = FALSE;
00583        }
00584     default:
00585       break;
00586     }
00587   return FALSE;
00588 
00589 }
00590 
00591 /* Callback when an image is selected */
00592 static gint
00593 item_event_images_selector(GnomeCanvasItem *item, GdkEvent *event, gpointer data)
00594 {
00595 
00596   if(display_in_progress)
00597     return TRUE;
00598 
00599   switch (event->type)
00600     {
00601     case GDK_ENTER_NOTIFY:
00602       break;
00603     case GDK_LEAVE_NOTIFY:
00604       break;
00605     case GDK_BUTTON_PRESS:
00606       if(!strcmp((char *)data, "/ok/"))
00607        {
00608          gc_selector_images_stop();
00609        }
00610       else
00611        {
00612          if(imageSelectorCallBack!=NULL)
00613            imageSelectorCallBack(data);
00614 
00615          gc_selector_images_stop();
00616        }
00617     default:
00618       break;
00619     }
00620   return FALSE;
00621 
00622 }
00623 
00624 /* Callback when a scroll event happens */
00625 static gint
00626 item_event_scroll(GnomeCanvasItem *item, GdkEvent *event, GnomeCanvas *canvas)
00627 {
00628   int x, y;
00629   if(!rootitem)
00630     return FALSE;
00631 
00632   switch (event->type)
00633     {
00634     case GDK_SCROLL:
00635       gnome_canvas_get_scroll_offsets (canvas, &x, &y);
00636       if ( event->scroll.direction == GDK_SCROLL_UP )
00637        gnome_canvas_scroll_to (canvas, x, y - 20);
00638       else if ( event->scroll.direction == GDK_SCROLL_DOWN )
00639        gnome_canvas_scroll_to (canvas, x, y + 20);
00640 
00641       break;
00642     default:
00643       break;
00644     }
00645   return FALSE;
00646 }
00647 
00648 /*
00649  * Images PARSING
00650  * --------------
00651  */
00652 
00653 static void
00654 parseImage (xmlDocPtr doc, xmlNodePtr cur) {
00655   GcomprisProperties *properties = gc_prop_get();
00656   gchar  *imageSetName = NULL;
00657   gchar  *filename;
00658   gchar        *pathname = NULL;
00659   gchar  *absolutepath;
00660   GSList *imageList = NULL; /* List of Images */
00661   gboolean havePathName = FALSE;
00662   gchar  *type = NULL;
00663   GDir   *imageset_directory;
00664 
00665   /* get the filename of this ImageSet */
00666   imageSetName = (gchar *)xmlGetProp(cur, BAD_CAST "filename");
00667   if (xmlHasProp(cur, BAD_CAST "PathName")){
00668     pathname = (gchar *)xmlGetProp(cur, BAD_CAST "PathName");
00669     havePathName = TRUE;
00670   }
00671   if (havePathName && pathname[0] == '~'){
00672     /* replace '~' by home dir */
00673     pathname = g_strdup_printf("%s%s",g_get_home_dir(), pathname+1);
00674     if (!g_file_test ((pathname), G_FILE_TEST_IS_DIR)){
00675        g_warning("In ImageSet %s, the pathname for the home directory '%s' is not found. Skipping the whole ImageSet.",
00676                imageSetName, pathname);
00677       return;
00678     }
00679   }
00680 
00681   if (xmlHasProp(cur, BAD_CAST "type")){
00682     /* lsdir means try all file of directory */
00683     /* list means just keep old behaviour */
00684     /* others are extensions to look for */
00685     type = (gchar *)xmlGetProp(cur, BAD_CAST "type");
00686   }
00687 
00688   /* Looking for imageSetName */
00689   /* absolute path -> we check it's here */
00690   /* relative path -> we check for pathname/imagesetname */
00691   /*               -> and else for PACKAGE_DATA_DIR/imagesetname */
00692   if (havePathName) {
00693     if (!g_path_is_absolute (imageSetName)){
00694       absolutepath = gc_file_find_absolute(imageSetName, NULL);
00695     }
00696     else
00697       absolutepath = g_strdup(imageSetName);
00698   }
00699   else
00700     absolutepath = gc_file_find_absolute(imageSetName, NULL);
00701 
00702   if(!absolutepath)
00703     {
00704       g_warning("In ImageSet %s, an image is not found. Skipping ImageSet...", imageSetName);
00705       return;
00706     }
00707 
00708   if ((type == NULL) || (g_ascii_strcasecmp (type,"list")==0)) {
00709     /* old behaviour : we read the filenames from xml files */
00710 
00711     cur = cur->xmlChildrenNode;
00712     while (cur != NULL) {
00713       if ((!xmlStrcmp(cur->name, (const xmlChar *)"Image"))) {
00714        /* get the filename of this ImageSet */
00715        filename = (gchar *)xmlGetProp(cur, BAD_CAST "filename");
00716        if (havePathName){
00717          filename = g_strdup_printf("%s/%s",pathname,filename);
00718        }
00719        imageList = g_slist_prepend (imageList, filename);
00720       }
00721       cur = cur->next;
00722     }
00723 
00724   }
00725   else {
00726     /* new behaviour : we read all file of a directory */
00727     /* or all files with a given suffix */
00728 
00729     if (!g_file_test ((pathname), G_FILE_TEST_IS_DIR)){
00730       char *tmpdir;
00731       tmpdir = g_strdup_printf("%s/%s", properties->package_data_dir, pathname);
00732       g_free(pathname);
00733       pathname = tmpdir;
00734       if (!g_file_test ((pathname), G_FILE_TEST_IS_DIR)){
00735         g_warning("In ImageSet %s, directory %s is not found. Skipping all the ImageSet...", absolutepath, pathname);
00736         return;
00737       }
00738     }
00739     imageset_directory = g_dir_open (pathname, 0, NULL);
00740     const gchar * onefile;
00741     while ((onefile = g_dir_read_name(imageset_directory))){
00742       if ((g_ascii_strcasecmp (type,"lsdir") != 0) &&
00743          (!g_str_has_suffix (onefile, type))){
00744        continue;
00745       }
00746       filename = g_strdup_printf("%s/%s", pathname, onefile);
00747       if (!g_file_test ((filename), G_FILE_TEST_IS_REGULAR)){
00748        continue;
00749       }
00750 
00751       {
00752        /* Add a % before a % to avoid it being used as a format arg */
00753        gchar **tmp;
00754        gchar *filename2;
00755        if((tmp = g_strsplit(filename, "%", -1)))
00756          {
00757            filename2 = g_strjoinv("%%", tmp);
00758            g_strfreev(tmp);
00759            g_free(filename);
00760            filename = filename2;
00761          }
00762       }
00763       imageList = g_slist_prepend (imageList, filename);
00764     }
00765     g_dir_close(imageset_directory);
00766   }
00767 
00768   /* do not display if there is nothing to display */
00769   if (imageList != NULL) /* g_slist is not empty */
00770     display_image_set(imageSetName, imageList);
00771 
00772   g_free(absolutepath);
00773   if(pathname)
00774     g_free(pathname);
00775   if(type)
00776     g_free(type);
00777 
00778   return;
00779 }
00780 
00781 static void
00782 parse_doc(xmlDocPtr doc) {
00783   xmlNodePtr cur;
00784 
00785   cur = xmlDocGetRootElement(doc);
00786   if (cur == NULL) {
00787     fprintf(stderr,"empty document\n");
00788     xmlFreeDoc(doc);
00789     return;
00790   }
00791   cur = cur->xmlChildrenNode;
00792 
00793   while (cur != NULL) {
00794     if ((!xmlStrcmp(cur->name, (const xmlChar *)"ImageSet"))){
00795       parseImage (doc, cur);
00796     }
00797 
00798     cur = cur->next;
00799   }
00800 
00801   return;
00802 }
00803 
00804 
00805 /* read an xml file into our memory structures and update our view,
00806  * dump any old data we have in memory if we can load a new set
00807  *
00808  * \param fname is an absolute file name
00809  *
00810  */
00811 static gboolean
00812 read_xml_file(gchar *fname)
00813 {
00814   /* pointer to the new doc */
00815   xmlDocPtr doc;
00816 
00817   g_return_val_if_fail(fname!=NULL, FALSE);
00818 
00819   doc = gc_net_load_xml(fname);
00820 
00821   /* in case something went wrong */
00822   if(!doc)
00823     return FALSE;
00824 
00825   if(/* if there is no root element */
00826      !doc->children ||
00827      /* if it doesn't have a name */
00828      !doc->children->name ||
00829      /* if it isn't the good node */
00830      g_strcasecmp((gchar *)doc->children->name, "ImageSetRoot")!=0) {
00831     xmlFreeDoc(doc);
00832     return FALSE;
00833   }
00834 
00835   /* parse our document and replace old data */
00836   parse_doc(doc);
00837 
00838   xmlFreeDoc(doc);
00839 
00840   return TRUE;
00841 }
00842 
00843 
00850 static gboolean
00851 read_dataset_directory(gchar *dataset_dir)
00852 {
00853   GDir *dataset_directory = g_dir_open (dataset_dir, 0, NULL);
00854   const gchar *fname;
00855   gchar *absolute_fname;
00856 
00857   if(!dataset_directory)
00858     return FALSE;
00859 
00860   while ((fname = g_dir_read_name(dataset_directory))) {
00861     /* skip files without ".xml" */
00862     if (!g_str_has_suffix (fname,".xml")){
00863       g_warning("skipping file not in .xml : %s", fname);
00864       continue;
00865     }
00866 
00867     absolute_fname = g_strdup_printf("%s/%s", dataset_dir, fname);
00868     g_warning("Reading dataset file %s", absolute_fname);
00869 
00870     if (!g_file_test ((absolute_fname), G_FILE_TEST_EXISTS))
00871     {
00872       g_free(absolute_fname);
00873       continue;
00874     }
00875 
00876     /* parse the new file and put the result into newdoc */
00877 
00878     /* pointer to the new doc */
00879     xmlDocPtr doc;
00880 
00881     doc = xmlParseFile(absolute_fname);
00882 
00883     /* in case something went wrong */
00884     if(!doc)
00885     {
00886       g_free(absolute_fname);
00887       continue;
00888     }
00889     
00890     if(/* if there is no root element */
00891        !doc->children ||
00892        /* if it doesn't have a name */
00893        !doc->children->name ||
00894        /* if it isn't the good node */
00895        g_strcasecmp((gchar *)doc->children->name, "ImageSetRoot")!=0) {
00896       xmlFreeDoc(doc);
00897       g_free(absolute_fname);
00898       continue;
00899     }
00900 
00901     /* parse our document and replace old data */
00902     g_warning("Parsing dataset : %s \n", absolute_fname);
00903     g_free(absolute_fname);
00904     parse_doc(doc);
00905 
00906     xmlFreeDoc(doc);
00907   }
00908 
00909   g_dir_close(dataset_directory);
00910 
00911   return TRUE;
00912 }