Merge branch 'improve-documentation' into 'master'
[atk.git] / atk / atkrelationset.c
blob95d50e66b905af27cdf6ca7cd2d3d8d9dd14d5ae
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 "config.h"
22 #include <glib-object.h>
24 #include "atk.h"
26 /**
27 * SECTION:atkrelationset
28 * @Short_description: A set of AtkRelations, normally the set of
29 * AtkRelations which an AtkObject has.
30 * @Title:AtkRelationSet
32 * The AtkRelationSet held by an object establishes its relationships
33 * with objects beyond the normal "parent/child" hierarchical
34 * relationships that all user interface objects have.
35 * AtkRelationSets establish whether objects are labelled or
36 * controlled by other components, share group membership with other
37 * components (for instance within a radio-button group), or share
38 * content which "flows" between them, among other types of possible
39 * relationships.
42 static gpointer parent_class = NULL;
44 static void atk_relation_set_class_init (AtkRelationSetClass *klass);
45 static void atk_relation_set_finalize (GObject *object);
47 GType
48 atk_relation_set_get_type (void)
50 static GType type = 0;
52 if (!type)
54 static const GTypeInfo typeInfo =
56 sizeof (AtkRelationSetClass),
57 (GBaseInitFunc) NULL,
58 (GBaseFinalizeFunc) NULL,
59 (GClassInitFunc) atk_relation_set_class_init,
60 (GClassFinalizeFunc) NULL,
61 NULL,
62 sizeof (AtkRelationSet),
64 (GInstanceInitFunc) NULL,
65 } ;
66 type = g_type_register_static (G_TYPE_OBJECT, "AtkRelationSet", &typeInfo, 0) ;
68 return type;
71 static void
72 atk_relation_set_class_init (AtkRelationSetClass *klass)
74 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
76 parent_class = g_type_class_peek_parent (klass);
78 gobject_class->finalize = atk_relation_set_finalize;
81 /**
82 * atk_relation_set_new:
84 * Creates a new empty relation set.
86 * Returns: a new #AtkRelationSet
87 **/
88 AtkRelationSet*
89 atk_relation_set_new (void)
91 AtkRelationSet *relation_set;
93 relation_set = g_object_new (ATK_TYPE_RELATION_SET, NULL);
94 return relation_set;
97 /**
98 * atk_relation_set_contains:
99 * @set: an #AtkRelationSet
100 * @relationship: an #AtkRelationType
102 * Determines whether the relation set contains a relation that matches the
103 * specified type.
105 * Returns: %TRUE if @relationship is the relationship type of a relation
106 * in @set, %FALSE otherwise
108 gboolean
109 atk_relation_set_contains (AtkRelationSet *set,
110 AtkRelationType relationship)
112 GPtrArray *array_item;
113 AtkRelation *item;
114 gint i;
116 g_return_val_if_fail (ATK_IS_RELATION_SET (set), FALSE);
118 array_item = set->relations;
119 if (array_item == NULL)
120 return FALSE;
121 for (i = 0; i < array_item->len; i++)
123 item = g_ptr_array_index (array_item, i);
124 if (item->relationship == relationship)
125 return TRUE;
127 return FALSE;
131 * atk_relation_set_remove:
132 * @set: an #AtkRelationSet
133 * @relation: an #AtkRelation
135 * Removes a relation from the relation set.
136 * This function unref's the #AtkRelation so it will be deleted unless there
137 * is another reference to it.
139 void
140 atk_relation_set_remove (AtkRelationSet *set,
141 AtkRelation *relation)
143 GPtrArray *array_item;
144 AtkRelationType relationship;
146 g_return_if_fail (ATK_IS_RELATION_SET (set));
148 array_item = set->relations;
149 if (array_item == NULL)
150 return;
152 if (g_ptr_array_remove (array_item, relation))
154 g_object_unref (relation);
156 else
158 relationship = atk_relation_get_relation_type (relation);
159 if (atk_relation_set_contains (set, relationship))
161 AtkRelation *exist_relation;
162 gint i;
163 exist_relation = atk_relation_set_get_relation_by_type (set, relationship);
164 for (i = 0; i < relation->target->len; i++)
166 AtkObject *target = g_ptr_array_index(relation->target, i);
167 atk_relation_remove_target (exist_relation, target);
174 * atk_relation_set_add:
175 * @set: an #AtkRelationSet
176 * @relation: an #AtkRelation
178 * Add a new relation to the current relation set if it is not already
179 * present.
180 * This function ref's the AtkRelation so the caller of this function
181 * should unref it to ensure that it will be destroyed when the AtkRelationSet
182 * is destroyed.
184 void
185 atk_relation_set_add (AtkRelationSet *set,
186 AtkRelation *relation)
188 AtkRelationType relationship;
190 g_return_if_fail (ATK_IS_RELATION_SET (set));
191 g_return_if_fail (relation != NULL);
193 if (set->relations == NULL)
195 set->relations = g_ptr_array_new ();
198 relationship = atk_relation_get_relation_type (relation);
199 if (!atk_relation_set_contains (set, relationship))
201 g_ptr_array_add (set->relations, relation);
202 g_object_ref (relation);
204 else
206 AtkRelation *exist_relation;
207 gint i;
208 exist_relation = atk_relation_set_get_relation_by_type (set, relationship);
209 for (i = 0; i < relation->target->len; i++)
211 AtkObject *target = g_ptr_array_index(relation->target, i);
212 atk_relation_add_target (exist_relation, target);
218 * atk_relation_set_get_n_relations:
219 * @set: an #AtkRelationSet
221 * Determines the number of relations in a relation set.
223 * Returns: an integer representing the number of relations in the set.
225 gint
226 atk_relation_set_get_n_relations (AtkRelationSet *set)
228 g_return_val_if_fail (ATK_IS_RELATION_SET (set), 0);
230 if (set->relations == NULL)
231 return 0;
233 return set->relations->len;
237 * atk_relation_set_get_relation:
238 * @set: an #AtkRelationSet
239 * @i: a gint representing a position in the set, starting from 0.
241 * Determines the relation at the specified position in the relation set.
243 * Returns: (transfer none): a #AtkRelation, which is the relation at
244 * position i in the set.
246 AtkRelation*
247 atk_relation_set_get_relation (AtkRelationSet *set,
248 gint i)
250 GPtrArray *array_item;
251 AtkRelation* item;
253 g_return_val_if_fail (ATK_IS_RELATION_SET (set), NULL);
254 g_return_val_if_fail (i >= 0, NULL);
256 array_item = set->relations;
257 if (array_item == NULL)
258 return NULL;
259 item = g_ptr_array_index (array_item, i);
260 if (item == NULL)
261 return NULL;
263 return item;
267 * atk_relation_set_get_relation_by_type:
268 * @set: an #AtkRelationSet
269 * @relationship: an #AtkRelationType
271 * Finds a relation that matches the specified type.
273 * Returns: (transfer none): an #AtkRelation, which is a relation matching the
274 * specified type.
276 AtkRelation*
277 atk_relation_set_get_relation_by_type (AtkRelationSet *set,
278 AtkRelationType relationship)
280 GPtrArray *array_item;
281 AtkRelation *item;
282 gint i;
284 g_return_val_if_fail (ATK_IS_RELATION_SET (set), NULL);
286 array_item = set->relations;
287 if (array_item == NULL)
288 return NULL;
289 for (i = 0; i < array_item->len; i++)
291 item = g_ptr_array_index (array_item, i);
292 if (item->relationship == relationship)
293 return item;
295 return NULL;
298 static void
299 atk_relation_set_finalize (GObject *object)
301 AtkRelationSet *relation_set;
302 GPtrArray *array;
303 gint i;
305 g_return_if_fail (ATK_IS_RELATION_SET (object));
307 relation_set = ATK_RELATION_SET (object);
308 array = relation_set->relations;
310 if (array)
312 for (i = 0; i < array->len; i++)
314 g_object_unref (g_ptr_array_index (array, i));
316 g_ptr_array_free (array, TRUE);
319 G_OBJECT_CLASS (parent_class)->finalize (object);
323 * atk_relation_set_add_relation_by_type:
324 * @set: an #AtkRelationSet
325 * @relationship: an #AtkRelationType
326 * @target: an #AtkObject
328 * Add a new relation of the specified type with the specified target to
329 * the current relation set if the relation set does not contain a relation
330 * of that type. If it is does contain a relation of that typea the target
331 * is added to the relation.
333 * Since: 1.9
335 void
336 atk_relation_set_add_relation_by_type (AtkRelationSet *set,
337 AtkRelationType relationship,
338 AtkObject *target)
340 AtkRelation *relation;
342 g_return_if_fail (ATK_IS_RELATION_SET (set));
343 g_return_if_fail (ATK_IS_OBJECT (target));
345 relation = atk_relation_set_get_relation_by_type (set,
346 relationship);
347 if (relation)
349 atk_relation_add_target (relation, target);
351 else
353 /* the relation hasn't been created yet ... */
354 relation = atk_relation_new (&target, 1, relationship);
355 atk_relation_set_add (set, relation);
356 g_object_unref(relation);
361 * atk_relation_set_contains_target:
362 * @set: an #AtkRelationSet
363 * @relationship: an #AtkRelationType
364 * @target: an #AtkObject
366 * Determines whether the relation set contains a relation that
367 * matches the specified pair formed by type @relationship and object
368 * @target.
370 * Returns: %TRUE if @set contains a relation with the relationship
371 * type @relationship with an object @target, %FALSE otherwise
374 gboolean
375 atk_relation_set_contains_target (AtkRelationSet *set,
376 AtkRelationType relationship,
377 AtkObject *target)
379 GPtrArray *array_relations;
380 GPtrArray *array_target;
381 AtkObject *current_target;
382 AtkRelation *relation;
383 gint i;
384 gint c;
386 g_return_val_if_fail (ATK_IS_RELATION_SET (set), FALSE);
387 g_return_val_if_fail (ATK_IS_OBJECT (target), FALSE);
389 array_relations = set->relations;
390 if (array_relations == NULL)
391 return FALSE;
393 for (i = 0; i < array_relations->len; i++)
395 relation = g_ptr_array_index (array_relations, i);
396 if (relation->relationship == relationship)
398 array_target = atk_relation_get_target (relation);
399 for (c = 0; c < array_target->len; c++)
401 current_target = g_ptr_array_index (array_target, c);
402 if (target == current_target)
403 return TRUE;
408 return FALSE;