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 <glib-object.h>
25 * SECTION:atkrelationset
26 * @Short_description: A set of AtkRelations, normally the set of
27 * AtkRelations which an AtkObject has.
28 * @Title:AtkRelationSet
30 * The AtkRelationSet held by an object establishes its relationships
31 * with objects beyond the normal "parent/child" hierarchical
32 * relationships that all user interface objects have.
33 * AtkRelationSets establish whether objects are labelled or
34 * controlled by other components, share group membership with other
35 * components (for instance within a radio-button group), or share
36 * content which "flows" between them, among other types of possible
40 static gpointer parent_class = NULL;
42 static void atk_relation_set_class_init (AtkRelationSetClass *klass);
43 static void atk_relation_set_finalize (GObject *object);
46 atk_relation_set_get_type (void)
48 static GType type = 0;
52 static const GTypeInfo typeInfo =
54 sizeof (AtkRelationSetClass),
56 (GBaseFinalizeFunc) NULL,
57 (GClassInitFunc) atk_relation_set_class_init,
58 (GClassFinalizeFunc) NULL,
60 sizeof (AtkRelationSet),
62 (GInstanceInitFunc) NULL,
64 type = g_type_register_static (G_TYPE_OBJECT, "AtkRelationSet", &typeInfo, 0) ;
70 atk_relation_set_class_init (AtkRelationSetClass *klass)
72 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
74 parent_class = g_type_class_peek_parent (klass);
76 gobject_class->finalize = atk_relation_set_finalize;
80 * atk_relation_set_new:
82 * Creates a new empty relation set.
84 * Returns: a new #AtkRelationSet
87 atk_relation_set_new (void)
89 AtkRelationSet *relation_set;
91 relation_set = g_object_new (ATK_TYPE_RELATION_SET, NULL);
96 * atk_relation_set_contains:
97 * @set: an #AtkRelationSet
98 * @relationship: an #AtkRelationType
100 * Determines whether the relation set contains a relation that matches the
103 * Returns: %TRUE if @relationship is the relationship type of a relation
104 * in @set, %FALSE otherwise
107 atk_relation_set_contains (AtkRelationSet *set,
108 AtkRelationType relationship)
110 GPtrArray *array_item;
114 g_return_val_if_fail (ATK_IS_RELATION_SET (set), FALSE);
116 array_item = set->relations;
117 if (array_item == NULL)
119 for (i = 0; i < array_item->len; i++)
121 item = g_ptr_array_index (array_item, i);
122 if (item->relationship == relationship)
129 * atk_relation_set_remove:
130 * @set: an #AtkRelationSet
131 * @relation: an #AtkRelation
133 * Removes a relation from the relation set.
134 * This function unref's the #AtkRelation so it will be deleted unless there
135 * is another reference to it.
138 atk_relation_set_remove (AtkRelationSet *set,
139 AtkRelation *relation)
141 GPtrArray *array_item;
142 AtkRelationType relationship;
144 g_return_if_fail (ATK_IS_RELATION_SET (set));
146 array_item = set->relations;
147 if (array_item == NULL)
150 if (g_ptr_array_remove (array_item, relation))
152 g_object_unref (relation);
156 relationship = atk_relation_get_relation_type (relation);
157 if (atk_relation_set_contains (set, relationship))
159 AtkRelation *exist_relation;
161 exist_relation = atk_relation_set_get_relation_by_type (set, relationship);
162 for (i = 0; i < relation->target->len; i++)
164 AtkObject *target = g_ptr_array_index(relation->target, i);
165 atk_relation_remove_target (exist_relation, target);
172 * atk_relation_set_add:
173 * @set: an #AtkRelationSet
174 * @relation: an #AtkRelation
176 * Add a new relation to the current relation set if it is not already
178 * This function ref's the AtkRelation so the caller of this function
179 * should unref it to ensure that it will be destroyed when the AtkRelationSet
183 atk_relation_set_add (AtkRelationSet *set,
184 AtkRelation *relation)
186 AtkRelationType relationship;
188 g_return_if_fail (ATK_IS_RELATION_SET (set));
189 g_return_if_fail (relation != NULL);
191 if (set->relations == NULL)
193 set->relations = g_ptr_array_new ();
196 relationship = atk_relation_get_relation_type (relation);
197 if (!atk_relation_set_contains (set, relationship))
199 g_ptr_array_add (set->relations, relation);
200 g_object_ref (relation);
204 AtkRelation *exist_relation;
206 exist_relation = atk_relation_set_get_relation_by_type (set, relationship);
207 for (i = 0; i < relation->target->len; i++)
209 AtkObject *target = g_ptr_array_index(relation->target, i);
210 atk_relation_add_target (exist_relation, target);
216 * atk_relation_set_get_n_relations:
217 * @set: an #AtkRelationSet
219 * Determines the number of relations in a relation set.
221 * Returns: an integer representing the number of relations in the set.
224 atk_relation_set_get_n_relations (AtkRelationSet *set)
226 g_return_val_if_fail (ATK_IS_RELATION_SET (set), 0);
228 if (set->relations == NULL)
231 return set->relations->len;
235 * atk_relation_set_get_relation:
236 * @set: an #AtkRelationSet
237 * @i: a gint representing a position in the set, starting from 0.
239 * Determines the relation at the specified position in the relation set.
241 * Returns: (transfer none): a #AtkRelation, which is the relation at
242 * position i in the set.
245 atk_relation_set_get_relation (AtkRelationSet *set,
248 GPtrArray *array_item;
251 g_return_val_if_fail (ATK_IS_RELATION_SET (set), NULL);
252 g_return_val_if_fail (i >= 0, NULL);
254 array_item = set->relations;
255 if (array_item == NULL)
257 item = g_ptr_array_index (array_item, i);
265 * atk_relation_set_get_relation_by_type:
266 * @set: an #AtkRelationSet
267 * @relationship: an #AtkRelationType
269 * Finds a relation that matches the specified type.
271 * Returns: (transfer none): an #AtkRelation, which is a relation matching the
275 atk_relation_set_get_relation_by_type (AtkRelationSet *set,
276 AtkRelationType relationship)
278 GPtrArray *array_item;
282 g_return_val_if_fail (ATK_IS_RELATION_SET (set), NULL);
284 array_item = set->relations;
285 if (array_item == NULL)
287 for (i = 0; i < array_item->len; i++)
289 item = g_ptr_array_index (array_item, i);
290 if (item->relationship == relationship)
297 atk_relation_set_finalize (GObject *object)
299 AtkRelationSet *relation_set;
303 g_return_if_fail (ATK_IS_RELATION_SET (object));
305 relation_set = ATK_RELATION_SET (object);
306 array = relation_set->relations;
310 for (i = 0; i < array->len; i++)
312 g_object_unref (g_ptr_array_index (array, i));
314 g_ptr_array_free (array, TRUE);
317 G_OBJECT_CLASS (parent_class)->finalize (object);
321 * atk_relation_set_add_relation_by_type:
322 * @set: an #AtkRelationSet
323 * @relationship: an #AtkRelationType
324 * @target: an #AtkObject
326 * Add a new relation of the specified type with the specified target to
327 * the current relation set if the relation set does not contain a relation
328 * of that type. If it is does contain a relation of that typea the target
329 * is added to the relation.
334 atk_relation_set_add_relation_by_type (AtkRelationSet *set,
335 AtkRelationType relationship,
338 AtkRelation *relation;
340 g_return_if_fail (ATK_IS_RELATION_SET (set));
341 g_return_if_fail (ATK_IS_OBJECT (target));
343 relation = atk_relation_set_get_relation_by_type (set,
347 atk_relation_add_target (relation, target);
351 /* the relation hasn't been created yet ... */
352 relation = atk_relation_new (&target, 1, relationship);
353 atk_relation_set_add (set, relation);
354 g_object_unref(relation);
359 * atk_relation_set_contains_target:
360 * @set: an #AtkRelationSet
361 * @relationship: an #AtkRelationType
362 * @target: an #AtkObject
364 * Determines whether the relation set contains a relation that
365 * matches the specified pair formed by type @relationship and object
368 * Returns: %TRUE if @set contains a relation with the relationship
369 * type @relationship with an object @target, %FALSE otherwise
373 atk_relation_set_contains_target (AtkRelationSet *set,
374 AtkRelationType relationship,
377 GPtrArray *array_relations;
378 GPtrArray *array_target;
379 AtkObject *current_target;
380 AtkRelation *relation;
384 g_return_val_if_fail (ATK_IS_RELATION_SET (set), FALSE);
385 g_return_val_if_fail (ATK_IS_OBJECT (target), FALSE);
387 array_relations = set->relations;
388 if (array_relations == NULL)
391 for (i = 0; i < array_relations->len; i++)
393 relation = g_ptr_array_index (array_relations, i);
394 if (relation->relationship == relationship)
396 array_target = atk_relation_get_target (relation);
397 for (c = 0; c < array_target->len; c++)
399 current_target = g_ptr_array_index (array_target, c);
400 if (target == current_target)