source: trunk/third/bonobo/bonobo/bonobo-item-container.c @ 16750

Revision 16750, 7.3 KB checked in by ghudson, 23 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r16749, which included commits to RCS files with non-trunk default branches.
Line 
1/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2/**
3 * bonobo-item-container.h: a generic container for monikers.
4 *
5 * The BonoboItemContainer object represents a document which may have one
6 * or more embedded document objects.  To embed an object in the
7 * container, create a BonoboClientSite, add it to the container, and
8 * then create an object supporting Bonobo::Embeddable and bind it to
9 * the client site.  The BonoboItemContainer maintains a list of the client
10 * sites which correspond to the objects embedded in the container.
11 *
12 * Author:
13 *   Miguel de Icaza (miguel@kernel.org)
14 *   Nat Friedman    (nat@nat.org)
15 *
16 * Copyright 1999, 2000 Helix Code, Inc.
17 */
18#include <config.h>
19#include <gtk/gtksignal.h>
20#include <gtk/gtkmarshal.h>
21#include <gtk/gtkwidget.h>
22#include <bonobo/bonobo-exception.h>
23#include <bonobo/bonobo-main.h>
24#include <bonobo/bonobo-object.h>
25#include <bonobo/bonobo-item-container.h>
26#include <bonobo/bonobo-client-site.h>
27
28enum {
29        GET_OBJECT,
30        LAST_SIGNAL
31};
32
33static guint signals [LAST_SIGNAL] = { 0, };
34
35#define PARENT_TYPE BONOBO_X_OBJECT_TYPE
36
37static GtkObjectClass *bonobo_item_container_parent_class;
38
39struct _BonoboItemContainerPrivate {
40        GHashTable *objects;
41};
42
43static gboolean
44remove_object (gpointer key,
45               gpointer value,
46               gpointer user_data)
47{
48        g_free (key);
49        bonobo_object_unref (value);
50
51        return TRUE;
52}
53
54static void
55bonobo_item_container_destroy (GtkObject *object)
56{
57        BonoboItemContainer *container = BONOBO_ITEM_CONTAINER (object);
58
59        /* Destroy all the ClientSites. */
60        g_hash_table_foreach_remove (container->priv->objects,
61                                     remove_object, NULL);
62
63        bonobo_item_container_parent_class->destroy (object);
64}
65
66static void
67bonobo_item_container_finalize (GtkObject *object)
68{
69        BonoboItemContainer *container = BONOBO_ITEM_CONTAINER (object);
70
71        g_hash_table_destroy (container->priv->objects);
72        g_free (container->priv);
73       
74        bonobo_item_container_parent_class->finalize (object);
75}
76
77static void
78get_object_names (gpointer key, gpointer value, gpointer user_data)
79{
80        GSList **l = user_data;
81
82        *l = g_slist_prepend (*l, CORBA_string_dup (key));
83}
84
85/*
86 * Returns a list of the objects in this container
87 */
88static Bonobo_ItemContainer_ObjectNames *
89impl_Bonobo_ItemContainer_enumObjects (PortableServer_Servant servant,
90                                       CORBA_Environment     *ev)
91{
92        Bonobo_ItemContainer_ObjectNames *list;
93        BonoboItemContainer              *container;
94        GSList                           *objects, *l;
95        int                               i;
96
97        container = BONOBO_ITEM_CONTAINER (
98                bonobo_object_from_servant (servant));
99        g_return_val_if_fail (container != NULL, NULL);
100
101        list = Bonobo_ItemContainer_ObjectNames__alloc ();
102        if (!list)
103                return NULL;
104
105        objects = NULL;
106        g_hash_table_foreach (container->priv->objects,
107                              get_object_names, &objects);
108
109        list->_length = list->_maximum = g_slist_length (objects);
110       
111        list->_buffer = CORBA_sequence_CORBA_string_allocbuf (list->_length);
112        if (!list->_buffer) {
113                GSList *l;
114                CORBA_free (list);
115                for (l = objects; l; l = l->next)
116                        CORBA_free (l->data);
117                g_slist_free (objects);
118                return NULL;
119        }
120       
121        /* Assemble the list of objects */
122        for (i = 0, l = objects; l; l = l->next)
123                list->_buffer [i++] = l->data;
124
125        g_slist_free (objects);
126
127        return list;
128}
129
130static Bonobo_Unknown
131impl_Bonobo_ItemContainer_getObjectByName (PortableServer_Servant servant,
132                                           const CORBA_char      *item_name,
133                                           CORBA_boolean          only_if_exists,
134                                           CORBA_Environment     *ev)
135{
136        Bonobo_Unknown ret;
137       
138        gtk_signal_emit (
139                GTK_OBJECT (bonobo_object_from_servant (servant)),
140                signals [GET_OBJECT], item_name, only_if_exists, ev, &ret);
141
142        return ret;
143}
144
145typedef Bonobo_Unknown (*GnomeSignal_POINTER__POINTER_BOOL_POINTER) (
146        BonoboItemContainer *item_container,
147        CORBA_char *item_name,
148        CORBA_boolean only_if_exists,
149        CORBA_Environment *ev,
150        gpointer func_data);
151
152static void
153gnome_marshal_POINTER__POINTER_BOOL_POINTER (GtkObject * object,
154                                             GtkSignalFunc func,
155                                             gpointer func_data,
156                                             GtkArg * args)
157{
158        GnomeSignal_POINTER__POINTER_BOOL_POINTER rfunc;
159        void **return_val;
160        return_val = GTK_RETLOC_POINTER (args[3]);
161        rfunc = (GnomeSignal_POINTER__POINTER_BOOL_POINTER) func;
162        *return_val = (*rfunc) (BONOBO_ITEM_CONTAINER (object),
163                                GTK_VALUE_POINTER (args[0]),
164                                GTK_VALUE_BOOL (args[1]),
165                                GTK_VALUE_POINTER (args[2]),
166                                func_data);
167}
168
169/* BonoboItemContainer class initialization routine  */
170static void
171bonobo_item_container_class_init (BonoboItemContainerClass *klass)
172{
173        GtkObjectClass *object_class = (GtkObjectClass *) klass;
174        POA_Bonobo_ItemContainer__epv *epv = &klass->epv;
175
176        bonobo_item_container_parent_class = gtk_type_class (PARENT_TYPE);
177
178        object_class->destroy = bonobo_item_container_destroy;
179        object_class->finalize = bonobo_item_container_finalize;
180
181        signals [GET_OBJECT] =
182                gtk_signal_new  (
183                        "get_object",
184                        GTK_RUN_LAST,
185                        object_class->type,
186                        0,
187                        gnome_marshal_POINTER__POINTER_BOOL_POINTER,
188                        GTK_TYPE_POINTER,
189                        3,
190                        GTK_TYPE_POINTER, GTK_TYPE_BOOL, GTK_TYPE_POINTER);
191        gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL);
192
193        epv->enumObjects     = impl_Bonobo_ItemContainer_enumObjects;
194        epv->getObjectByName = impl_Bonobo_ItemContainer_getObjectByName;
195}
196
197/*
198 * BonoboItemContainer instance initialization routine
199 */
200static void
201bonobo_item_container_init (BonoboItemContainer *container)
202{
203        container->priv = g_new0 (BonoboItemContainerPrivate, 1);
204        container->priv->objects = g_hash_table_new (
205                g_str_hash, g_str_equal);
206}
207
208BONOBO_X_TYPE_FUNC_FULL (BonoboItemContainer,
209                           Bonobo_ItemContainer,
210                           PARENT_TYPE,
211                           bonobo_item_container);
212
213/**
214 * bonobo_item_container_new:
215 *
216 * Creates a new BonoboItemContainer object.  These are used to hold
217 * client sites.
218 *
219 * Returns: The newly created BonoboItemContainer object
220 */
221BonoboItemContainer *
222bonobo_item_container_new (void)
223{
224        return gtk_type_new (bonobo_item_container_get_type ());
225}
226
227/**
228 * bonobo_item_container_add:
229 * @container: The object to operate on.
230 * @name: The name of the object
231 * @object: The object to add to the container
232 *
233 * Adds the @object to the list of objects managed by this
234 * container
235 */
236void
237bonobo_item_container_add (BonoboItemContainer *container,
238                           const char          *name,
239                           BonoboObject        *object)
240{
241        g_return_if_fail (name != NULL);
242        g_return_if_fail (BONOBO_IS_OBJECT (object));
243        g_return_if_fail (BONOBO_IS_ITEM_CONTAINER (container));
244
245        if (g_hash_table_lookup (container->priv->objects, name)) {
246                g_warning ("Object of name '%s' already exists", name);
247        } else {
248                bonobo_object_ref (object);
249                g_hash_table_insert (container->priv->objects,
250                                     g_strdup (name),
251                                     object);
252        }
253}
254
255/**
256 * bonobo_item_container_remove_by_name:
257 * @container: The object to operate on.
258 * @name: The name of the object to remove from the container
259 *
260 * Removes the named object from the @container
261 */
262void
263bonobo_item_container_remove_by_name (BonoboItemContainer *container,
264                                      const char          *name)
265{
266        gpointer key, value;
267
268        g_return_if_fail (name != NULL);
269        g_return_if_fail (BONOBO_IS_ITEM_CONTAINER (container));
270
271        if (!g_hash_table_lookup_extended (container->priv->objects, name,
272                                           &key, &value))
273                g_warning ("Removing '%s' but not in container", name);
274        else {
275                g_hash_table_remove (container->priv->objects, name);
276                g_free (key);
277                bonobo_object_unref (value);
278        }
279}
280
Note: See TracBrowser for help on using the repository browser.