/* This is -*- C -*- */ /* vim: set sw=2: */ /* $Id: guppi-config-model.c,v 1.2 2001/11/26 20:00:18 trow Exp $ */ /* * guppi-config-model.c * * Copyright (C) 2001 The Free Software Foundation * * Developed by Jon Trowbridge * * 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 #include #include #include "guppi-config-model.h" static GtkObjectClass *parent_class = NULL; enum { LAST_SIGNAL }; static guint guppi_config_model_signals[LAST_SIGNAL] = { 0 }; struct _GuppiConfigModelPrivate { GList *items; }; /* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */ typedef struct _ConfigItem ConfigItem; struct _ConfigItem { gchar *major_label; gchar *minor_label; GuppiConfigType type; GuppiAttributeBag *bag; GuppiConfigFn config_fn; gpointer config_closure; GtkDestroyNotify config_closure_destructor; }; static ConfigItem * config_item_new (void) { return guppi_new0 (ConfigItem, 1); } static void config_item_free (ConfigItem *ci) { if (ci == NULL) return; guppi_free (ci->major_label); guppi_free (ci->minor_label); guppi_unref (ci->bag); if (ci->config_closure_destructor) ci->config_closure_destructor (ci->config_closure); guppi_free (ci); } /* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */ static void guppi_config_model_finalize (GtkObject *obj) { GuppiConfigModel *x = GUPPI_CONFIG_MODEL(obj); g_list_foreach (x->priv->items, (GFunc) config_item_free, NULL); g_list_free (x->priv->items); g_free (x->priv); x->priv = NULL; guppi_finalized (obj); if (parent_class->finalize) parent_class->finalize (obj); } static void guppi_config_model_class_init (GuppiConfigModelClass *klass) { GtkObjectClass *object_class = (GtkObjectClass *)klass; parent_class = gtk_type_class (GTK_TYPE_OBJECT); object_class->finalize = guppi_config_model_finalize; #if 0 /* Signal definition template */ guppi_config_model_signals[CHANGED] = gtk_signal_new ("changed", GTK_RUN_FIRST, object_class->type, GTK_SIGNAL_OFFSET (GuppiConfigModelClass, changed), gtk_marshal_NONE__NONE, GTK_TYPE_NONE, 0); #endif gtk_object_class_add_signals (object_class, guppi_config_model_signals, LAST_SIGNAL); } static void guppi_config_model_init (GuppiConfigModel *obj) { obj->priv = g_new0 (GuppiConfigModelPrivate, 1); } GtkType guppi_config_model_get_type (void) { static GtkType guppi_config_model_type = 0; if (!guppi_config_model_type) { static const GtkTypeInfo guppi_config_model_info = { "GuppiConfigModel", sizeof (GuppiConfigModel), sizeof (GuppiConfigModelClass), (GtkClassInitFunc)guppi_config_model_class_init, (GtkObjectInitFunc)guppi_config_model_init, NULL, NULL, (GtkClassInitFunc)NULL }; guppi_config_model_type = gtk_type_unique (GTK_TYPE_OBJECT, &guppi_config_model_info); } return guppi_config_model_type; } GuppiConfigModel * guppi_config_model_new (void) { return GUPPI_CONFIG_MODEL (guppi_type_new (guppi_config_model_get_type ())); } void guppi_config_model_add (GuppiConfigModel *model, const gchar *major_label, const gchar *minor_label, GuppiConfigType type, GuppiAttributeBag *bag, GuppiConfigFn config_fn, gpointer config_closure, GtkDestroyNotify config_closure_destructor) { ConfigItem *ci; g_return_if_fail (GUPPI_IS_CONFIG_MODEL (model)); g_return_if_fail (major_label != NULL && minor_label != NULL); g_return_if_fail (bag == NULL || GUPPI_IS_ATTRIBUTE_BAG (bag)); ci = config_item_new (); ci->major_label = guppi_strdup (major_label); ci->minor_label = guppi_strdup (minor_label); ci->bag = bag; ci->type = type; ci->config_fn = config_fn; ci->config_closure = config_closure; ci->config_closure_destructor = config_closure_destructor; guppi_ref (ci->bag); model->priv->items = g_list_append (model->priv->items, ci); } /* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */ typedef struct _GladeInfo GladeInfo; struct _GladeInfo { gchar *filename; gchar *root; void (*glade_init) (GladeXML *, gpointer); gpointer glade_init_closure; GtkDestroyNotify glade_init_closure_destroy; }; static void glade_info_free (GladeInfo *info) { guppi_free (info->filename); guppi_free (info->root); if (info->glade_init_closure_destroy) info->glade_init_closure_destroy (info->glade_init_closure); guppi_free (info); } static GtkWidget * glade_info_cb (gpointer closure) { GladeInfo *info = closure; GladeXML *glade; GtkWidget *w; glade = glade_xml_new (guppi_glade_path (info->filename), info->root); if (glade == NULL) return NULL; if (info->glade_init) info->glade_init (glade, info->glade_init_closure); w = glade_xml_get_widget (glade, info->root); gtk_object_unref (GTK_OBJECT (glade)); return w; } void guppi_config_model_add_glade_file (GuppiConfigModel *model, const gchar *major_label, const gchar *minor_label, GuppiConfigType type, GuppiAttributeBag *bag, const gchar *filename, const gchar *root, void (*glade_init) (GladeXML *, gpointer), gpointer glade_init_closure, GtkDestroyNotify glade_init_closure_destroy) { GladeInfo *info; g_return_if_fail (GUPPI_IS_CONFIG_MODEL (model)); g_return_if_fail (major_label != NULL && minor_label != NULL); g_return_if_fail (bag == NULL || GUPPI_IS_ATTRIBUTE_BAG (bag)); info = guppi_new0 (GladeInfo, 1); info->filename = guppi_strdup (filename); info->root = guppi_strdup (root); info->glade_init = glade_init; info->glade_init_closure = glade_init_closure; info->glade_init_closure_destroy = glade_init_closure_destroy; guppi_config_model_add (model, major_label, minor_label, type, bag, glade_info_cb, info, (GtkDestroyNotify) glade_info_free); } /* ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** ** */ void guppi_config_model_combine (GuppiConfigModel *dest, const gchar *major_label_override, GuppiConfigModel *src) { GList *iter; g_return_if_fail (GUPPI_IS_CONFIG_MODEL (dest)); if (src == NULL) return; g_return_if_fail (GUPPI_IS_CONFIG_MODEL (src)); for (iter = src->priv->items; iter != NULL; iter = g_list_next (iter)) { ConfigItem *ci = iter->data; if (major_label_override) { guppi_free (ci->major_label); ci->major_label = guppi_strdup (major_label_override); } dest->priv->items = g_list_append (dest->priv->items, ci); } g_list_free (src->priv->items); src->priv->items = NULL; } void guppi_config_model_foreach (GuppiConfigModel *model, GuppiConfigIteratorFn iter_fn, gpointer closure) { GList *iter; g_return_if_fail (GUPPI_IS_CONFIG_MODEL (model)); g_return_if_fail (iter_fn != NULL); for (iter = model->priv->items; iter != NULL; iter = g_list_next (iter)) { ConfigItem *ci = iter->data; GtkWidget *w = NULL; if (ci->config_fn) w = ci->config_fn (ci->config_closure); if (w && ci->bag) guppi_attribute_widget_recursively_attach_bag (w, ci->bag); iter_fn (ci->major_label, ci->minor_label, ci->type, w, closure); } }