/* This is -*- C -*- */
/* $Id: guppi-struct-core.c,v 1.1 2002/01/08 06:29:00 trow Exp $ */
/*
* guppi-struct-core-impl.c
*
* Copyright (C) 2000 EMC Capital Management, Inc.
* Copyright (C) 2001 The Free Software Foundation
*
* Developed by Jon Trowbridge <trow@gnu.org> and
* Havoc Pennington <hp@pobox.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-struct-core.h"
#include <libgnome/gnome-defs.h>
#include <libgnome/gnome-config.h>
#include <libgnome/gnome-i18n.h>
#include <guppi-convenient.h>
#include <guppi-memory.h>
static GtkObjectClass *parent_class = NULL;
typedef struct _GuppiStructField GuppiStructField;
struct _GuppiStructField {
GtkType type;
GuppiData *data;
};
static void
hash_free (gpointer key, gpointer val, gpointer user_data)
{
GuppiStructField *f = (GuppiStructField *) val;
guppi_unref0 (f->data);
guppi_free (key);
guppi_free (val);
}
static void
guppi_struct_core_destroy (GtkObject *obj)
{
GuppiStructCore *core = GUPPI_STRUCT_CORE (obj);
if (parent_class->destroy)
parent_class->destroy (obj);
g_hash_table_foreach (core->fields, hash_free, NULL);
g_hash_table_destroy (core->fields);
g_list_free (core->field_names);
core->fields = NULL;
}
static void
guppi_struct_core_finalize (GtkObject *obj)
{
if (parent_class->finalize)
parent_class->finalize (obj);
}
/***************************************************************************/
static gboolean
v_struct_add_field (GuppiStruct *str, const gchar *field, GtkType t)
{
GuppiStructCore *core = GUPPI_STRUCT_CORE (str);
GuppiStructField *p;
gchar *dup_field;
p = (GuppiStructField *) g_hash_table_lookup (core->fields, field);
if (p != NULL)
return FALSE;
++core->field_count;
dup_field = guppi_strdup (field);
core->field_names = g_list_append (core->field_names, dup_field);
p = guppi_new (GuppiStructField, 1);
p->type = t;
p->data = NULL;
g_hash_table_insert (core->fields, dup_field, p);
return TRUE;
}
static GtkType
v_struct_field_type (GuppiStruct *str, const gchar *field)
{
GuppiStructCore *core = GUPPI_STRUCT_CORE (str);
GuppiStructField *p;
p = (GuppiStructField *) g_hash_table_lookup (core->fields, field);
if (p == NULL)
return (GtkType) 0;
return p->type;
}
static GuppiData *
v_struct_get (GuppiStruct *str, const gchar *field)
{
GuppiStructCore *core = GUPPI_STRUCT_CORE (str);
GuppiStructField *p;
p = (GuppiStructField *) g_hash_table_lookup (core->fields, field);
return p ? p->data : NULL;
}
static gboolean
v_struct_set (GuppiStruct *str, const gchar *field, GuppiData *data)
{
GuppiStructCore *core = GUPPI_STRUCT_CORE (str);
GuppiStructField *p;
p = (GuppiStructField *) g_hash_table_lookup (core->fields, field);
if (p == NULL)
return FALSE;
if (p->type && !gtk_type_is_a (GTK_OBJECT_TYPE (data), p->type))
return FALSE;
guppi_refcounting_assign (p->data, data);
return TRUE;
}
static void
v_struct_foreach (GuppiStruct *str, GuppiStructFn fn, gpointer user_data)
{
GuppiStructCore *core = GUPPI_STRUCT_CORE (str);
GList *iter = core->field_names;
GuppiData *d;
/* By doing this rather than using the g_hash_table_foreach function,
we can make sure that our function gets called in the same order
as the objects have been added to the struct. */
while (iter) {
d = v_struct_get (str, (gchar *)iter->data);
fn ((gchar *)iter->data, d, user_data);
iter = g_list_next (iter);
}
}
/***************************************************************************/
static void
guppi_struct_core_class_init (GuppiStructCoreClass *klass)
{
GtkObjectClass *object_class = (GtkObjectClass *) klass;
GuppiDataClass *data_class = GUPPI_DATA_CLASS (klass);
GuppiStructClass *struct_class = GUPPI_STRUCT_CLASS (klass);
parent_class = gtk_type_class (GUPPI_TYPE_STRUCT);
object_class->destroy = guppi_struct_core_destroy;
object_class->finalize = guppi_struct_core_finalize;
struct_class->add_field = v_struct_add_field;
struct_class->field_type = v_struct_field_type;
struct_class->get = v_struct_get;
struct_class->set = v_struct_set;
struct_class->foreach = v_struct_foreach;
data_class->is_leaf_type = TRUE;
}
static void
guppi_struct_core_init (GuppiStructCore *obj)
{
obj->fields = g_hash_table_new (g_str_hash, g_str_equal);
}
GtkType guppi_struct_core_get_type (void)
{
static GtkType guppi_struct_core_type = 0;
if (!guppi_struct_core_type) {
static const GtkTypeInfo guppi_struct_core_info = {
"GuppiStructCore",
sizeof (GuppiStructCore),
sizeof (GuppiStructCoreClass),
(GtkClassInitFunc) guppi_struct_core_class_init,
(GtkObjectInitFunc) guppi_struct_core_init,
NULL, NULL, (GtkClassInitFunc) NULL
};
guppi_struct_core_type =
gtk_type_unique (GUPPI_TYPE_STRUCT, &guppi_struct_core_info);
}
return guppi_struct_core_type;
}
/* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */
GuppiStruct *
guppi_struct_core_new (void)
{
return GUPPI_STRUCT (guppi_type_new (guppi_struct_core_get_type ()));
}
/* $Id: guppi-struct-core.c,v 1.1 2002/01/08 06:29:00 trow Exp $ */
syntax highlighted by Code2HTML, v. 0.9.1