/* -*- 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 #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 #include 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)); }