/* gcompris - images_selector.c * * Copyright (C) 2000 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 . */ /** * An image selector for gcompris * */ #include "string.h" /* libxml includes */ #include #include #include "gcompris.h" #define SOUNDLISTFILE PACKAGE static gint item_event_images_selector(GnomeCanvasItem *item, GdkEvent *event, gpointer data); static gint item_event_imageset_selector(GnomeCanvasItem *item, GdkEvent *event, gpointer data); static gint item_event_scroll(GnomeCanvasItem *item, GdkEvent *event, GnomeCanvas *canvas); static gboolean read_xml_file(gchar *fname); static gboolean read_dataset_directory(gchar *dataset_dir); static void display_image(gchar *imagename, GnomeCanvasItem *rootitem); static void free_stuff (GtkObject *obj, GSList *data); static gboolean images_selector_displayed = FALSE; static GnomeCanvasItem *rootitem = NULL; static GnomeCanvasItem *current_root_set = NULL; static GnomeCanvas *canvas_list_selector; /* The scrolled left part */ static GnomeCanvasItem *list_bg_item; static GnomeCanvas *canvas_image_selector; /* The scrolled right part */ static GnomeCanvasItem *image_bg_item; static ImageSelectorCallBack imageSelectorCallBack = NULL; static gboolean display_in_progress; /* Represent the limits of the image area */ #define DRAWING_AREA_X1 111.0 #define DRAWING_AREA_Y1 14.0 #define DRAWING_AREA_X2 774.0 #define DRAWING_AREA_Y2 500.0 /* Represent the limits of list area */ #define LIST_AREA_X1 18.0 #define LIST_AREA_Y1 16.0 #define LIST_AREA_X2 80.0 #define LIST_AREA_Y2 500.0 #define VERTICAL_NUMBER_OF_LIST_IMAGE 6 #define HORIZONTAL_NUMBER_OF_IMAGE 8 #define VERTICAL_NUMBER_OF_IMAGE 4 #define IMAGE_GAP 10 #define IMAGE_WIDTH (DRAWING_AREA_X2-DRAWING_AREA_X1)/HORIZONTAL_NUMBER_OF_IMAGE-IMAGE_GAP #define IMAGE_HEIGHT (DRAWING_AREA_Y2-DRAWING_AREA_Y1)/VERTICAL_NUMBER_OF_IMAGE-IMAGE_GAP #define LIST_IMAGE_WIDTH LIST_AREA_X2-LIST_AREA_X1-IMAGE_GAP #define LIST_IMAGE_HEIGHT (LIST_AREA_Y2-LIST_AREA_Y1)/VERTICAL_NUMBER_OF_LIST_IMAGE-IMAGE_GAP static guint ix; static guint iy; static guint isy; /* * Main entry point * ---------------- * */ /* * Do all the images_selector display and register the events */ void gc_selector_images_start (GcomprisBoard *gcomprisBoard, gchar *dataset, ImageSelectorCallBack iscb) { GnomeCanvasItem *item, *item2; GdkPixbuf *pixmap = NULL; gint y = 0; gint y_start = 0; gint x_start = 0; gchar *dataseturl = NULL; GtkWidget *w; if(rootitem) return; gc_bar_hide(TRUE); gc_board_pause(TRUE); imageSelectorCallBack=iscb; rootitem = \ gnome_canvas_item_new (gnome_canvas_root(gc_get_canvas()), gnome_canvas_group_get_type (), "x", (double)0, "y", (double)0, NULL); images_selector_displayed = TRUE; pixmap = gc_skin_pixmap_load("images_selector_bg.png"); y_start = (BOARDHEIGHT - gdk_pixbuf_get_height(pixmap))/2; x_start = (BOARDWIDTH - gdk_pixbuf_get_width(pixmap))/2; item = gnome_canvas_item_new (GNOME_CANVAS_GROUP(rootitem), gnome_canvas_pixbuf_get_type (), "pixbuf", pixmap, "x", (double) x_start, "y", (double) y_start, NULL); y = BOARDHEIGHT - (BOARDHEIGHT - gdk_pixbuf_get_height(pixmap))/2; gdk_pixbuf_unref(pixmap); y_start += 110; pixmap = gc_skin_pixmap_load("button_large.png"); /* * Create the list scrollbar * ------------------------- */ canvas_list_selector = GNOME_CANVAS(gnome_canvas_new ()); gnome_canvas_item_new (GNOME_CANVAS_GROUP(rootitem), gnome_canvas_widget_get_type (), "widget", GTK_WIDGET(canvas_list_selector), "x", (double) LIST_AREA_X1, "y", (double) LIST_AREA_Y1, "width", LIST_AREA_X2 - LIST_AREA_X1, "height", LIST_AREA_Y2 - LIST_AREA_Y1 - 35.0, NULL); gtk_widget_show (GTK_WIDGET(canvas_list_selector)); /* Set the new canvas to the background color or it's white */ list_bg_item = gnome_canvas_item_new (gnome_canvas_root(canvas_list_selector), gnome_canvas_rect_get_type (), "x1", (double) 0, "y1", (double) 0, "x2", (double) LIST_AREA_X2 - LIST_AREA_X1, "y2", (double) LIST_AREA_Y2 - LIST_AREA_Y1, "fill_color_rgba", gc_skin_get_color("gcompris/imageselectbg"), NULL); w = gtk_vscrollbar_new (GTK_LAYOUT(canvas_list_selector)->vadjustment); gnome_canvas_item_new (GNOME_CANVAS_GROUP(rootitem), gnome_canvas_widget_get_type (), "widget", GTK_WIDGET(w), "x", (double) LIST_AREA_X2 - 5.0, "y", (double) LIST_AREA_Y1, "width", 30.0, "height", LIST_AREA_Y2 - LIST_AREA_Y1 - 20.0, NULL); gtk_widget_show (w); gnome_canvas_set_center_scroll_region (GNOME_CANVAS (canvas_list_selector), FALSE); /* Set the scrollwheel event */ gtk_signal_connect(GTK_OBJECT(canvas_list_selector), "event", (GtkSignalFunc) item_event_scroll, GNOME_CANVAS(canvas_list_selector)); /* * Create the image scrollbar * -------------------------- */ canvas_image_selector = GNOME_CANVAS(gnome_canvas_new ()); gnome_canvas_item_new (GNOME_CANVAS_GROUP(rootitem), gnome_canvas_widget_get_type (), "widget", GTK_WIDGET(canvas_image_selector), "x", (double) DRAWING_AREA_X1, "y", (double) DRAWING_AREA_Y1, "width", DRAWING_AREA_X2 - DRAWING_AREA_X1, "height", DRAWING_AREA_Y2 - DRAWING_AREA_Y1 - 35.0, NULL); gtk_widget_show (GTK_WIDGET(canvas_image_selector)); /* Set the new canvas to the background color or it's white */ image_bg_item = gnome_canvas_item_new (gnome_canvas_root(canvas_image_selector), gnome_canvas_rect_get_type (), "x1", (double) 0, "y1", (double) 0, "x2", (double) DRAWING_AREA_X2 - DRAWING_AREA_X1, "y2", (double) DRAWING_AREA_Y2 - DRAWING_AREA_Y1, "fill_color_rgba", gc_skin_get_color("gcompris/imageselectbg"), NULL); w = gtk_vscrollbar_new (GTK_LAYOUT(canvas_image_selector)->vadjustment); gnome_canvas_item_new (GNOME_CANVAS_GROUP(rootitem), gnome_canvas_widget_get_type (), "widget", GTK_WIDGET(w), "x", (double) DRAWING_AREA_X2 - 5.0, "y", (double) DRAWING_AREA_Y1, "width", 30.0, "height", DRAWING_AREA_Y2 - DRAWING_AREA_Y1 - 20.0, NULL); gtk_widget_show (w); gnome_canvas_set_center_scroll_region (GNOME_CANVAS (canvas_image_selector), FALSE); /* Set the scrollwheel event */ gtk_signal_connect(GTK_OBJECT(canvas_image_selector), "event", (GtkSignalFunc) item_event_scroll, GNOME_CANVAS(canvas_image_selector)); /* * DISPLAY IMAGES */ /* Initial image position */ ix = 0; iy = 0; isy = 0; /* I need the following : -> if dataset is a file read it. -> if dataset is a directory, read all xml file in it. */ dataseturl = \ gc_file_find_absolute(dataset, NULL); /* if the file doesn't exist */ if(g_file_test ((dataseturl), G_FILE_TEST_IS_DIR) ) { g_warning("dataset %s is a directory. Trying to read xml", dataseturl); 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); /* * OK Button * --------- */ item = gnome_canvas_item_new (GNOME_CANVAS_GROUP(rootitem), gnome_canvas_pixbuf_get_type (), "pixbuf", pixmap, "x", (double) (BOARDWIDTH*0.5) - gdk_pixbuf_get_width(pixmap)/2, "y", (double) y - gdk_pixbuf_get_height(pixmap) - 10, NULL); gtk_signal_connect(GTK_OBJECT(item), "event", (GtkSignalFunc) item_event_images_selector, "/ok/"); gtk_signal_connect(GTK_OBJECT(item), "event", (GtkSignalFunc) gc_item_focus_event, NULL); item2 = gnome_canvas_item_new (GNOME_CANVAS_GROUP(rootitem), gnome_canvas_text_get_type (), "text", _("OK"), "font", gc_skin_font_title, "x", (double) BOARDWIDTH*0.5, "y", (double) y - gdk_pixbuf_get_height(pixmap) + 15, "anchor", GTK_ANCHOR_CENTER, "fill_color_rgba", gc_skin_color_text_button, NULL); gtk_signal_connect(GTK_OBJECT(item2), "event", (GtkSignalFunc) item_event_images_selector, "/ok/"); gtk_signal_connect(GTK_OBJECT(item2), "event", (GtkSignalFunc) gc_item_focus_event, item); gdk_pixbuf_unref(pixmap); } /* * Remove the displayed images_selector. * Do nothing if none is currently being dislayed */ void gc_selector_images_stop () { GcomprisBoard *gcomprisBoard = gc_board_get_current(); if(gcomprisBoard!=NULL && images_selector_displayed) { gc_board_pause(FALSE); } // Destroy the images_selector box if(rootitem!=NULL) { gtk_object_destroy(GTK_OBJECT(rootitem)); } rootitem = NULL; current_root_set = NULL; gc_bar_hide(FALSE); images_selector_displayed = FALSE; } /*-------------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------------*/ static void display_image(gchar *imagename, GnomeCanvasItem *root_item) { GdkPixbuf *pixmap = NULL; GnomeCanvasItem *item; double xratio, yratio; double iw, ih; if (imagename==NULL || !images_selector_displayed) return; pixmap = gc_pixmap_load(imagename); /* Sad, the image is not found */ if(!pixmap) return; iw = IMAGE_WIDTH; ih = IMAGE_HEIGHT; /* Calc the max to resize width or height */ xratio = (double) (((double)gdk_pixbuf_get_width(pixmap))/iw); yratio = (double) (((double)gdk_pixbuf_get_height(pixmap))/ih); xratio = MAX(yratio,xratio); item = gnome_canvas_item_new (GNOME_CANVAS_GROUP(root_item), gnome_canvas_pixbuf_get_type (), "pixbuf", pixmap, "x", (double)ix, "y", (double)iy, "width", (double) gdk_pixbuf_get_width(pixmap)/xratio, "height", (double) gdk_pixbuf_get_height(pixmap)/xratio, "width_set", TRUE, "height_set", TRUE, NULL); gdk_pixbuf_unref(pixmap); gtk_signal_connect(GTK_OBJECT(item), "event", (GtkSignalFunc) item_event_images_selector, imagename); gtk_signal_connect(GTK_OBJECT(item), "event", (GtkSignalFunc) gc_item_focus_event, NULL); ix+=IMAGE_WIDTH + IMAGE_GAP; if(ix>=DRAWING_AREA_X2-DRAWING_AREA_X1-IMAGE_GAP) { guint iy_calc; ix=0; iy+=IMAGE_HEIGHT + IMAGE_GAP; /* Cannot use GINT_TO_POINTER with a constant calculation */ iy_calc = iy + IMAGE_HEIGHT + IMAGE_GAP; g_object_set_data (G_OBJECT (root_item), "iy", GINT_TO_POINTER (iy_calc)); if(iy>=DRAWING_AREA_Y2-DRAWING_AREA_Y1) { gnome_canvas_item_set(image_bg_item, "y2", (double) iy + IMAGE_HEIGHT + IMAGE_GAP, NULL); } } } /* * Same as display_image but for the dataset * The imagelist contains the list of images to be displayed when this dataset is selected */ static void display_image_set(gchar *imagename, GSList *imagelist) { GdkPixbuf *pixmap = NULL; GnomeCanvasItem *item; GnomeCanvasItem *rootitem_set; double xratio, yratio; double iw, ih; if (imagename==NULL || !images_selector_displayed) return; pixmap = gc_pixmap_load(imagename); iw = LIST_IMAGE_WIDTH; ih = LIST_IMAGE_HEIGHT; /* Calc the max to resize width or height */ xratio = (double) (((double)gdk_pixbuf_get_width(pixmap))/iw); yratio = (double) (((double)gdk_pixbuf_get_height(pixmap))/ih); xratio = MAX(yratio,xratio); item = gnome_canvas_item_new (gnome_canvas_root(canvas_list_selector), gnome_canvas_pixbuf_get_type (), "pixbuf", pixmap, "x", (double)5, "y", (double)isy, "width", (double) gdk_pixbuf_get_width(pixmap)/xratio, "height", (double) gdk_pixbuf_get_height(pixmap)/xratio, "width_set", TRUE, "height_set", TRUE, NULL); gdk_pixbuf_unref(pixmap); g_object_set_data (G_OBJECT (item), "imagelist", imagelist); gtk_signal_connect(GTK_OBJECT(item), "event", (GtkSignalFunc) item_event_imageset_selector, imagename); gtk_signal_connect(GTK_OBJECT(item), "event", (GtkSignalFunc) gc_item_focus_event, NULL); isy+=LIST_IMAGE_HEIGHT + IMAGE_GAP; gnome_canvas_set_scroll_region (GNOME_CANVAS (canvas_list_selector), 0, 0, LIST_AREA_X2- LIST_AREA_X1, isy - IMAGE_GAP); if(isy>=LIST_AREA_Y2-LIST_AREA_Y1) { gnome_canvas_item_set(list_bg_item, "y2", (double)isy + LIST_IMAGE_HEIGHT + IMAGE_GAP, NULL); } /* Create a root item to put the image list in it */ rootitem_set = \ gnome_canvas_item_new (gnome_canvas_root(canvas_image_selector), gnome_canvas_group_get_type (), "x", (double)0, "y", (double)0, NULL); g_object_set_data (G_OBJECT (item), "rootitem", rootitem_set); g_object_set_data (G_OBJECT (item), "imageset_done", GINT_TO_POINTER (0)); g_signal_connect (item, "destroy", G_CALLBACK (free_stuff), imagelist); } static void free_stuff (GtkObject *obj, GSList *list) { while (g_slist_length(list) > 0) { g_free(g_slist_nth_data(list,0)); list = g_slist_remove(list, g_slist_nth_data(list,0)); } g_slist_free(list); } /* Callback when an image set is selected */ static gint item_event_imageset_selector(GnomeCanvasItem *item, GdkEvent *event, gpointer data) { GSList *image_list; GnomeCanvasItem *rootitem_set; guint imageset_done; if(display_in_progress) return TRUE; switch (event->type) { case GDK_ENTER_NOTIFY: break; case GDK_LEAVE_NOTIFY: break; case GDK_BUTTON_PRESS: { guint last_iy; display_in_progress = TRUE; /* We must display the list of images for this set */ image_list = (GSList *)g_object_get_data (G_OBJECT (item), "imagelist"); g_return_val_if_fail (image_list != NULL, FALSE); /* We must display the list of images for this set */ rootitem_set = (GnomeCanvasItem *)g_object_get_data (G_OBJECT (item), "rootitem"); g_return_val_if_fail (rootitem_set != NULL, FALSE); imageset_done = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (item), "imageset_done")); /* Hide the previous image set if any */ if (current_root_set != NULL) { gnome_canvas_item_hide(current_root_set); } /* Not yet displayed this set */ if(!imageset_done) { guint iy_calc; /* Cannot use GINT_TO_POINTER with a constant calculation */ /* Set the initial iy value */ iy_calc = IMAGE_HEIGHT + IMAGE_GAP; g_object_set_data (G_OBJECT (rootitem_set), "iy", GINT_TO_POINTER (iy_calc)); g_slist_foreach (image_list, (GFunc) display_image, rootitem_set); g_object_set_data (G_OBJECT (item), "imageset_done", GINT_TO_POINTER (1)); } /* Set the image scrollbar back to its max position */ last_iy = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (rootitem_set), "iy")); gnome_canvas_set_scroll_region (GNOME_CANVAS (canvas_image_selector), 0, 0, DRAWING_AREA_X2- DRAWING_AREA_X1, last_iy - IMAGE_GAP); if(last_iy>=DRAWING_AREA_Y2-DRAWING_AREA_Y1) { gnome_canvas_item_set(image_bg_item, "y2", (double) last_iy + IMAGE_HEIGHT + IMAGE_GAP, NULL); } gnome_canvas_item_show(rootitem_set); current_root_set = rootitem_set; /* Back to the initial image position */ ix = 0; iy = 0; display_in_progress = FALSE; } default: break; } return FALSE; } /* Callback when an image is selected */ static gint item_event_images_selector(GnomeCanvasItem *item, GdkEvent *event, gpointer data) { if(display_in_progress) return TRUE; switch (event->type) { case GDK_ENTER_NOTIFY: break; case GDK_LEAVE_NOTIFY: break; case GDK_BUTTON_PRESS: if(!strcmp((char *)data, "/ok/")) { gc_selector_images_stop(); } else { if(imageSelectorCallBack!=NULL) imageSelectorCallBack(data); gc_selector_images_stop(); } default: break; } return FALSE; } /* Callback when a scroll event happens */ static gint item_event_scroll(GnomeCanvasItem *item, GdkEvent *event, GnomeCanvas *canvas) { int x, y; if(!rootitem) return FALSE; switch (event->type) { case GDK_SCROLL: gnome_canvas_get_scroll_offsets (canvas, &x, &y); if ( event->scroll.direction == GDK_SCROLL_UP ) gnome_canvas_scroll_to (canvas, x, y - 20); else if ( event->scroll.direction == GDK_SCROLL_DOWN ) gnome_canvas_scroll_to (canvas, x, y + 20); break; default: break; } return FALSE; } /* * Images PARSING * -------------- */ static void parseImage (xmlDocPtr doc, xmlNodePtr cur) { GcomprisProperties *properties = gc_prop_get(); gchar *imageSetName = NULL; gchar *filename; gchar *pathname = NULL; gchar *absolutepath; GSList *imageList = NULL; /* List of Images */ gboolean havePathName = FALSE; gchar *type = NULL; GDir *imageset_directory; /* get the filename of this ImageSet */ imageSetName = (gchar *)xmlGetProp(cur, BAD_CAST "filename"); if (xmlHasProp(cur, BAD_CAST "PathName")){ pathname = (gchar *)xmlGetProp(cur, BAD_CAST "PathName"); havePathName = TRUE; } if (havePathName && pathname[0] == '~' && g_get_home_dir()) { /* replace '~' by home dir */ pathname = g_strdup_printf("%s%s",g_get_home_dir(), pathname+1); if (!g_file_test ((pathname), G_FILE_TEST_IS_DIR)){ g_warning("In ImageSet %s, the pathname for the home directory '%s' is not found. Skipping the whole ImageSet.", imageSetName, pathname); return; } } if (xmlHasProp(cur, BAD_CAST "type")){ /* lsdir means try all file of directory */ /* list means just keep old behaviour */ /* others are extensions to look for */ type = (gchar *)xmlGetProp(cur, BAD_CAST "type"); } /* Looking for imageSetName */ /* absolute path -> we check it's here */ /* relative path -> we check for pathname/imagesetname */ /* -> and else for PACKAGE_DATA_DIR/imagesetname */ if (havePathName) { if (!g_path_is_absolute (imageSetName)){ absolutepath = gc_file_find_absolute(imageSetName, NULL); } else absolutepath = g_strdup(imageSetName); } else absolutepath = gc_file_find_absolute(imageSetName, NULL); if(!absolutepath) { g_warning("In ImageSet %s, an image is not found. Skipping ImageSet...", imageSetName); return; } if ((type == NULL) || (g_ascii_strcasecmp (type,"list")==0)) { /* old behaviour : we read the filenames from xml files */ cur = cur->xmlChildrenNode; while (cur != NULL) { if ((!xmlStrcmp(cur->name, (const xmlChar *)"Image"))) { /* get the filename of this ImageSet */ filename = (gchar *)xmlGetProp(cur, BAD_CAST "filename"); if (havePathName){ filename = g_strdup_printf("%s/%s",pathname,filename); } imageList = g_slist_prepend (imageList, filename); } cur = cur->next; } } else { /* new behaviour : we read all file of a directory */ /* or all files with a given suffix */ if (!g_file_test ((pathname), G_FILE_TEST_IS_DIR)){ char *tmpdir; tmpdir = g_strdup_printf("%s/%s", properties->package_data_dir, pathname); g_free(pathname); pathname = tmpdir; if (!g_file_test ((pathname), G_FILE_TEST_IS_DIR)){ g_warning("In ImageSet %s, directory %s is not found. Skipping all the ImageSet...", absolutepath, pathname); return; } } imageset_directory = g_dir_open (pathname, 0, NULL); const gchar * onefile; while ((onefile = g_dir_read_name(imageset_directory))) { /* Skip README file */ if(g_ascii_strcasecmp (onefile, "readme") == 0) continue; if ((g_ascii_strcasecmp (type,"lsdir") != 0) && (!g_str_has_suffix (onefile, type))){ continue; } filename = g_strdup_printf("%s/%s", pathname, onefile); if (!g_file_test ((filename), G_FILE_TEST_IS_REGULAR)){ continue; } { /* Add a % before a % to avoid it being used as a format arg */ gchar **tmp; gchar *filename2; if((tmp = g_strsplit(filename, "%", -1))) { filename2 = g_strjoinv("%%", tmp); g_strfreev(tmp); g_free(filename); filename = filename2; } } imageList = g_slist_prepend (imageList, filename); } g_dir_close(imageset_directory); } /* do not display if there is nothing to display */ if (imageList != NULL) /* g_slist is not empty */ display_image_set(imageSetName, imageList); g_free(absolutepath); if(pathname) g_free(pathname); if(type) g_free(type); return; } static void parse_doc(xmlDocPtr doc) { xmlNodePtr cur; cur = xmlDocGetRootElement(doc); if (cur == NULL) { g_warning("empty document\n"); xmlFreeDoc(doc); return; } cur = cur->xmlChildrenNode; while (cur != NULL) { if ((!xmlStrcmp(cur->name, (const xmlChar *)"ImageSet"))){ parseImage (doc, cur); } cur = cur->next; } return; } /* 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 * * \return TRUE is the parsing occurs, FALSE instead * */ static gboolean read_dataset_directory(gchar *dataset_dir) { GDir *dataset_directory = g_dir_open (dataset_dir, 0, NULL); const gchar *fname; gchar *absolute_fname; if(!dataset_directory) return FALSE; while ((fname = g_dir_read_name(dataset_directory))) { /* skip files without ".xml" */ if (!g_str_has_suffix (fname,".xml")){ g_warning("skipping file not in .xml : %s", fname); continue; } absolute_fname = g_strdup_printf("%s/%s", dataset_dir, fname); g_warning("Reading dataset file %s", absolute_fname); if (!g_file_test ((absolute_fname), G_FILE_TEST_EXISTS)) { g_free(absolute_fname); continue; } /* parse the new file and put the result into newdoc */ /* pointer to the new doc */ xmlDocPtr doc; doc = xmlParseFile(absolute_fname); /* in case something went wrong */ if(!doc) { g_free(absolute_fname); continue; } 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); g_free(absolute_fname); continue; } /* parse our document and replace old data */ g_warning("Parsing dataset : %s \n", absolute_fname); g_free(absolute_fname); parse_doc(doc); xmlFreeDoc(doc); } g_dir_close(dataset_directory); return TRUE; }