Bug 640574: gobject-introspection annotation and documentation fixes
[atk.git] / atk / atkrelation.c
blob9c266608877ccff137614004458a8bc9512dd529
1 /* ATK - Accessibility Toolkit
2 * Copyright 2001 Sun Microsystems Inc.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
20 #include <string.h>
21 #include <glib-object.h>
22 #include "atkobject.h"
23 #include "atkrelation.h"
24 #include "atk-enum-types.h"
26 enum {
27 PROP_0,
29 PROP_RELATION_TYPE,
30 PROP_TARGET,
31 PROP_LAST
34 static GPtrArray *extra_names = NULL;
36 static gpointer parent_class = NULL;
38 static void atk_relation_class_init (AtkRelationClass *klass);
39 static void atk_relation_finalize (GObject *object);
40 static void atk_relation_set_property (GObject *object,
41 guint prop_id,
42 const GValue *value,
43 GParamSpec *pspec);
44 static void atk_relation_get_property (GObject *object,
45 guint prop_id,
46 GValue *value,
47 GParamSpec *pspec);
49 static GPtrArray* atk_relation_get_ptr_array_from_value_array (GValueArray *array);
50 static GValueArray* atk_relation_get_value_array_from_ptr_array (GPtrArray *array);
52 GType
53 atk_relation_get_type (void)
55 static GType type = 0;
57 if (!type)
59 static const GTypeInfo typeInfo =
61 sizeof (AtkRelationClass),
62 (GBaseInitFunc) NULL,
63 (GBaseFinalizeFunc) NULL,
64 (GClassInitFunc) atk_relation_class_init,
65 (GClassFinalizeFunc) NULL,
66 NULL,
67 sizeof (AtkRelation),
69 (GInstanceInitFunc) NULL,
70 } ;
71 type = g_type_register_static (G_TYPE_OBJECT, "AtkRelation", &typeInfo, 0) ;
73 return type;
76 static void
77 atk_relation_class_init (AtkRelationClass *klass)
79 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
81 parent_class = g_type_class_peek_parent (klass);
83 gobject_class->finalize = atk_relation_finalize;
84 gobject_class->set_property = atk_relation_set_property;
85 gobject_class->get_property = atk_relation_get_property;
87 g_object_class_install_property (gobject_class,
88 PROP_RELATION_TYPE,
89 g_param_spec_enum ("relation_type",
90 "Relation Type",
91 "The type of the relation",
92 ATK_TYPE_RELATION_TYPE,
93 ATK_RELATION_NULL,
94 G_PARAM_READWRITE));
95 g_object_class_install_property (gobject_class,
96 PROP_TARGET,
97 g_param_spec_value_array ("target",
98 "Target",
99 "An array of the targets for the relation",
100 NULL,
102 G_PARAM_READWRITE));
106 * atk_relation_type_register:
107 * @name: a name string
109 * Associate @name with a new #AtkRelationType
111 * Returns: an #AtkRelationType associated with @name
113 AtkRelationType
114 atk_relation_type_register (const gchar *name)
116 g_return_val_if_fail (name, ATK_RELATION_NULL);
118 if (!extra_names)
119 extra_names = g_ptr_array_new ();
121 g_ptr_array_add (extra_names, g_strdup (name));
122 return extra_names->len + ATK_RELATION_LAST_DEFINED;
126 * atk_relation_type_get_name:
127 * @type: The #AtkRelationType whose name is required
129 * Gets the description string describing the #AtkRelationType @type.
131 * Returns: the string describing the AtkRelationType
133 G_CONST_RETURN gchar*
134 atk_relation_type_get_name (AtkRelationType type)
136 GTypeClass *type_class;
137 GEnumValue *value;
138 const gchar *name = NULL;
140 type_class = g_type_class_ref (ATK_TYPE_RELATION_TYPE);
141 g_return_val_if_fail (G_IS_ENUM_CLASS (type_class), NULL);
143 value = g_enum_get_value (G_ENUM_CLASS (type_class), type);
145 if (value)
147 name = value->value_nick;
149 else
151 if (extra_names)
153 gint n = type;
155 n -= ATK_RELATION_LAST_DEFINED + 1;
157 if (n < extra_names->len)
158 name = g_ptr_array_index (extra_names, n);
161 g_type_class_unref (type_class);
162 return name;
166 * atk_relation_type_for_name:
167 * @name: a string which is the (non-localized) name of an ATK relation type.
169 * Get the #AtkRelationType type corresponding to a relation name.
171 * Returns: the #AtkRelationType enumerated type corresponding to the specified name,
172 * or #ATK_RELATION_NULL if no matching relation type is found.
174 AtkRelationType
175 atk_relation_type_for_name (const gchar *name)
177 GTypeClass *type_class;
178 GEnumValue *value;
179 AtkRelationType type = ATK_RELATION_NULL;
181 g_return_val_if_fail (name, ATK_RELATION_NULL);
183 type_class = g_type_class_ref (ATK_TYPE_RELATION_TYPE);
184 g_return_val_if_fail (G_IS_ENUM_CLASS (type_class), ATK_RELATION_NULL);
186 value = g_enum_get_value_by_nick (G_ENUM_CLASS (type_class), name);
188 if (value)
190 type = value->value;
192 else
194 gint i;
196 if (extra_names)
198 for (i = 0; i < extra_names->len; i++)
200 gchar *extra_name = (gchar *)g_ptr_array_index (extra_names, i);
202 g_return_val_if_fail (extra_name, ATK_RELATION_NULL);
204 if (strcmp (name, extra_name) == 0)
206 type = i + 1 + ATK_RELATION_LAST_DEFINED;
207 break;
212 g_type_class_unref (type_class);
214 return type;
219 * atk_relation_new:
220 * @targets: an array of pointers to #AtkObjects
221 * @n_targets: number of #AtkObjects pointed to by @targets
222 * @relationship: an #AtkRelationType with which to create the new
223 * #AtkRelation
225 * Create a new relation for the specified key and the specified list
226 * of targets. See also atk_object_add_relationship().
228 * Returns: a pointer to a new #AtkRelation
230 AtkRelation*
231 atk_relation_new (AtkObject **targets,
232 gint n_targets,
233 AtkRelationType relationship)
235 AtkRelation *relation;
236 int i;
237 GValueArray *array;
238 GValue *value;
240 g_return_val_if_fail (targets != NULL, NULL);
242 array = g_value_array_new (n_targets);
243 for (i = 0; i < n_targets; i++)
245 value = g_new0 (GValue, 1);
246 g_value_init (value, ATK_TYPE_OBJECT);
247 g_value_set_object (value, targets[i]);
248 array = g_value_array_append (array, value);
249 g_value_unset (value);
250 g_free (value);
253 relation = g_object_new (ATK_TYPE_RELATION,
254 "relation_type", relationship,
255 "target", array,
256 NULL);
258 g_value_array_free (array);
260 return relation;
264 * atk_relation_get_relation_type:
265 * @relation: an #AtkRelation
267 * Gets the type of @relation
269 * Returns: the type of @relation
271 AtkRelationType
272 atk_relation_get_relation_type (AtkRelation *relation)
274 g_return_val_if_fail (ATK_IS_RELATION (relation), 0);
276 return relation->relationship;
280 * atk_relation_get_target:
281 * @relation: an #AtkRelation
283 * Gets the target list of @relation
285 * Returns: (transfer none): the target list of @relation
287 GPtrArray*
288 atk_relation_get_target (AtkRelation *relation)
290 g_return_val_if_fail (ATK_IS_RELATION (relation), NULL);
292 return relation->target;
295 static void
296 delete_object_while_in_relation (gpointer callback_data,
297 GObject *where_the_object_was)
299 GPtrArray *array;
301 g_assert (callback_data != NULL);
303 array = callback_data;
304 g_ptr_array_remove (array, where_the_object_was);
308 * atk_relation_add_target:
309 * @relation: an #AtkRelation
310 * @target: an #AtkObject
312 * Adds the specified AtkObject to the target for the relation, if it is
313 * not already present. See also atk_object_add_relationship().
316 * Since: 1.9
318 void
319 atk_relation_add_target (AtkRelation *relation,
320 AtkObject *target)
322 guint i;
324 g_return_if_fail (ATK_IS_RELATION (relation));
325 g_return_if_fail (ATK_IS_OBJECT (target));
327 /* first check if target occurs in array ... */
328 for (i = 0; i < relation->target->len; i++)
329 if (g_ptr_array_index(relation->target, i) == target)
330 return;
332 g_ptr_array_add (relation->target, target);
333 g_object_weak_ref (G_OBJECT (target), (GWeakNotify) delete_object_while_in_relation, relation->target);
337 * atk_relation_remove_target:
338 * @relation: an #AtkRelation
339 * @target: an #AtkObject
341 * Remove the specified AtkObject from the target for the relation.
343 * Returns TRUE if the removal is successful.
346 gboolean
347 atk_relation_remove_target (AtkRelation *relation,
348 AtkObject *target)
350 gboolean ret = FALSE;
351 GPtrArray *array;
353 array = atk_relation_get_target (relation);
355 if (array && g_ptr_array_remove (array, target))
357 g_object_weak_unref (G_OBJECT (target),
358 (GWeakNotify) delete_object_while_in_relation,
359 relation->target);
360 ret = TRUE;
362 return ret;
365 static void
366 atk_relation_finalize (GObject *object)
368 AtkRelation *relation;
370 g_return_if_fail (ATK_IS_RELATION (object));
372 relation = ATK_RELATION (object);
374 if (relation->target)
376 gint i;
378 for (i = 0; i < relation->target->len; i++)
380 g_object_weak_unref (G_OBJECT (g_ptr_array_index (relation->target, i)),
381 (GWeakNotify) delete_object_while_in_relation,
382 relation->target);
384 g_ptr_array_free (relation->target, TRUE);
387 G_OBJECT_CLASS (parent_class)->finalize (object);
390 static void
391 atk_relation_set_property (GObject *object,
392 guint prop_id,
393 const GValue *value,
394 GParamSpec *pspec)
396 AtkRelation *relation;
397 gpointer boxed;
399 relation = ATK_RELATION (object);
401 switch (prop_id)
403 case PROP_RELATION_TYPE:
404 relation->relationship = g_value_get_enum (value);
405 break;
406 case PROP_TARGET:
407 if (relation->target)
409 gint i;
411 for (i = 0; i < relation->target->len; i++)
413 g_object_weak_unref (G_OBJECT (g_ptr_array_index (relation->target, i)),
414 (GWeakNotify) delete_object_while_in_relation,
415 relation->target);
417 g_ptr_array_free (relation->target, TRUE);
419 boxed = g_value_get_boxed (value);
420 relation->target = atk_relation_get_ptr_array_from_value_array ( (GValueArray *) boxed);
421 break;
422 default:
423 break;
427 static void
428 atk_relation_get_property (GObject *object,
429 guint prop_id,
430 GValue *value,
431 GParamSpec *pspec)
433 AtkRelation *relation;
434 GValueArray *array;
436 relation = ATK_RELATION (object);
438 switch (prop_id)
440 case PROP_RELATION_TYPE:
441 g_value_set_enum (value, relation->relationship);
442 break;
443 case PROP_TARGET:
444 array = atk_relation_get_value_array_from_ptr_array (relation->target);
445 g_value_set_boxed (value, array);
446 break;
447 default:
448 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
449 break;
453 static GPtrArray*
454 atk_relation_get_ptr_array_from_value_array (GValueArray *array)
456 gint i;
457 GPtrArray *return_array;
458 GValue *value;
459 GObject *obj;
461 return_array = g_ptr_array_sized_new (array->n_values);
462 for (i = 0; i < array->n_values; i++)
464 value = g_value_array_get_nth (array, i);
465 obj = g_value_get_object (value);
466 g_ptr_array_add (return_array, obj);
467 g_object_weak_ref (obj, (GWeakNotify) delete_object_while_in_relation, return_array);
470 return return_array;
473 static GValueArray*
474 atk_relation_get_value_array_from_ptr_array (GPtrArray *array)
476 int i;
477 GValueArray *return_array;
478 GValue *value;
480 return_array = g_value_array_new (array->len);
481 for (i = 0; i < array->len; i++)
483 value = g_new0 (GValue, 1);
484 g_value_init (value, ATK_TYPE_OBJECT);
485 g_value_set_object (value, g_ptr_array_index (array, i));
486 return_array = g_value_array_append (return_array, value);
488 return return_array;