/* -*- 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 <config.h>
#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 <guppi-root-group-item.h>
#include <guppi-seq-scalar.h>
#include <guppi-seq-date.h>
#include <guppi-seq-string.h>
#include <guppi-useful.h>
#include <guppi-marker.h>
#include <gnome-xml/parser.h>
#include <gal/util/e-xml-utils.h>
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;
}
syntax highlighted by Code2HTML, v. 0.9.1