/* This is -*- C -*- */
/* vim: set sw=2: */
/* $Id: guppi-attribute-widget.c,v 1.1 2001/11/16 17:12:57 trow Exp $ */
/*
* guppi-attribute-widget.c
*
* Copyright (C) 2001 The Free Software Foundation
*
* Developed by Jon Trowbridge <trow@gnu.org>
*
* 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-attribute-widget.h"
#include <gtk/gtksignal.h>
#include <guppi-memory.h>
static GtkObjectClass *parent_class = NULL;
enum {
BAG_TO_WIDGET,
LAST_SIGNAL
};
static guint guppi_attribute_widget_signals[LAST_SIGNAL] = { 0 };
struct _GuppiAttributeWidgetPrivate {
gchar *key;
GuppiAttributeFlavor flavor;
gint set_lock;
GuppiAttributeBag *bag;
guint bag_changed_tag;
};
static void
guppi_attribute_widget_destroy (GtkObject *obj)
{
if (parent_class->destroy)
parent_class->destroy (obj);
}
static void
guppi_attribute_widget_finalize (GtkObject *obj)
{
GuppiAttributeWidget *x = GUPPI_ATTRIBUTE_WIDGET(obj);
guppi_free (x->priv->key);
if (x->priv->bag_changed_tag && x->priv->bag) {
gtk_signal_disconnect (GTK_OBJECT (x->priv->bag), x->priv->bag_changed_tag);
}
guppi_unref (x->priv->bag);
g_free (x->priv);
x->priv = NULL;
guppi_finalized (obj);
if (parent_class->finalize)
parent_class->finalize (obj);
}
static void
guppi_attribute_widget_class_init (GuppiAttributeWidgetClass *klass)
{
GtkObjectClass *object_class = (GtkObjectClass *)klass;
parent_class = gtk_type_class (GTK_TYPE_TABLE);
object_class->destroy = guppi_attribute_widget_destroy;
object_class->finalize = guppi_attribute_widget_finalize;
guppi_attribute_widget_signals[BAG_TO_WIDGET] =
gtk_signal_new ("bag_to_widget",
GTK_RUN_FIRST,
object_class->type,
GTK_SIGNAL_OFFSET (GuppiAttributeWidgetClass, bag_to_widget),
gtk_marshal_NONE__NONE, GTK_TYPE_NONE, 0);
gtk_object_class_add_signals (object_class, guppi_attribute_widget_signals, LAST_SIGNAL);
}
static void
guppi_attribute_widget_init (GuppiAttributeWidget *obj)
{
GuppiAttributeWidgetPrivate *p = g_new0 (GuppiAttributeWidgetPrivate, 1);
obj->priv = p;
}
GtkType
guppi_attribute_widget_get_type (void)
{
static GtkType guppi_attribute_widget_type = 0;
if (!guppi_attribute_widget_type) {
static const GtkTypeInfo guppi_attribute_widget_info = {
"GuppiAttributeWidget",
sizeof (GuppiAttributeWidget),
sizeof (GuppiAttributeWidgetClass),
(GtkClassInitFunc)guppi_attribute_widget_class_init,
(GtkObjectInitFunc)guppi_attribute_widget_init,
NULL, NULL, (GtkClassInitFunc)NULL
};
guppi_attribute_widget_type = gtk_type_unique (GTK_TYPE_TABLE, &guppi_attribute_widget_info);
}
return guppi_attribute_widget_type;
}
static void
emit_bag_to_widget (GuppiAttributeWidget *gaw)
{
gtk_signal_emit (GTK_OBJECT (gaw), guppi_attribute_widget_signals[BAG_TO_WIDGET]);
}
GtkWidget *
guppi_attribute_widget_new (GuppiAttributeFlavor flavor, const gchar *key)
{
GtkWidget *w;
g_return_val_if_fail (key && *key, NULL);
w = GTK_WIDGET (guppi_type_new (guppi_attribute_widget_get_type ()));
guppi_attribute_widget_construct (GUPPI_ATTRIBUTE_WIDGET (w), flavor, key);
return w;
}
void
guppi_attribute_widget_construct (GuppiAttributeWidget *gaw, GuppiAttributeFlavor flavor, const gchar *key)
{
g_return_if_fail (GUPPI_IS_ATTRIBUTE_WIDGET (gaw));
g_return_if_fail (key != NULL);
g_return_if_fail (gaw->priv->key == NULL);
gaw->priv->key = guppi_strdup (key);
gaw->priv->flavor = flavor;
}
static void
bag_changed_cb (GuppiAttributeBag *bag, const gchar *key, gpointer closure)
{
GuppiAttributeWidget *gaw = GUPPI_ATTRIBUTE_WIDGET (closure);
g_assert (gaw != NULL);
if (gaw->priv->set_lock > 0)
return;
if (strcmp (key, gaw->priv->key))
return;
emit_bag_to_widget (gaw);
}
void
guppi_attribute_widget_attach_bag (GuppiAttributeWidget *gaw, GuppiAttributeBag *bag)
{
GuppiAttributeFlavor bag_flavor;
g_return_if_fail (GUPPI_IS_ATTRIBUTE_WIDGET (gaw));
g_return_if_fail (GUPPI_IS_ATTRIBUTE_BAG (bag));
g_return_if_fail (gaw->priv->bag == NULL);
if (! guppi_attribute_bag_contains (bag, gaw->priv->key)) {
g_warning ("Bag does not contain key '%s'", gaw->priv->key);
return;
}
bag_flavor = guppi_attribute_bag_get_flavor (bag, gaw->priv->key);
if (bag_flavor != gaw->priv->flavor) {
g_message ("%d %d", bag_flavor, gaw->priv->flavor);
g_warning ("Flavor mismatch on key '%s'", gaw->priv->key);
return;
}
gaw->priv->bag = bag;
guppi_ref (bag);
gaw->priv->bag_changed_tag = gtk_signal_connect (GTK_OBJECT (bag),
"changed",
GTK_SIGNAL_FUNC (bag_changed_cb),
gaw);
emit_bag_to_widget (gaw);
}
void
guppi_attribute_widget_recursively_attach_bag (GtkWidget *w, GuppiAttributeBag *bag)
{
g_return_if_fail (GTK_IS_WIDGET (w));
g_return_if_fail (GUPPI_IS_ATTRIBUTE_BAG (bag));
if (GUPPI_IS_ATTRIBUTE_WIDGET (w)) {
guppi_attribute_widget_attach_bag (GUPPI_ATTRIBUTE_WIDGET (w), bag);
} else if (GTK_IS_CONTAINER (w)) {
gtk_container_foreach (GTK_CONTAINER (w),
(GtkCallback) guppi_attribute_widget_recursively_attach_bag,
bag);
}
}
void
guppi_attribute_widget_bag_get (GuppiAttributeWidget *gaw, const gchar *subkey, gpointer dest)
{
gchar *key = NULL;
g_return_if_fail (GUPPI_IS_ATTRIBUTE_WIDGET (gaw));
g_return_if_fail (dest != NULL);
if (gaw->priv->bag == NULL) {
g_warning ("Getting without a bag.");
return;
}
if (subkey && *subkey) {
key = guppi_strdup_printf ("%s::%s", gaw->priv->key, subkey);
}
guppi_attribute_bag_get1 (gaw->priv->bag, key ? key : gaw->priv->key, dest);
guppi_free (key);
}
void
guppi_attribute_widget_bag_set (GuppiAttributeWidget *gaw, const gchar *subkey, ...)
{
gchar *key = NULL;
va_list varargs;
g_return_if_fail (GUPPI_IS_ATTRIBUTE_WIDGET (gaw));
if (gaw->priv->bag == NULL) {
g_warning ("Setting without a bag.");
return;
}
if (subkey && *subkey) {
key = guppi_strdup_printf ("%s::%s", gaw->priv->key, subkey);
}
va_start (varargs, subkey);
++gaw->priv->set_lock;
guppi_attribute_bag_vset1 (gaw->priv->bag, key ? key : gaw->priv->key, &varargs);
--gaw->priv->set_lock;
va_end (varargs);
guppi_free (key);
}
syntax highlighted by Code2HTML, v. 0.9.1