/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* vim: set sw=8: */ /* * guppi-gnumeric-xml.c: utilites for manipulating the xml spec * used to describe a graph. * * Copyright (C) 2001 Ximian, Inc * * Developed by Jody Goldberg (jgoldberg@home.com) * * 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 2 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, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA */ #include #include "guppi-gnumeric-xml.h" #include "guppi-gnumeric-graph.h" #include "guppi-gnumeric-manager.h" #include "guppi-gnumeric-vector.h" #include #include #include #include #include xmlNode * gup_gnm_graph_get_plot (GupGnmGraph *graph, int plotID) { xmlNode *plot; g_return_val_if_fail (graph != NULL, NULL); if (graph->spec == NULL) return NULL; plot = e_xml_get_child_by_name (graph->spec->xmlRootNode, "Plots"); g_return_val_if_fail (plot != NULL, NULL); for (plot = plot->xmlChildrenNode ; plot ; plot = plot->next) if (!strcmp (plot->name, "Plot") && gup_gnm_plot_get_id (plot) == plotID) return plot; return NULL; } gboolean gup_gnm_graph_foreach_series (GupGnmGraph *graph, GupGnmSeriesFn func, gpointer user) { xmlNode *plot, *series; if (graph->spec == NULL) return FALSE; plot = e_xml_get_child_by_name (graph->spec->xmlRootNode, "Plots"); g_return_val_if_fail (plot != NULL, TRUE); for (plot = plot->xmlChildrenNode ; plot ; plot = plot->next) { if (strcmp (plot->name, "Plot")) continue; series = e_xml_get_child_by_name (plot, "Data"); if (series == NULL) continue; for (series = series->xmlChildrenNode ; series ; series = series->next) { if (strcmp (series->name, "Series")) continue; if ((*func)(graph, plot, series, user)) return TRUE; } } return FALSE; } int gup_gnm_plot_get_id (xmlNode *plot) { /* FIXME : get an 'ID' rather than using index */ return e_xml_get_integer_prop_by_name_with_default (plot, "index", -1); } int gup_gnm_series_get_id (xmlNode *series) { /* FIXME : get an 'ID' rather than using index */ return e_xml_get_integer_prop_by_name_with_default (series, "index", -1); } static inline int gup_gnm_dimension_get_vectorID (xmlNode *dim) { return e_xml_get_integer_prop_by_name_with_default (dim, "ID", -1); } xmlNode * gup_gnm_series_get_dimension (xmlNode *series, char const *target_dim_name) { xmlNode *dim; xmlChar *dim_name; for (dim = series->xmlChildrenNode; dim != NULL ; dim = dim->next) { if (strcmp (dim->name, "Dimension")) continue; dim_name = xmlGetProp (dim, "dim_name"); if (dim_name != NULL) { gboolean const res = (strcmp (dim_name, target_dim_name) == 0); xmlFree (dim_name); if (res) return dim; } } return NULL; } GupGnmVector * gup_gnm_series_dim_get_vector (xmlNode *series, char const *dim_name, GupGnmGraph const *graph) { xmlNode *dim = gup_gnm_series_get_dimension (series, dim_name); if (dim != NULL) { int id = gup_gnm_dimension_get_vectorID (dim); if (id >= 0) return gup_gnm_manager_get_vector (graph->manager, id); } return NULL; } GuppiSeqScalar * gup_gnm_series_dim_get_scalar (xmlNode *series, char const *dim, GupGnmGraph const *graph) { GupGnmVector *vec = gup_gnm_series_dim_get_vector (series, dim, graph); if (vec != NULL) return gup_gnm_vector_get_scalar (vec); return NULL; } GuppiSeqString * gup_gnm_series_dim_get_string (xmlNode *series, char const *dim, GupGnmGraph const *graph) { GupGnmVector *vec = gup_gnm_series_dim_get_vector (series, dim, graph); if (vec != NULL) return gup_gnm_vector_get_string (vec); return NULL; } void gup_gnm_series_add_dimension (xmlNode *series, char const *dim_name, int id) { xmlNode *vec = xmlNewChild (series, series->ns, "Dimension", NULL); xmlSetProp (vec, "dim_name", dim_name); e_xml_set_integer_prop_by_name (vec, "ID", id); } xmlNode * gup_gnm_attr_get (xmlNode *node, char const *name) { return node ? e_xml_get_child_by_name (node, name) : NULL; } gboolean gup_gnm_attr_get_bool (xmlNode *node, char const *name, gboolean default_val) { xmlChar *content; gboolean res; node = gup_gnm_attr_get (node, name); if (node == NULL) return default_val; content = xmlNodeGetContent (node); if (content == NULL) return TRUE; /* == true */ res = guppi_string2boolean (content); xmlFree (content); return res; } int gup_gnm_attr_get_int (xmlNode *node, char const *name, int default_val) { xmlChar *content; char *end; int res; node = gup_gnm_attr_get (node, name); if (node == NULL) return default_val; content = xmlNodeGetContent (node); g_return_val_if_fail (content != NULL, default_val); errno = 0; /* strto(ld) sets errno, but does not clear it. */ res = strtol (content, &end, 10); xmlFree (content); g_return_val_if_fail (errno != ERANGE, default_val); g_return_val_if_fail ((char *)content != end, default_val); return res; } double gup_gnm_attr_get_double (xmlNode *node, char const *name, double default_val) { xmlChar *content; char *end; double res; node = gup_gnm_attr_get (node, name); if (node == NULL) return default_val; content = xmlNodeGetContent (node); g_return_val_if_fail (content != NULL, default_val); errno = 0; /* strto(ld) sets errno, but does not clear it. */ res = strtod (content, &end); xmlFree (content); g_return_val_if_fail (errno != ERANGE, default_val); g_return_val_if_fail ((char *)content != end, default_val); return res; } guint32 gup_gnm_attr_get_color (xmlNode *node, char const *name, guint32 default_val) { xmlChar *content; guint32 res = default_val; int r, g, b; node = gup_gnm_attr_get (node, name); if (node == NULL) return default_val; content = xmlNodeGetContent (node); g_return_val_if_fail (content != NULL, default_val); if (sscanf (content, "%X:%X:%X", &r, &g, &b) == 3) res = RGB_TO_RGBA(RGB_TO_UINT(r,g,b) ,0xff); xmlFree (content); return res; } GuppiMarker gup_gnm_attr_get_marker (xmlNode *node, char const *name, GuppiMarker default_val) { xmlChar *content; guint32 res; node = gup_gnm_attr_get (node, name); if (node == NULL) return default_val; content = xmlNodeGetContent (node); g_return_val_if_fail (content != NULL, default_val); res = guppi_str2marker (content); xmlFree (content); g_return_val_if_fail (res != GUPPI_MARKER_UNKNOWN, default_val); return res; }