/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/* vim: set sw=8: */
/*
* guppi-gnumeric-config-guru.c: Manage
*
* Copyright (C) 2001 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-data-guru.h"
#include "guppi-gnumeric-config-guru.h"
#include "guppi-gnumeric-manager.h"
#include "guppi-gnumeric-view.h"
#include "guppi-gnumeric-xml.h"
#include <guppi-memory.h>
#include <gal/util/e-xml-utils.h>
struct _GupGnmDataGuru {
GupGnmConfigGuru parent;
GupGnmView view;
};
typedef struct {
GupGnmConfigGuruClass parent_class;
POA_GUPPI_GNUMERIC_DATA_GURU(epv) epv;
} GupGnmDataGuruClass;
#define GUP_GNM_DATA_GURU_CLASS(k) (GTK_CHECK_CLASS_CAST((k), GUP_GNM_DATA_GURU_TYPE, GupGnmDataGuruClass))
#define IS_GUP_GNM_DATA_GURU_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), GUP_GNM_DATA_GURU_TYPE))
static BonoboControlClass *gup_gnm_data_guru_parent_class = NULL;
static GNOME_Gnumeric_Buffer *
impl_get_spec (PortableServer_Servant servant, CORBA_Environment *ev)
{
GupGnmConfigGuru *cguru = gup_gnm_config_guru_from_servant (servant);
GupGnmGraph *graph = gup_gnm_config_guru_get_graph (cguru);
GNOME_Gnumeric_Buffer *spec;
xmlChar *mem = NULL;
int size = 0;
if (graph != NULL)
xmlDocDumpMemory (graph->spec, &mem, &size);
spec = GNOME_Gnumeric_Buffer__alloc ();
spec->_length = spec->_maximum = size;
spec->_buffer = CORBA_sequence_CORBA_octet_allocbuf(size);
spec->_release = CORBA_TRUE;
memcpy (spec->_buffer, mem, size);
xmlFree (mem);
return spec;
}
static void
impl_seriesSetDimension (PortableServer_Servant servant,
const GNOME_Gnumeric_SeriesID seriesID,
const CORBA_char *dim,
const GNOME_Gnumeric_VectorID vectorID,
CORBA_Environment *ev)
{
GupGnmConfigGuru *cguru = gup_gnm_config_guru_from_servant (servant);
GupGnmGraph *graph = gup_gnm_config_guru_get_graph (cguru);
g_return_if_fail (graph != NULL);
ggd(5, printf ("seriesSetDimension guru == %p\n", cguru));
if (gup_gnm_graph_set_series_dim (graph, seriesID, dim, vectorID))
gup_gnm_graph_regenerate_plots (graph);
}
static GNOME_Gnumeric_PlotID
impl_plotAdd (PortableServer_Servant servant,
CORBA_Environment *ev)
{
GupGnmConfigGuru *cguru = gup_gnm_config_guru_from_servant (servant);
GupGnmGraph *graph = gup_gnm_config_guru_get_graph (cguru);
g_return_val_if_fail (graph != NULL, -1);
ggd(5, printf ("plotAdd data-guru == %p\n", cguru));
return -1;
}
static void
impl_plotDelete (PortableServer_Servant servant,
const GNOME_Gnumeric_PlotID plot,
CORBA_Environment *ev)
{
GupGnmConfigGuru *cguru = gup_gnm_config_guru_from_servant (servant);
GupGnmGraph *graph = gup_gnm_config_guru_get_graph (cguru);
g_return_if_fail (graph != NULL);
ggd(5, printf ("plotDelete data-guru == %p\n", cguru));
}
typedef struct {
GNOME_Gnumeric_SeriesID max;
xmlNode *sibling;
} SeriesAddClosure;
static gboolean
cb_find_max_index (GupGnmGraph *graph,
xmlNode *plot, xmlNode *series,
gpointer user)
{
SeriesAddClosure *closure = user;
int ID = gup_gnm_series_get_id (series);
if (closure->max < ID)
closure->max = ID;
if (closure->sibling == NULL)
closure->sibling = series;
return FALSE;
}
static GNOME_Gnumeric_SeriesID
impl_seriesAdd (PortableServer_Servant servant,
const GNOME_Gnumeric_PlotID plotID,
CORBA_Environment *ev)
{
GupGnmConfigGuru *cguru = gup_gnm_config_guru_from_servant (servant);
GupGnmGraph *graph = gup_gnm_config_guru_get_graph (cguru);
xmlNode *data, *plot, *series;
SeriesAddClosure user;
g_return_val_if_fail (graph != NULL, -1);
ggd(5, printf ("seriesAdd data-guru == %p\n", cguru));
plot = gup_gnm_graph_get_plot (graph, plotID);
if (plot == NULL)
return -1;
data = e_xml_get_child_by_name (plot, "Data");
if (data == NULL)
return -1;
user.max = -1;
user.sibling = NULL;
gup_gnm_graph_foreach_series (graph, cb_find_max_index, &user);
user.max++;
series = xmlNewChild (data, data->ns, "Series", NULL);
e_xml_set_integer_prop_by_name (series, "index", user.max);
/* series is blank, no need to regenerate, but we should add markup */
if (user.sibling != NULL) {
GupGnmPlotDescriptor const *descriptor = gup_gnm_plot_get_descriptor (plot);
if (descriptor != NULL) {
int i = 0;
for (i = 0; descriptor->spec [i].display_name != NULL ; i++)
if (descriptor->spec [i].shared) {
xmlNode *sibling = gup_gnm_series_get_dimension (user.sibling,
descriptor->spec [i].dim_name);
if (sibling != NULL)
xmlAddChild (series, xmlCopyNode (sibling, TRUE));
}
} else {
g_warning ("Unkown plot type");
}
}
gup_gnm_graph_markup_spec (graph);
return user.max;
}
static gboolean
cb_series_delete (GupGnmGraph *graph,
xmlNode *plot, xmlNode *series,
gpointer user)
{
int targetID = GPOINTER_TO_INT (user);
int ID = gup_gnm_series_get_id (series);
if (targetID == ID) {
xmlUnlinkNode (series);
xmlFreeNode (series);
gup_gnm_graph_markup_spec (graph);
gup_gnm_graph_regenerate_plots (graph);
return TRUE;
}
return FALSE;
}
static void
impl_seriesDelete (PortableServer_Servant servant,
const GNOME_Gnumeric_SeriesID seriesID,
CORBA_Environment *ev)
{
GupGnmConfigGuru *cguru = gup_gnm_config_guru_from_servant (servant);
GupGnmGraph *graph = gup_gnm_config_guru_get_graph (cguru);
g_return_if_fail (graph != NULL);
ggd(5, printf ("seriesDelete data-guru == %p\n", cguru));
gup_gnm_graph_foreach_series (graph, cb_series_delete,
GINT_TO_POINTER (seriesID));
}
static void
gup_gnm_data_guru_destroy (GtkObject *obj)
{
GupGnmDataGuru *dguru = GUP_GNM_DATA_GURU (obj);
ggd (1, printf ("Destroy data guru %p \n", dguru););
GTK_OBJECT_CLASS (gup_gnm_data_guru_parent_class)->destroy (obj);
}
static void
gup_gnm_data_guru_class_init (GupGnmDataGuruClass *klass)
{
GtkObjectClass *object_class = (GtkObjectClass *) klass;
POA_GUPPI_GNUMERIC_DATA_GURU(epv) *epv = &klass->epv;
gup_gnm_data_guru_parent_class = gtk_type_class (gup_gnm_config_guru_get_type ());
object_class->destroy = gup_gnm_data_guru_destroy;
epv->seriesSetDimension = impl_seriesSetDimension;
epv->_get_spec = impl_get_spec;
epv->plotAdd = impl_plotAdd;
epv->plotDelete = impl_plotDelete;
epv->seriesAdd = impl_seriesAdd;
epv->seriesDelete = impl_seriesDelete;
}
GtkType
gup_gnm_data_guru_get_type (void)
{
static GtkType type = 0;
if (!type) {
GtkTypeInfo info = {
"GupGnmDataGuru",
sizeof (GupGnmDataGuru),
sizeof (GupGnmDataGuruClass),
(GtkClassInitFunc) gup_gnm_data_guru_class_init,
(GtkObjectInitFunc) NULL,
NULL, /* reserved 1 */
NULL, /* reserved 2 */
(GtkClassInitFunc) NULL
};
type = bonobo_x_type_unique (
GUP_GNM_CONFIG_GURU_TYPE,
POA_GUPPI_GNUMERIC_DATA_GURU(init),
POA_GUPPI_GNUMERIC_DATA_GURU(fini),
GTK_STRUCT_OFFSET (GupGnmDataGuruClass, epv),
&info);
}
return type;
}
GupGnmConfigGuru *
gup_gnm_data_guru_new (GupGnmGraph *graph)
{
GupGnmDataGuru *dguru = guppi_type_new (GUP_GNM_DATA_GURU_TYPE);
ggd(5, printf ("gup_gnm_data_guru_new == %p\n", dguru));
gup_gnm_view_construct (&dguru->view, graph);
return gup_gnm_config_guru_construct (GUP_GNM_CONFIG_GURU (dguru),
graph, GTK_WIDGET (dguru->view.canvas));
}
syntax highlighted by Code2HTML, v. 0.9.1