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.
21 #include <glib-object.h>
22 #include "atkobject.h"
23 #include "atkrelation.h"
24 #include "atk-enum-types.h"
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
,
44 static void atk_relation_get_property (GObject
*object
,
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
);
53 atk_relation_get_type (void)
55 static GType type
= 0;
59 static const GTypeInfo typeInfo
=
61 sizeof (AtkRelationClass
),
63 (GBaseFinalizeFunc
) NULL
,
64 (GClassInitFunc
) atk_relation_class_init
,
65 (GClassFinalizeFunc
) NULL
,
69 (GInstanceInitFunc
) NULL
,
71 type
= g_type_register_static (G_TYPE_OBJECT
, "AtkRelation", &typeInfo
, 0) ;
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
,
89 g_param_spec_enum ("relation_type",
91 "The type of the relation",
92 ATK_TYPE_RELATION_TYPE
,
95 g_object_class_install_property (gobject_class
,
97 g_param_spec_value_array ("target",
99 "An array of the targets for the relation",
106 * atk_relation_type_register:
107 * @name: a name string
109 * Associate @name with a new #AtkRelationType
111 * Returns: an #AtkRelationType associated with @name
114 atk_relation_type_register (const gchar
*name
)
116 g_return_val_if_fail (name
, ATK_RELATION_NULL
);
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
;
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
);
147 name
= value
->value_nick
;
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
);
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.
175 atk_relation_type_for_name (const gchar
*name
)
177 GTypeClass
*type_class
;
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
);
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
;
212 g_type_class_unref (type_class
);
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
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
231 atk_relation_new (AtkObject
**targets
,
233 AtkRelationType relationship
)
235 AtkRelation
*relation
;
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
);
253 relation
= g_object_new (ATK_TYPE_RELATION
,
254 "relation_type", relationship
,
258 g_value_array_free (array
);
264 * atk_relation_get_relation_type:
265 * @relation: an #AtkRelation
267 * Gets the type of @relation
269 * Returns: the type of @relation
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
288 atk_relation_get_target (AtkRelation
*relation
)
290 g_return_val_if_fail (ATK_IS_RELATION (relation
), NULL
);
292 return relation
->target
;
296 delete_object_while_in_relation (gpointer callback_data
,
297 GObject
*where_the_object_was
)
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().
319 atk_relation_add_target (AtkRelation
*relation
,
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
)
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.
347 atk_relation_remove_target (AtkRelation
*relation
,
350 gboolean ret
= FALSE
;
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
,
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
)
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
,
384 g_ptr_array_free (relation
->target
, TRUE
);
387 G_OBJECT_CLASS (parent_class
)->finalize (object
);
391 atk_relation_set_property (GObject
*object
,
396 AtkRelation
*relation
;
399 relation
= ATK_RELATION (object
);
403 case PROP_RELATION_TYPE
:
404 relation
->relationship
= g_value_get_enum (value
);
407 if (relation
->target
)
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
,
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
);
428 atk_relation_get_property (GObject
*object
,
433 AtkRelation
*relation
;
436 relation
= ATK_RELATION (object
);
440 case PROP_RELATION_TYPE
:
441 g_value_set_enum (value
, relation
->relationship
);
444 array
= atk_relation_get_value_array_from_ptr_array (relation
->target
);
445 g_value_set_boxed (value
, array
);
448 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, prop_id
, pspec
);
454 atk_relation_get_ptr_array_from_value_array (GValueArray
*array
)
457 GPtrArray
*return_array
;
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
);
474 atk_relation_get_value_array_from_ptr_array (GPtrArray
*array
)
477 GValueArray
*return_array
;
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
);