Change atk_relation_type_from_string to atk_relation_type_for_name Add
[platform/upstream/atk.git] / atk / atkrelation.c
1 /* ATK -  Accessibility Toolkit
2  * Copyright 2001 Sun Microsystems Inc.
3  *
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.
8  *
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.
13  *
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.
18  */
19
20 #include <string.h>
21 #include <glib-object.h>
22 #include "atkobject.h"
23 #include "atkrelation.h"
24
25 static gchar *relation_names[ATK_RELATION_LAST_DEFINED] = {
26   "null",
27   "controlled_by",
28   "controller_for",
29   "label_for",
30   "labelled_by",
31   "member_of",
32   "node_child_of"
33 };
34
35 GPtrArray *extra_names = NULL;
36   
37 static void            atk_relation_class_init       (AtkRelationClass  *klass);
38 static void            atk_relation_finalize         (GObject           *object);
39
40 GType
41 atk_relation_get_type (void)
42 {
43   static GType type = 0;
44
45   if (!type)
46     {
47       static const GTypeInfo typeInfo =
48       {
49         sizeof (AtkRelationClass),
50         (GBaseInitFunc) NULL,
51         (GBaseFinalizeFunc) NULL,
52         (GClassInitFunc) atk_relation_class_init,
53         (GClassFinalizeFunc) NULL,
54         NULL,
55         sizeof (AtkRelation),
56         0,
57         (GInstanceInitFunc) NULL,
58       } ;
59       type = g_type_register_static (G_TYPE_OBJECT, "AtkRelation", &typeInfo, 0) ;
60     }
61   return type;
62 }
63
64 static void
65 atk_relation_class_init (AtkRelationClass *klass)
66 {
67   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
68
69   gobject_class->finalize = atk_relation_finalize;
70 }
71
72 /**
73  * atk_relation_type_register:
74  * @name: a name string
75  *
76  * Associate @name with a new #AtkRelationType
77  *
78  * Returns: an #AtkRelationType associated with @name
79  **/
80 AtkRelationType
81 atk_relation_type_register (const gchar *name)
82 {
83   g_return_val_if_fail (name, ATK_RELATION_NULL);
84
85   if (!extra_names)
86     extra_names = g_ptr_array_new ();
87
88   g_ptr_array_add (extra_names, g_strdup (name));
89   return extra_names->len + ATK_RELATION_LAST_DEFINED - 1;
90 }
91
92 /**
93  * atk_relation_type_get_name:
94  * @type: The #AtkRelationType whose name is required
95  *
96  * Gets the description string describing the #AtkRelationType @type.
97  *
98  * Returns: the string describing the AtkRelationType
99  */
100 G_CONST_RETURN gchar*
101 atk_relation_type_get_name (AtkRelationType type)
102 {
103   gint n;
104
105   n = type;
106
107   if (n >= 0)
108     {
109       if (n < ATK_RELATION_LAST_DEFINED)
110         return relation_names[n];
111       else if (extra_names)
112         {
113           n -= ATK_RELATION_LAST_DEFINED;
114
115           if (n < extra_names->len)
116             return g_ptr_array_index (extra_names, n);
117         }
118     }
119   return ATK_RELATION_NULL;
120
121 }
122
123 /**
124  * atk_relation_type_for_name:
125  * @name: a string which is the (non-localized) name of an ATK relation type.
126  *
127  * Get the #AtkRelationType type corresponding to a relation name.
128  *
129  * Returns: the #AtkRelationType enumerated type corresponding to the specified name,
130  *          or #ATK_RELATION_NULL if no matching relation type is found.
131  **/
132 AtkRelationType
133 atk_relation_type_for_name (const gchar *name)
134 {
135   gint i;
136
137   g_return_val_if_fail (name, ATK_RELATION_NULL);
138
139   for (i = 0; i < ATK_RELATION_LAST_DEFINED; i++)
140     {
141       if (strcmp (name, relation_names[i]) == 0)
142         return i;
143     }
144
145   if (extra_names)
146     {
147       for (i = 0; i < extra_names->len; i++)
148         {
149           gchar *extra_name = (gchar *)g_ptr_array_index (extra_names, i);
150
151           g_return_val_if_fail (extra_name, ATK_RELATION_NULL);
152          
153           if (strcmp (name, extra_name) == 0)
154             return i + ATK_RELATION_LAST_DEFINED;
155         }
156     }
157   return ATK_RELATION_NULL;
158 }
159
160
161 /**
162  * atk_relation_new:
163  * @targets: an array of pointers to #AtkObjects  
164  * @n_targets: number of #AtkObjects pointed to by @targets
165  * @relationship: an #AtkRelationType with which to create the new
166  *  #AtkRelation
167  *
168  * Create a new relation for the specified key and the specified list
169  * of targets.
170  *
171  * Returns: a pointer to a new #AtkRelation
172  **/
173 AtkRelation*
174 atk_relation_new (AtkObject       **targets,
175                   gint            n_targets,
176                   AtkRelationType relationship)
177 {
178   AtkRelation *relation;
179   int         i;
180   GPtrArray      *array;
181
182   g_return_val_if_fail (targets != NULL, NULL);
183
184   relation = g_object_new (ATK_TYPE_RELATION, NULL);
185   array = g_ptr_array_sized_new (n_targets);
186   for (i = 0; i < n_targets; i++)
187   {
188     /*
189      * Add a reference to AtkObject being added to a relation
190      */
191     g_object_ref (targets[i]);
192     g_ptr_array_add (array, targets[i]);
193   }
194   
195   relation->target = array;
196   relation->relationship = relationship;
197
198   return relation;
199 }
200
201 /**
202  * atk_relation_get_relation_type:
203  * @relation: an #AtkRelation 
204  *
205  * Gets the type of @relation
206  *
207  * Returns: the type of @relation
208  **/
209 AtkRelationType
210 atk_relation_get_relation_type (AtkRelation *relation)
211 {
212   g_return_val_if_fail (ATK_IS_RELATION (relation), 0);
213   
214   return relation->relationship;
215 }
216
217 /**
218  * atk_relation_get_target:
219  * @relation: an #AtkRelation
220  *
221  * Gets the target list of @relation
222  *
223  * Returns: the target list of @relation
224  **/
225 GPtrArray*
226 atk_relation_get_target (AtkRelation *relation)
227 {
228   g_return_val_if_fail (ATK_IS_RELATION (relation), FALSE);
229
230   return relation->target;
231 }
232
233 static void
234 atk_relation_finalize (GObject *object)
235 {
236   AtkRelation        *relation;
237
238   g_return_if_fail (ATK_IS_RELATION (object));
239
240   relation = ATK_RELATION (object);
241
242   if (relation->target)
243   {
244     gint i;
245
246     for (i = 0; i < relation->target->len; i++)
247     {
248       /*
249        * Remove a reference to AtkObject being removed from a relation
250        */
251       g_object_unref (g_ptr_array_index (relation->target, i));
252     }
253     g_ptr_array_free (relation->target, TRUE);
254   } 
255 }