/* -*- 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 <config.h>
#include "guppi-gnumeric-xml.h"
#include "guppi-gnumeric-graph.h"
#include "guppi-gnumeric-manager.h"
#include "guppi-gnumeric-vector.h"
#include <guppi-string.h>
#include <guppi-rgb.h>
#include <gal/util/e-xml-utils.h>
#include <gnome-xml/xmlmemory.h>
#include <errno.h>
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; /* <foo/> == <foo>true</foo> */
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;
}
syntax highlighted by Code2HTML, v. 0.9.1