/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* vim: set sw=8: */ /* * guppi-gnumeric-manger.c: * * Copyright (C) 2000-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-manager.h" #include "guppi-gnumeric-version.h" #include "guppi-gnumeric-vector.h" #include "guppi-gnumeric-view.h" #include "guppi-gnumeric-bonobo-view.h" #include "guppi-gnumeric-type-selector.h" #include "guppi-gnumeric-data-guru.h" #include "guppi-gnumeric-format-guru.h" #include #include #include #include #include #include #include #include typedef struct { BonoboEmbeddableClass parent; POA_GUPPI_GNUMERIC_MANAGER(epv) epv; } GupGnmManagerClass; #define GUP_GNM_MANAGER_CLASS(k) (GTK_CHECK_CLASS_CAST((k), GUP_GNM_MANAGER_TYPE, GupGnmManagerClass)) #define IS_GUP_GNM_MANAGER_CLASS(k) (GTK_CHECK_CLASS_TYPE ((k), GUP_GNM_MANAGER_TYPE)) /*************************************************************************/ static void gup_gnm_manager_clear_arrangement (GupGnmManager *manager) { if (manager->data_ids != NULL) { guppi_free (manager->data_ids); manager->data_ids = NULL; manager->header_ids = NULL; manager->arrangement_len = -1; } } static void gup_gnm_manager_add_vector (GupGnmManager *manager, GupGnmVector *vector) { int id; g_return_if_fail (IS_GUP_GNM_MANAGER (manager)); g_return_if_fail (IS_GUP_GNM_VECTOR (vector)); gup_gnm_manager_clear_arrangement (manager); id = gup_gnm_vector_id_get (vector); if (manager->vectors->len <= id) g_ptr_array_set_size (manager->vectors, id+1); g_ptr_array_index (manager->vectors, id) = vector; } GupGnmVector * gup_gnm_manager_get_vector (GupGnmManager const *manager, unsigned id) { g_return_val_if_fail (IS_GUP_GNM_MANAGER(manager), NULL); g_return_val_if_fail (manager->vectors != NULL, NULL); g_return_val_if_fail (manager->vectors->len > id, NULL); return g_ptr_array_index (manager->vectors, id); } static inline GupGnmManager * gup_gnm_manager_from_servant (PortableServer_Servant servant) { return GUP_GNM_MANAGER (bonobo_object_from_servant (servant)); } static Bonobo_Control impl_configure (PortableServer_Servant servant, const CORBA_char *type, CORBA_Environment *ev) { GupGnmManager *manager = gup_gnm_manager_from_servant (servant); GupGnmConfigGuru *cguru = NULL; ggd(0, printf ("Guppi : configure %s\n", type)); gup_gnm_graph_set_spec (&manager->gurus, manager->graph.spec, TRUE); if (!strcmp (type, "DataGuru")) cguru = gup_gnm_data_guru_new (&manager->gurus); else if (!strcmp (type, "TypeSelector")) cguru = gup_gnm_type_selector_new (&manager->gurus); else if (!strcmp (type, "FormatGuru")) cguru = gup_gnm_format_guru_new (&manager->gurus); if (cguru == NULL) return CORBA_OBJECT_NIL; return CORBA_Object_duplicate (BONOBO_OBJREF (cguru), ev); } static GNOME_Gnumeric_Buffer * impl_get_spec (PortableServer_Servant servant, CORBA_Environment *ev) { GupGnmManager *manager = gup_gnm_manager_from_servant (servant); GNOME_Gnumeric_Buffer *spec; xmlChar *mem; int size; xmlDocDumpMemory (manager->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_set_spec (PortableServer_Servant servant, GNOME_Gnumeric_Buffer const *spec, CORBA_Environment * ev) { GupGnmManager *manager = gup_gnm_manager_from_servant (servant); xmlParserCtxtPtr pctxt; ggd (1, puts ("Guppi : import spec");); /* A limit in libxml */ g_return_if_fail (spec->_length >= 4); pctxt = xmlCreatePushParserCtxt (NULL, NULL, spec->_buffer, spec->_length, NULL); xmlParseChunk (pctxt, "", 0, TRUE); gup_gnm_graph_set_spec (&manager->graph, pctxt->myDoc, FALSE); xmlFreeParserCtxt (pctxt); } static GNOME_Gnumeric_Scalar_Vector impl_addVector (PortableServer_Servant servant, const GNOME_Gnumeric_VectorSelection subscriber, const GNOME_Gnumeric_VectorType type, const GNOME_Gnumeric_VectorID id, const CORBA_char *default_fmt, CORBA_Environment *ev) { GupGnmManager *manager = gup_gnm_manager_from_servant (servant); GupGnmVector *vector; ggd(5, printf ("addVector manager == %p, type = %d, id = %d\n", manager, type, id)); vector = gup_gnm_vector_new (subscriber, type, id); if (vector == NULL) return CORBA_OBJECT_NIL; gup_gnm_manager_add_vector (manager, vector); return gup_gnm_vector_servant_get (vector); } static void impl_clearVectors (PortableServer_Servant servant, CORBA_Environment * ev) { GupGnmManager *manager = gup_gnm_manager_from_servant (servant); ggd(5, printf ("clearVectors manager == %p\n", manager)); } static void impl_arrangeVectors (PortableServer_Servant servant, GNOME_Gnumeric_VectorIDs const * data, GNOME_Gnumeric_VectorIDs const * optional_headers, CORBA_Environment * ev) { GupGnmManager *manager = gup_gnm_manager_from_servant (servant); unsigned i; ggd(5, printf ("arrangeVectors manager == %p\n", manager)); gup_gnm_manager_clear_arrangement (manager); manager->arrangement_len = data->_length; manager->data_ids = guppi_new (int, manager->arrangement_len *2); manager->header_ids = manager->data_ids + manager->arrangement_len; for (i = 0 ; i < manager->arrangement_len ; i++) { manager->data_ids[i] = data->_buffer[i]; manager->header_ids[i] = optional_headers->_buffer[i]; } gup_gnm_graph_generate_series (&manager->graph); } static GtkObjectClass *gup_gnm_manager_parent_class = NULL; static void gup_gnm_manager_destroy (GtkObject *obj) { GupGnmManager *manager = GUP_GNM_MANAGER (obj); ggd(2, puts ("GUPPI : GupGnmManager destroyed")); gup_gnm_graph_release (&manager->graph); gup_gnm_graph_release (&manager->gurus); if (manager->vectors != NULL) { int i; i = manager->vectors->len; while (i-- > 0) { GupGnmVector *vector = g_ptr_array_index (manager->vectors, i); if (vector != NULL) guppi_unref (GTK_OBJECT (vector)); } g_ptr_array_free (manager->vectors, TRUE); manager->vectors = NULL; } if (gup_gnm_manager_parent_class->destroy) gup_gnm_manager_parent_class->destroy (obj); } static void gup_gnm_manager_class_init (GupGnmManagerClass *klass) { GtkObjectClass *object_class = (GtkObjectClass *) klass; POA_GUPPI_GNUMERIC_MANAGER(epv) *epv = &klass->epv; object_class->destroy = gup_gnm_manager_destroy; gup_gnm_manager_parent_class = gtk_type_class (BONOBO_EMBEDDABLE_TYPE); epv->configure = impl_configure; epv->_get_spec = impl_get_spec; epv->_set_spec = impl_set_spec; epv->addVector = impl_addVector; epv->clearVectors = impl_clearVectors; epv->arrangeVectors = impl_arrangeVectors; } static void gup_gnm_manager_init (GtkObject *object) { GupGnmManager *manager = GUP_GNM_MANAGER (object); manager->vectors = g_ptr_array_new (); manager->data_ids = NULL; manager->header_ids = NULL; manager->arrangement_len = -1; gup_gnm_graph_construct (&manager->graph, manager); gup_gnm_graph_construct (&manager->gurus, manager); } GtkType gup_gnm_manager_get_type (void) { static GtkType type = 0; if (!type) { GtkTypeInfo info = { "GupGnmManager", sizeof (GupGnmManager), sizeof (GupGnmManagerClass), (GtkClassInitFunc) gup_gnm_manager_class_init, (GtkObjectInitFunc) gup_gnm_manager_init, NULL, /* reserved 1 */ NULL, /* reserved 2 */ (GtkClassInitFunc) NULL }; type = bonobo_x_type_unique ( BONOBO_EMBEDDABLE_TYPE, POA_GUPPI_GNUMERIC_MANAGER(init), POA_GUPPI_GNUMERIC_MANAGER(fini), GTK_STRUCT_OFFSET (GupGnmManagerClass, epv), &info); } return type; } static void gup_gnm_manager_print (GnomePrintContext * ctx, double width, double height, Bonobo_PrintScissor const *scissor, gpointer graph) { GuppiRootGroupView *plot = gup_gnm_graph_get_view (graph); guppi_element_view_print_to_bbox (GUPPI_ELEMENT_VIEW (plot), ctx, 0, 0, width, height); } GupGnmManager * gup_gnm_manager_new (void) { GupGnmManager *manager; BonoboPrint *print; manager = guppi_type_new (GUP_GNM_MANAGER_TYPE); bonobo_embeddable_construct (BONOBO_EMBEDDABLE (manager), gup_gnm_bonobo_view_factory, NULL); ggd(2, printf ("Manager::new() == %p\n", manager)); /* Register the Bonobo::Print interface */ print = bonobo_print_new (gup_gnm_manager_print, &manager->graph); if (!print) { bonobo_object_unref (BONOBO_OBJECT (manager)); return NULL; } bonobo_object_add_interface (BONOBO_OBJECT (manager), BONOBO_OBJECT (print)); return manager; }