summaryrefslogtreecommitdiff
path: root/tools/glade/glade/gnome/gnomecontrol.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/glade/glade/gnome/gnomecontrol.c')
-rw-r--r--tools/glade/glade/gnome/gnomecontrol.c757
1 files changed, 757 insertions, 0 deletions
diff --git a/tools/glade/glade/gnome/gnomecontrol.c b/tools/glade/glade/gnome/gnomecontrol.c
new file mode 100644
index 00000000..5744fda9
--- /dev/null
+++ b/tools/glade/glade/gnome/gnomecontrol.c
@@ -0,0 +1,757 @@
+/* Gtk+ User Interface Builder
+ * Copyright (C) 1998 Damon Chaplin
+ *
+ * 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.
+ */
+
+/*
+ * Glade only shows Bonobo controls which have a 'glade:show' attribute set
+ * to TRUE, e.g. with this in their .server file:
+ *
+ * <oaf_attribute name="glade:show" type="boolean" value="TRUE"/>
+ *
+ */
+
+#include <config.h>
+
+#include <gtk/gtkhbox.h>
+#include <gtk/gtklabel.h>
+#include <gtk/gtkmain.h>
+#include <gtk/gtkmenu.h>
+#include <gtk/gtkmenuitem.h>
+#include <gtk/gtkspinbutton.h>
+
+#include "../gb.h"
+#include "../palette.h"
+
+#include <bonobo.h>
+
+/* Include the 21x21 icon pixmap for this widget, to be used in the palette */
+#include "../graphics/gnome-control.xpm"
+
+/*
+ * This is the GbWidget struct for this widget (see ../gbwidget.h).
+ * It is initialized in the init() function at the end of this file
+ */
+static GbWidget gbwidget;
+
+/* This is the key we use to store a pointer to the bonobo widget's property
+ bag. */
+static gchar *GladePropertyBagKey = "GladePropertyBagKey";
+
+/* This is the Moniker property which stores the type of control. It is saved
+ in the XML. */
+const gchar *Moniker = "BonoboWidget::moniker";
+
+
+static GbWidget *control_get_gb_widget (const char *obj_id);
+
+
+/****************************************************************************
+ * This is the dummy GbWidget we put in the palette. It only contains a
+ * new() function to create Bonobo controls. We create a GbWidget for each
+ * type of control when needed, and it is that that contains functions to
+ * create/get/set properties.
+ ****************************************************************************/
+
+/* Columns in the GtkTreeView for selecting the type of control. */
+enum {
+ COL_OBJID,
+ COL_DESC,
+ COL_LAST
+};
+
+static GtkWidget *
+control_create (GbWidgetNewData * data, char *obj_id, Bonobo_UIContainer uic)
+{
+ GtkWidget *widget;
+ BonoboControlFrame *cf;
+ Bonobo_PropertyBag pb;
+
+ g_return_val_if_fail (obj_id != NULL, NULL);
+
+ widget = bonobo_widget_new_control (obj_id, uic);
+
+ g_return_val_if_fail (widget != NULL, NULL);
+ cf = bonobo_widget_get_control_frame (BONOBO_WIDGET (widget));
+
+ if (!cf) {
+ g_warning ("Control has no frame!");
+ gtk_widget_destroy (widget);
+
+ return NULL;
+ }
+
+ pb = bonobo_control_frame_get_control_property_bag (cf, NULL);
+
+ gtk_object_set_data (GTK_OBJECT (widget), GladePropertyBagKey, pb);
+ gtk_object_set_data (GTK_OBJECT (widget), Moniker, g_strdup (obj_id));
+
+ /* Make sure the GbWidget for this control is created & registered,
+ and set the real GbWidget for this control. */
+ data->widget_data->gbwidget = control_get_gb_widget (obj_id);
+
+ return widget;
+}
+
+static Bonobo_PropertyBag
+control_get_pb (GtkWidget *widget)
+{
+ return gtk_object_get_data (GTK_OBJECT (widget),
+ GladePropertyBagKey);
+}
+
+static Bonobo_UIContainer
+widget_get_uic (GtkWidget *widget)
+{
+ GtkWidget *top;
+
+ top = gtk_widget_get_toplevel (widget);
+
+ if (!BONOBO_IS_WINDOW (top))
+ return CORBA_OBJECT_NIL;
+
+ /* FIXME: Should we unref this somewhere? */
+ return (Bonobo_UIContainer) BONOBO_OBJREF (bonobo_window_get_ui_container (BONOBO_WINDOW (top)));
+}
+
+static void
+on_control_dialog_ok (GtkWidget *widget,
+ GbWidgetNewData *data)
+{
+ GtkTreeView *view;
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ GtkWidget *dialog;
+ GtkTreeSelection *selection;
+ char *moniker;
+ GtkWidget *new_widget;
+
+ dialog = gtk_widget_get_toplevel (widget);
+
+ view = g_object_get_data (G_OBJECT (dialog), "tree_view");
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
+ gtk_tree_selection_get_selected (selection, &model, &iter);
+ gtk_tree_model_get (model, &iter, COL_OBJID, &moniker, -1);
+
+ new_widget = control_create (data, moniker, widget_get_uic (data->parent));
+ if (new_widget)
+ {
+ gb_widget_initialize (new_widget, data);
+ data->callback (new_widget, data);
+ }
+ else
+ {
+ glade_util_show_message_box (_("Couldn't create the Bonobo control"),
+ NULL);
+ }
+
+ gtk_widget_destroy (dialog);
+}
+
+static void
+on_control_dialog_destroy (GtkWidget *widget,
+ GbWidgetNewData *data)
+{
+ gb_widget_free_new_data (data);
+ gtk_grab_remove (widget);
+}
+
+static GtkListStore *
+do_query (void)
+{
+ GtkListStore *store;
+ Bonobo_ServerInfoList *servers;
+#if 0
+ /* This is the old query, but too many components are not generally useful
+ and cause problems, so we are changing to an 'opt-in' query, where
+ we only include components that have a 'glade:show' property set to TRUE.
+ */
+ const char *query = "repo_ids.has('IDL:Bonobo/Control:1.0') AND NOT "
+ "repo_ids.has('IDL:GNOME/Vertigo/PanelAppletShell:1.0')";
+#else
+ const char *query = "glade:show";
+#endif
+ char *sort[] = { "description", NULL };
+ CORBA_Environment ev;
+ int i;
+
+ Bonobo_ServerInfo *serverinfo;
+ const char *desc;
+ GtkTreeIter iter;
+
+ store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
+
+ CORBA_exception_init (&ev);
+
+ servers = bonobo_activation_query (query, sort, &ev);
+ if (BONOBO_EX (&ev)) {
+ g_warning ("query failed: %s\n", ev._id);
+ CORBA_exception_free (&ev);
+ return store;
+ }
+ CORBA_exception_free (&ev);
+
+#if 0
+ g_print ("got %d servers.\n", servers ? servers->_length : 0);
+#endif
+
+ for (i = 0; i < servers->_length; i++) {
+ serverinfo = &servers->_buffer[i];
+
+ desc = bonobo_server_info_prop_lookup (serverinfo, "description", NULL);
+ if (!desc)
+ desc = bonobo_server_info_prop_lookup (serverinfo, "name", NULL);
+ if (!desc)
+ desc = serverinfo->iid;
+
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter,
+ COL_OBJID, serverinfo->iid,
+ COL_DESC, desc,
+ -1);
+ }
+
+ CORBA_free (servers);
+
+ return store;
+}
+
+static void
+on_list_selection_changed (GtkTreeSelection *selection, GtkDialog *dialog)
+{
+ gtk_dialog_set_response_sensitive (dialog, GTK_RESPONSE_OK,
+ gtk_tree_selection_get_selected (selection, NULL, NULL));
+}
+
+static void
+show_control_dialog (GbWidgetNewData *data)
+{
+ GtkWidget *dialog, *vbox, *label, *list, *scroll;
+ GtkListStore *store;
+ GtkCellRenderer *ren;
+
+ dialog = glade_util_create_dialog (_("New Bonobo Control"), data->parent,
+ GTK_SIGNAL_FUNC (on_control_dialog_ok),
+ data, &vbox);
+ g_object_set (G_OBJECT (dialog),
+ "resizable", TRUE,
+ "default-width", 400,
+ "default-height", 300,
+ NULL);
+ gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog),
+ GTK_RESPONSE_OK, FALSE);
+ g_signal_connect (dialog, "destroy",
+ G_CALLBACK (on_control_dialog_destroy), data);
+
+ label = gtk_label_new (_("Select a Bonobo Control"));
+ gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
+
+ scroll = g_object_new (GTK_TYPE_SCROLLED_WINDOW,
+ "hadjustment", NULL,
+ "vadjustment", NULL,
+ "shadow-type", GTK_SHADOW_ETCHED_IN,
+ "vscrollbar-policy", GTK_POLICY_AUTOMATIC,
+ "hscrollbar-policy", GTK_POLICY_AUTOMATIC,
+ NULL);
+ gtk_box_pack_start (GTK_BOX (vbox), scroll, TRUE, TRUE, 0);
+
+ store = do_query ();
+
+ list = g_object_new (GTK_TYPE_TREE_VIEW,
+ "model", store,
+ "headers-visible", FALSE,
+ NULL);
+ g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (list)),
+ "changed",
+ G_CALLBACK (on_list_selection_changed), dialog);
+
+ g_object_unref (store);
+
+ ren = gtk_cell_renderer_text_new ();
+
+#if 0
+ gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (list),
+ -1, _("OAFIID"), ren,
+ "text", COL_OBJID,
+ NULL);
+#endif
+ gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (list),
+ -1, _("Description"), ren,
+ "text", COL_DESC,
+ NULL);
+
+ gtk_container_add (GTK_CONTAINER (scroll), list);
+
+ g_object_set_data (G_OBJECT (dialog), "tree_view", list);
+
+ gtk_widget_show_all (dialog);
+ gtk_grab_add (dialog);
+}
+
+static GtkWidget *
+gb_bonobo_control_new (GbWidgetNewData * data)
+{
+ GtkWidget *new_widget;
+
+ if (data->action == GB_LOADING) {
+ char *moniker;
+
+ moniker = load_string (data->loading_data, Moniker);
+
+ new_widget = control_create (data, moniker, widget_get_uic (data->parent));
+
+ return new_widget;
+ } else {
+ show_control_dialog (data);
+ return NULL;
+ }
+}
+
+/*
+ * Initializes the GbWidget structure.
+ */
+GbWidget *
+gb_bonobo_control_init ()
+{
+ /* Initialise the GTK type */
+ volatile GtkType type;
+ type = BONOBO_TYPE_WIDGET;
+
+ gb_widget_init_struct (&gbwidget);
+
+ gbwidget.pixmap_struct = gnome_control_xpm;
+ gbwidget.tooltip = _("Bonobo Control");
+
+ gbwidget.gb_widget_new = gb_bonobo_control_new;
+
+ return &gbwidget;
+}
+
+
+/****************************************************************************
+ * This is the GbWidget that will be created for each type of control.
+ ****************************************************************************/
+
+/* We use the moniker to ensure the property names are unique in the property
+ editor. */
+static char *
+create_prop_name (const char *moniker, const char *txt)
+{
+ return g_strconcat (moniker, "::", txt, NULL);
+}
+
+/*
+ * Creates the components needed to edit the extra properties of this widget.
+ */
+static void
+gb_bonobo_control_create_properties (GtkWidget * widget, GbWidgetCreateArgData * data)
+{
+ Bonobo_PropertyBag pb = control_get_pb (widget);
+ char *moniker = gtk_object_get_data (GTK_OBJECT (widget), Moniker);
+ GList *key_list, *names;
+
+ g_assert (moniker);
+
+ if (!pb)
+ return;
+
+ key_list = bonobo_pbclient_get_keys (pb, NULL);
+ for (names = key_list; names; names = names->next) {
+ CORBA_TypeCode tc;
+ char *title, *doc;
+ char *prop = create_prop_name (moniker, names->data);
+
+ tc = bonobo_pbclient_get_type (pb, names->data, NULL);
+ title = bonobo_pbclient_get_doc_title (pb, names->data, NULL);
+ doc = bonobo_pbclient_get_doc (pb, names->data, NULL);
+
+ switch (tc->kind) {
+ case CORBA_tk_boolean:
+ property_add_bool (prop, title, doc);
+ break;
+ case CORBA_tk_string:
+ property_add_string (prop, title, doc);
+ break;
+ case CORBA_tk_short:
+ case CORBA_tk_ushort:
+ /* FIXME: _int_range() ? */
+ property_add_int (prop, title, doc);
+ break;
+ case CORBA_tk_double:
+ case CORBA_tk_float:
+ property_add_float (prop, title, doc);
+ break;
+ case CORBA_tk_ulong:
+ case CORBA_tk_long:
+ property_add_int (prop, title, doc);
+ break;
+ default:
+ g_warning ("Unhandled type %d", tc->kind);
+ break;
+ }
+ g_free (prop);
+ CORBA_free (title);
+ CORBA_free (doc);
+ }
+ bonobo_pbclient_free_keys (key_list);
+}
+
+/*
+ * Gets the properties of the widget. This is used for both displaying the
+ * properties in the property editor, and also for saving the properties.
+ */
+static void
+gb_bonobo_control_get_properties (GtkWidget * widget, GbWidgetGetArgData * data)
+{
+ Bonobo_PropertyBag pb = control_get_pb (widget);
+ char *moniker = gtk_object_get_data (GTK_OBJECT (widget), Moniker);
+ GList *key_list, *names;
+
+ g_assert (moniker);
+
+ if (!pb)
+ return;
+
+ /* We save the moniker in the XML, though we don't show it in the property
+ editor. */
+ if (data->action == GB_SAVING)
+ {
+ save_string (data, Moniker, moniker);
+ }
+
+ key_list = bonobo_pbclient_get_keys (pb, NULL);
+ for (names = key_list; names; names = names->next) {
+ CORBA_TypeCode tc;
+ char *prop = create_prop_name (moniker, names->data);
+
+ tc = bonobo_pbclient_get_type (pb, names->data, NULL);
+ switch (tc->kind) {
+ case CORBA_tk_boolean:
+ gb_widget_output_bool (data, prop,
+ bonobo_pbclient_get_boolean (pb, names->data, NULL));
+ break;
+ case CORBA_tk_string:
+ {
+ char *str = bonobo_pbclient_get_string (pb, names->data, NULL);
+
+ gb_widget_output_translatable_string (data, prop, str);
+
+ g_free (str);
+ break;
+ }
+ case CORBA_tk_ulong:
+ gb_widget_output_int (data, prop,
+ bonobo_pbclient_get_ulong (pb, names->data, NULL));
+ break;
+ case CORBA_tk_long:
+ gb_widget_output_int (data, prop,
+ bonobo_pbclient_get_long (pb, names->data, NULL));
+ break;
+ case CORBA_tk_short:
+ gb_widget_output_int (data, prop,
+ bonobo_pbclient_get_short (pb, names->data, NULL));
+ break;
+ case CORBA_tk_ushort:
+ gb_widget_output_int (data, prop,
+ bonobo_pbclient_get_ushort (pb, names->data, NULL));
+ break;
+ case CORBA_tk_float:
+ gb_widget_output_float (data, prop,
+ bonobo_pbclient_get_float (pb, names->data, NULL));
+ break;
+ case CORBA_tk_double:
+ gb_widget_output_float (data, prop,
+ bonobo_pbclient_get_double (pb, names->data, NULL));
+ break;
+ default:
+ g_warning ("Unhandled type %d", tc->kind);
+ break;
+ }
+ g_free (prop);
+ }
+ bonobo_pbclient_free_keys (key_list);
+}
+
+
+/*
+ * Sets the properties of the widget. This is used for both applying the
+ * properties changed in the property editor, and also for loading.
+ */
+static void
+gb_bonobo_control_set_properties (GtkWidget * widget, GbWidgetSetArgData * data)
+{
+ Bonobo_PropertyBag pb = control_get_pb (widget);
+ char *moniker = gtk_object_get_data (GTK_OBJECT (widget), Moniker);
+ GList *key_list, *names;
+
+ g_assert (moniker);
+
+ if (!pb)
+ return;
+
+ key_list = bonobo_pbclient_get_keys (pb, NULL);
+ for (names = key_list; names; names = names->next) {
+ CORBA_TypeCode tc;
+ char *prop = create_prop_name (moniker, names->data);
+
+#if 0
+ g_print ("Checking property: %s\n", prop);
+#endif
+
+ tc = bonobo_pbclient_get_type (pb, names->data, NULL);
+ switch (tc->kind) {
+ case CORBA_tk_boolean:
+ {
+ gboolean val;
+
+ val = gb_widget_input_bool (data, prop);
+ if (data->apply)
+ bonobo_pbclient_set_boolean (pb, names->data, val, NULL);
+ break;
+ }
+ case CORBA_tk_string:
+ {
+ const char *str;
+
+ str = gb_widget_input_string (data, prop);
+ if (data->apply)
+ bonobo_pbclient_set_string (pb, names->data, str, NULL);
+
+ break;
+ }
+ case CORBA_tk_float:
+ {
+ gfloat val;
+
+ val = gb_widget_input_float (data, prop);
+ if (data->apply)
+ bonobo_pbclient_set_float (pb, names->data, val, NULL);
+ break;
+ }
+ case CORBA_tk_double:
+ {
+ gdouble val;
+
+ val = gb_widget_input_float (data, prop);
+ if (data->apply)
+ bonobo_pbclient_set_double (pb, names->data, val, NULL);
+ break;
+ }
+ case CORBA_tk_long:
+ {
+ glong val;
+
+ val = gb_widget_input_int (data, prop);
+ if (data->apply)
+ bonobo_pbclient_set_long (pb, names->data, val, NULL);
+ break;
+ }
+ case CORBA_tk_ulong:
+ {
+ glong val;
+
+ val = gb_widget_input_int (data, prop);
+ if (data->apply)
+ bonobo_pbclient_set_ulong (pb, names->data, val, NULL);
+ break;
+ }
+ case CORBA_tk_short:
+ {
+ glong val;
+
+ val = gb_widget_input_int (data, prop);
+ if (data->apply)
+ bonobo_pbclient_set_short (pb, names->data, val, NULL);
+ break;
+ }
+ case CORBA_tk_ushort:
+ {
+ glong val;
+
+ val = gb_widget_input_int (data, prop);
+ if (data->apply)
+ bonobo_pbclient_set_ushort (pb, names->data, val, NULL);
+ break;
+ }
+ default:
+ g_warning ("Unhandled type %d", tc->kind);
+ break;
+ }
+ g_free (prop);
+ }
+ bonobo_pbclient_free_keys (key_list);
+}
+
+/*
+ * Writes the source code needed to create this widget.
+ * You have to output everything necessary to create the widget here, though
+ * there are some convenience functions to help.
+ */
+static void
+gb_bonobo_control_write_source (GtkWidget * widget, GbWidgetWriteSourceData * data)
+{
+ char *moniker = gtk_object_get_data (GTK_OBJECT (widget), Moniker);
+ BonoboControlFrame *cf;
+ Bonobo_PropertyBag pb;
+ GList *key_list, *names;
+
+ if (data->create_widget)
+ {
+ /* Currently we don't support BonoboWindow, so it will always be NIL,
+ but if we ever do, then it just needs to set bonobo_uic when it is
+ created. */
+ source_ensure_decl (data, " Bonobo_UIContainer bonobo_uic = CORBA_OBJECT_NIL;\n");
+ source_add (data,
+ " %s = bonobo_widget_new_control (%s, bonobo_uic);\n",
+ data->wname,
+ source_make_string (moniker, FALSE));
+ }
+
+ gb_widget_write_standard_source (widget, data);
+
+ cf = bonobo_widget_get_control_frame (BONOBO_WIDGET (widget));
+ if (!cf)
+ return;
+
+ pb = bonobo_control_frame_get_control_property_bag (cf, NULL);
+
+ source_ensure_decl (data, " BonoboControlFrame *bonobo_cf;\n");
+ source_ensure_decl (data, " Bonobo_PropertyBag bonobo_pb;\n");
+
+ source_add (data,
+ " bonobo_cf = bonobo_widget_get_control_frame (BONOBO_WIDGET (%s));\n",
+ data->wname);
+ source_add (data,
+ " bonobo_pb = bonobo_control_frame_get_control_property_bag (bonobo_cf, NULL);\n");
+
+
+ key_list = bonobo_pbclient_get_keys (pb, NULL);
+ for (names = key_list; names; names = names->next) {
+ CORBA_TypeCode tc;
+
+ tc = bonobo_pbclient_get_type (pb, names->data, NULL);
+ switch (tc->kind) {
+ case CORBA_tk_boolean: {
+ gboolean val = bonobo_pbclient_get_boolean (pb, names->data, NULL);
+ source_add (data,
+ " bonobo_pbclient_set_boolean (bonobo_pb, %s, %s, NULL);\n",
+ source_make_string (names->data, FALSE),
+ val ? "TRUE" : "FALSE");
+ break;
+ }
+ case CORBA_tk_string: {
+ char *val = bonobo_pbclient_get_string (pb, names->data, NULL);
+ source_add (data,
+ " bonobo_pbclient_set_string (bonobo_pb, %s,",
+ source_make_string (names->data, FALSE));
+ source_add (data, " %s, NULL);\n",
+ source_make_string (val, data->use_gettext));
+ g_free (val);
+ break;
+ }
+ case CORBA_tk_ulong: {
+ gulong val = bonobo_pbclient_get_ulong (pb, names->data, NULL);
+ source_add (data,
+ " bonobo_pbclient_set_ulong (bonobo_pb, %s, %lu, NULL);\n",
+ source_make_string (names->data, FALSE),
+ val);
+ break;
+ }
+ case CORBA_tk_long: {
+ glong val = bonobo_pbclient_get_long (pb, names->data, NULL);
+ source_add (data,
+ " bonobo_pbclient_set_long (bonobo_pb, %s, %li, NULL);\n",
+ source_make_string (names->data, FALSE),
+ val);
+ break;
+ }
+ case CORBA_tk_short: {
+ gshort val = bonobo_pbclient_get_short (pb, names->data, NULL);
+ source_add (data,
+ " bonobo_pbclient_set_short (bonobo_pb, %s, %i, NULL);\n",
+ source_make_string (names->data, FALSE),
+ val);
+ break;
+ }
+ case CORBA_tk_ushort: {
+ gushort val = bonobo_pbclient_get_ushort (pb, names->data, NULL);
+ source_add (data,
+ " bonobo_pbclient_set_ushort (bonobo_pb, %s, %u, NULL);\n",
+ source_make_string (names->data, FALSE),
+ val);
+ break;
+ }
+ case CORBA_tk_float: {
+ gfloat val = bonobo_pbclient_get_float (pb, names->data, NULL);
+ source_add (data,
+ " bonobo_pbclient_set_float (bonobo_pb, %s, %g, NULL);\n",
+ source_make_string (names->data, FALSE),
+ val);
+ break;
+ }
+ case CORBA_tk_double: {
+ gdouble val = bonobo_pbclient_get_double (pb, names->data, NULL);
+ source_add (data,
+ " bonobo_pbclient_set_double (bonobo_pb, %s, %g, NULL);\n",
+ source_make_string (names->data, FALSE),
+ val);
+ break;
+ }
+ default:
+ g_warning ("Unhandled type %d", tc->kind);
+ break;
+ }
+
+
+ }
+ bonobo_pbclient_free_keys (key_list);
+}
+
+static GbWidget *
+control_get_gb_widget (const char *obj_id)
+{
+ GbWidget *gbwidget;
+
+ /* Check if this GbWidget is already registered. */
+ gbwidget = gb_widget_lookup_class (obj_id);
+
+ /* If it isn't registered, create it and register it. */
+ if (!gbwidget)
+ {
+ gbwidget = g_new (GbWidget, 1);
+
+ gb_widget_init_struct (gbwidget);
+
+ /* Fill in the pixmap struct & tooltip */
+ gbwidget->pixmap_struct = gnome_control_xpm;
+ gbwidget->tooltip = NULL;
+
+ /* Fill in any functions that this Gbwidget has */
+ gbwidget->gb_widget_new = NULL;
+ gbwidget->gb_widget_create_properties = gb_bonobo_control_create_properties;
+ gbwidget->gb_widget_get_properties = gb_bonobo_control_get_properties;
+ gbwidget->gb_widget_set_properties = gb_bonobo_control_set_properties;
+ gbwidget->gb_widget_write_source = gb_bonobo_control_write_source;
+
+#if 0
+ g_print ("Registering Bonobo control GbWidget: %s\n", obj_id);
+#endif
+ gb_widget_register_gbwidget (obj_id, gbwidget);
+ }
+
+ return gbwidget;
+}
+