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, see <http://www.gnu.org/licenses/>.
18 #include <glib-object.h>
23 * SECTION:atkrelationset
24 * @Short_description: A set of AtkRelations, normally the set of
25 * AtkRelations which an AtkObject has.
26 * @Title:AtkRelationSet
28 * The AtkRelationSet held by an object establishes its relationships
29 * with objects beyond the normal "parent/child" hierarchical
30 * relationships that all user interface objects have.
31 * AtkRelationSets establish whether objects are labelled or
32 * controlled by other components, share group membership with other
33 * components (for instance within a radio-button group), or share
34 * content which "flows" between them, among other types of possible
38 static gpointer parent_class = NULL;
40 static void atk_relation_set_class_init (AtkRelationSetClass *klass);
41 static void atk_relation_set_finalize (GObject *object);
44 atk_relation_set_get_type (void)
46 static GType type = 0;
50 static const GTypeInfo typeInfo =
52 sizeof (AtkRelationSetClass),
54 (GBaseFinalizeFunc) NULL,
55 (GClassInitFunc) atk_relation_set_class_init,
56 (GClassFinalizeFunc) NULL,
58 sizeof (AtkRelationSet),
60 (GInstanceInitFunc) NULL,
62 type = g_type_register_static (G_TYPE_OBJECT, "AtkRelationSet", &typeInfo, 0) ;
68 atk_relation_set_class_init (AtkRelationSetClass *klass)
70 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
72 parent_class = g_type_class_peek_parent (klass);
74 gobject_class->finalize = atk_relation_set_finalize;
78 * atk_relation_set_new:
80 * Creates a new empty relation set.
82 * Returns: a new #AtkRelationSet
85 atk_relation_set_new (void)
87 AtkRelationSet *relation_set;
89 relation_set = g_object_new (ATK_TYPE_RELATION_SET, NULL);
94 * atk_relation_set_contains:
95 * @set: an #AtkRelationSet
96 * @relationship: an #AtkRelationType
98 * Determines whether the relation set contains a relation that matches the
101 * Returns: %TRUE if @relationship is the relationship type of a relation
102 * in @set, %FALSE otherwise
105 atk_relation_set_contains (AtkRelationSet *set,
106 AtkRelationType relationship)
108 GPtrArray *array_item;
112 g_return_val_if_fail (ATK_IS_RELATION_SET (set), FALSE);
114 array_item = set->relations;
115 if (array_item == NULL)
117 for (i = 0; i < array_item->len; i++)
119 item = g_ptr_array_index (array_item, i);
120 if (item->relationship == relationship)
127 * atk_relation_set_remove:
128 * @set: an #AtkRelationSet
129 * @relation: an #AtkRelation
131 * Removes a relation from the relation set.
132 * This function unref's the #AtkRelation so it will be deleted unless there
133 * is another reference to it.
136 atk_relation_set_remove (AtkRelationSet *set,
137 AtkRelation *relation)
139 GPtrArray *array_item;
140 AtkRelationType relationship;
142 g_return_if_fail (ATK_IS_RELATION_SET (set));
144 array_item = set->relations;
145 if (array_item == NULL)
148 if (g_ptr_array_remove (array_item, relation))
150 g_object_unref (relation);
154 relationship = atk_relation_get_relation_type (relation);
155 if (atk_relation_set_contains (set, relationship))
157 AtkRelation *exist_relation;
159 exist_relation = atk_relation_set_get_relation_by_type (set, relationship);
160 for (i = 0; i < relation->target->len; i++)
162 AtkObject *target = g_ptr_array_index(relation->target, i);
163 atk_relation_remove_target (exist_relation, target);
170 * atk_relation_set_add:
171 * @set: an #AtkRelationSet
172 * @relation: an #AtkRelation
174 * Add a new relation to the current relation set if it is not already
176 * This function ref's the AtkRelation so the caller of this function
177 * should unref it to ensure that it will be destroyed when the AtkRelationSet
181 atk_relation_set_add (AtkRelationSet *set,
182 AtkRelation *relation)
184 AtkRelationType relationship;
186 g_return_if_fail (ATK_IS_RELATION_SET (set));
187 g_return_if_fail (relation != NULL);
189 if (set->relations == NULL)
191 set->relations = g_ptr_array_new ();
194 relationship = atk_relation_get_relation_type (relation);
195 if (!atk_relation_set_contains (set, relationship))
197 g_ptr_array_add (set->relations, relation);
198 g_object_ref (relation);
202 AtkRelation *exist_relation;
204 exist_relation = atk_relation_set_get_relation_by_type (set, relationship);
205 for (i = 0; i < relation->target->len; i++)
207 AtkObject *target = g_ptr_array_index(relation->target, i);
208 atk_relation_add_target (exist_relation, target);
214 * atk_relation_set_get_n_relations:
215 * @set: an #AtkRelationSet
217 * Determines the number of relations in a relation set.
219 * Returns: an integer representing the number of relations in the set.
222 atk_relation_set_get_n_relations (AtkRelationSet *set)
224 g_return_val_if_fail (ATK_IS_RELATION_SET (set), 0);
226 if (set->relations == NULL)
229 return set->relations->len;
233 * atk_relation_set_get_relation:
234 * @set: an #AtkRelationSet
235 * @i: a gint representing a position in the set, starting from 0.
237 * Determines the relation at the specified position in the relation set.
239 * Returns: (transfer none): a #AtkRelation, which is the relation at
240 * position i in the set.
243 atk_relation_set_get_relation (AtkRelationSet *set,
246 GPtrArray *array_item;
249 g_return_val_if_fail (ATK_IS_RELATION_SET (set), NULL);
250 g_return_val_if_fail (i >= 0, NULL);
252 array_item = set->relations;
253 if (array_item == NULL)
255 item = g_ptr_array_index (array_item, i);
263 * atk_relation_set_get_relation_by_type:
264 * @set: an #AtkRelationSet
265 * @relationship: an #AtkRelationType
267 * Finds a relation that matches the specified type.
269 * Returns: (transfer none): an #AtkRelation, which is a relation matching the
273 atk_relation_set_get_relation_by_type (AtkRelationSet *set,
274 AtkRelationType relationship)
276 GPtrArray *array_item;
280 g_return_val_if_fail (ATK_IS_RELATION_SET (set), NULL);
282 array_item = set->relations;
283 if (array_item == NULL)
285 for (i = 0; i < array_item->len; i++)
287 item = g_ptr_array_index (array_item, i);
288 if (item->relationship == relationship)
295 atk_relation_set_finalize (GObject *object)
297 AtkRelationSet *relation_set;
301 g_return_if_fail (ATK_IS_RELATION_SET (object));
303 relation_set = ATK_RELATION_SET (object);
304 array = relation_set->relations;
308 for (i = 0; i < array->len; i++)
310 g_object_unref (g_ptr_array_index (array, i));
312 g_ptr_array_free (array, TRUE);
315 G_OBJECT_CLASS (parent_class)->finalize (object);
319 * atk_relation_set_add_relation_by_type:
320 * @set: an #AtkRelationSet
321 * @relationship: an #AtkRelationType
322 * @target: an #AtkObject
324 * Add a new relation of the specified type with the specified target to
325 * the current relation set if the relation set does not contain a relation
326 * of that type. If it is does contain a relation of that typea the target
327 * is added to the relation.
332 atk_relation_set_add_relation_by_type (AtkRelationSet *set,
333 AtkRelationType relationship,
336 AtkRelation *relation;
338 g_return_if_fail (ATK_IS_RELATION_SET (set));
339 g_return_if_fail (ATK_IS_OBJECT (target));
341 relation = atk_relation_set_get_relation_by_type (set,
345 atk_relation_add_target (relation, target);
349 /* the relation hasn't been created yet ... */
350 relation = atk_relation_new (&target, 1, relationship);
351 atk_relation_set_add (set, relation);
352 g_object_unref(relation);
357 * atk_relation_set_contains_target:
358 * @set: an #AtkRelationSet
359 * @relationship: an #AtkRelationType
360 * @target: an #AtkObject
362 * Determines whether the relation set contains a relation that
363 * matches the specified pair formed by type @relationship and object
366 * Returns: %TRUE if @set contains a relation with the relationship
367 * type @relationship with an object @target, %FALSE otherwise
371 atk_relation_set_contains_target (AtkRelationSet *set,
372 AtkRelationType relationship,
375 GPtrArray *array_relations;
376 GPtrArray *array_target;
377 AtkObject *current_target;
378 AtkRelation *relation;
382 g_return_val_if_fail (ATK_IS_RELATION_SET (set), FALSE);
383 g_return_val_if_fail (ATK_IS_OBJECT (target), FALSE);
385 array_relations = set->relations;
386 if (array_relations == NULL)
389 for (i = 0; i < array_relations->len; i++)
391 relation = g_ptr_array_index (array_relations, i);
392 if (relation->relationship == relationship)
394 array_target = atk_relation_get_target (relation);
395 for (c = 0; c < array_target->len; c++)
397 current_target = g_ptr_array_index (array_target, c);
398 if (target == current_target)