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