source: trunk/third/atk/atk/atkrelation.c @ 20776

Revision 20776, 11.2 KB checked in by ghudson, 20 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r20775, which included commits to RCS files with non-trunk default branches.
  • Property svn:executable set to *
Line 
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
26enum {
27  PROP_0,
28
29  PROP_RELATION_TYPE,
30  PROP_TARGET,
31  PROP_LAST
32};
33
34static GPtrArray *extra_names = NULL;
35
36static gpointer parent_class = NULL;
37 
38static void atk_relation_class_init   (AtkRelationClass *klass);
39static void atk_relation_finalize     (GObject          *object);
40static void atk_relation_set_property (GObject          *object,
41                                       guint            prop_id,
42                                       const GValue     *value,
43                                       GParamSpec       *pspec);
44static void atk_relation_get_property (GObject          *object,
45                                       guint            prop_id,
46                                       GValue           *value,
47                                       GParamSpec       *pspec);
48
49static GPtrArray* atk_relation_get_ptr_array_from_value_array (GValueArray *array);
50static GValueArray* atk_relation_get_value_array_from_ptr_array (GPtrArray *array);
51
52GType
53atk_relation_get_type (void)
54{
55  static GType type = 0;
56
57  if (!type)
58    {
59      static const GTypeInfo typeInfo =
60      {
61        sizeof (AtkRelationClass),
62        (GBaseInitFunc) NULL,
63        (GBaseFinalizeFunc) NULL,
64        (GClassInitFunc) atk_relation_class_init,
65        (GClassFinalizeFunc) NULL,
66        NULL,
67        sizeof (AtkRelation),
68        0,
69        (GInstanceInitFunc) NULL,
70      } ;
71      type = g_type_register_static (G_TYPE_OBJECT, "AtkRelation", &typeInfo, 0) ;
72    }
73  return type;
74}
75
76static void
77atk_relation_class_init (AtkRelationClass *klass)
78{
79  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
80
81  parent_class = g_type_class_peek_parent (klass);
82 
83  gobject_class->finalize = atk_relation_finalize;
84  gobject_class->set_property = atk_relation_set_property;
85  gobject_class->get_property = atk_relation_get_property;
86
87  g_object_class_install_property (gobject_class,
88                                   PROP_RELATION_TYPE,
89                                   g_param_spec_enum ("relation_type",
90                                                      "Relation Type",
91                                                      "The type of the relation",
92                                                      ATK_TYPE_RELATION_TYPE,
93                                                      ATK_RELATION_NULL,
94                                                      G_PARAM_READWRITE));
95  g_object_class_install_property (gobject_class,
96                                   PROP_TARGET,
97                                   g_param_spec_value_array ("target",
98                                                             "Target",
99                                                             "An array of the targets for the relation",
100                                                             NULL,
101
102                                                             G_PARAM_READWRITE));
103}
104
105/**
106 * atk_relation_type_register:
107 * @name: a name string
108 *
109 * Associate @name with a new #AtkRelationType
110 
111 * Returns: an #AtkRelationType associated with @name
112 **/
113AtkRelationType
114atk_relation_type_register (const gchar *name)
115{
116  g_return_val_if_fail (name, ATK_RELATION_NULL);
117
118  if (!extra_names)
119    extra_names = g_ptr_array_new ();
120
121  g_ptr_array_add (extra_names, g_strdup (name));
122  return extra_names->len + ATK_RELATION_LAST_DEFINED;
123}
124
125/**
126 * atk_relation_type_get_name:
127 * @type: The #AtkRelationType whose name is required
128 *
129 * Gets the description string describing the #AtkRelationType @type.
130 *
131 * Returns: the string describing the AtkRelationType
132 */
133G_CONST_RETURN gchar*
134atk_relation_type_get_name (AtkRelationType type)
135{
136  GTypeClass *type_class;
137  GEnumValue *value;
138  gchar *name = NULL;
139
140  type_class = g_type_class_ref (ATK_TYPE_RELATION_TYPE);
141  g_return_val_if_fail (G_IS_ENUM_CLASS (type_class), NULL);
142
143  value = g_enum_get_value (G_ENUM_CLASS (type_class), type);
144
145  if (value)
146    {
147      name = value->value_nick;
148    }
149  else
150    {
151      if (extra_names)
152        {
153          gint n = type;
154
155          n -= ATK_RELATION_LAST_DEFINED + 1;
156
157          if (n < extra_names->len)
158            name = g_ptr_array_index (extra_names, n);
159        }
160    }
161  g_type_class_unref (type_class);
162  return name;
163}
164
165/**
166 * atk_relation_type_for_name:
167 * @name: a string which is the (non-localized) name of an ATK relation type.
168 *
169 * Get the #AtkRelationType type corresponding to a relation name.
170 *
171 * Returns: the #AtkRelationType enumerated type corresponding to the specified name,
172 *          or #ATK_RELATION_NULL if no matching relation type is found.
173 **/
174AtkRelationType
175atk_relation_type_for_name (const gchar *name)
176{
177  GTypeClass *type_class;
178  GEnumValue *value;
179  AtkRelationType type = ATK_RELATION_NULL;
180
181  g_return_val_if_fail (name, ATK_RELATION_NULL);
182
183  type_class = g_type_class_ref (ATK_TYPE_RELATION_TYPE);
184  g_return_val_if_fail (G_IS_ENUM_CLASS (type_class), ATK_RELATION_NULL);
185
186  value = g_enum_get_value_by_nick (G_ENUM_CLASS (type_class), name);
187
188  if (value)
189    {
190      type = value->value;
191    }
192  else
193    {
194      gint i;
195
196      if (extra_names)
197        {
198          for (i = 0; i < extra_names->len; i++)
199            {
200              gchar *extra_name = (gchar *)g_ptr_array_index (extra_names, i);
201
202              g_return_val_if_fail (extra_name, ATK_RELATION_NULL);
203         
204              if (strcmp (name, extra_name) == 0)
205                {
206                  type = i + 1 + ATK_RELATION_LAST_DEFINED;
207                  break;
208                }
209            }
210        }
211    }
212  g_type_class_unref (type_class);
213 
214  return type;
215}
216
217
218/**
219 * atk_relation_new:
220 * @targets: an array of pointers to #AtkObjects 
221 * @n_targets: number of #AtkObjects pointed to by @targets
222 * @relationship: an #AtkRelationType with which to create the new
223 *  #AtkRelation
224 *
225 * Create a new relation for the specified key and the specified list
226 * of targets.
227 *
228 * Returns: a pointer to a new #AtkRelation
229 **/
230AtkRelation*
231atk_relation_new (AtkObject       **targets,
232                  gint            n_targets,
233                  AtkRelationType relationship)
234{
235  AtkRelation *relation;
236  int         i;
237  GValueArray *array;
238  GValue      *value;
239
240  g_return_val_if_fail (targets != NULL, NULL);
241
242  array = g_value_array_new (n_targets);
243  for (i = 0; i < n_targets; i++)
244  {
245    value = g_new0 (GValue, 1);
246    g_value_init (value, ATK_TYPE_OBJECT);
247    g_value_set_object (value, targets[i]);
248    array = g_value_array_append (array, value);
249    g_value_unset (value);
250    g_free (value);
251  }
252 
253  relation =  g_object_new (ATK_TYPE_RELATION,
254                            "relation_type", relationship,
255                            "target", array,
256                            NULL);
257
258  g_value_array_free (array);
259
260  return relation;
261}
262
263/**
264 * atk_relation_get_relation_type:
265 * @relation: an #AtkRelation
266 *
267 * Gets the type of @relation
268 *
269 * Returns: the type of @relation
270 **/
271AtkRelationType
272atk_relation_get_relation_type (AtkRelation *relation)
273{
274  g_return_val_if_fail (ATK_IS_RELATION (relation), 0);
275 
276  return relation->relationship;
277}
278
279/**
280 * atk_relation_get_target:
281 * @relation: an #AtkRelation
282 *
283 * Gets the target list of @relation
284 *
285 * Returns: the target list of @relation
286 **/
287GPtrArray*
288atk_relation_get_target (AtkRelation *relation)
289{
290  g_return_val_if_fail (ATK_IS_RELATION (relation), NULL);
291
292  return relation->target;
293}
294
295static void
296delete_object_while_in_relation (gpointer callback_data,
297                                 GObject *where_the_object_was)
298{
299  GPtrArray *array;
300
301  g_assert (callback_data != NULL);
302
303  array = callback_data;
304  g_ptr_array_remove (array, where_the_object_was);
305}
306
307static void
308atk_relation_finalize (GObject *object)
309{
310  AtkRelation        *relation;
311
312  g_return_if_fail (ATK_IS_RELATION (object));
313
314  relation = ATK_RELATION (object);
315
316  if (relation->target)
317  {
318    gint i;
319
320    for (i = 0; i < relation->target->len; i++)
321    {
322      g_object_weak_unref (G_OBJECT (g_ptr_array_index (relation->target, i)),
323                           (GWeakNotify) delete_object_while_in_relation,
324                           relation->target);
325    }
326    g_ptr_array_free (relation->target, TRUE);
327  }
328
329  G_OBJECT_CLASS (parent_class)->finalize (object);
330}
331
332static void
333atk_relation_set_property (GObject       *object,
334                           guint         prop_id,
335                           const GValue  *value,
336                           GParamSpec    *pspec)
337{
338  AtkRelation *relation;
339  gpointer boxed;
340
341  relation = ATK_RELATION (object);
342
343  switch (prop_id)
344    {
345    case PROP_RELATION_TYPE:
346      relation->relationship = g_value_get_enum (value);
347      break;
348    case PROP_TARGET:
349      boxed = g_value_get_boxed (value);
350      relation->target = atk_relation_get_ptr_array_from_value_array ( (GValueArray *) boxed);
351      break;
352    default:
353      break;
354    } 
355}
356
357static void
358atk_relation_get_property (GObject    *object,
359                           guint      prop_id,
360                           GValue     *value,
361                           GParamSpec *pspec)
362{
363  AtkRelation *relation;
364  GValueArray *array;
365
366  relation = ATK_RELATION (object);
367
368  switch (prop_id)
369    {
370    case PROP_RELATION_TYPE:
371      g_value_set_enum (value, relation->relationship);
372      break;
373    case PROP_TARGET:
374      array = atk_relation_get_value_array_from_ptr_array (relation->target);
375      g_value_set_boxed (value, array);
376      break;
377    default:
378      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
379      break;
380    } 
381}
382
383static GPtrArray*
384atk_relation_get_ptr_array_from_value_array (GValueArray *array)
385{
386  gint i;
387  GPtrArray *return_array;
388  GValue *value;
389  GObject *obj;
390
391  return_array = g_ptr_array_sized_new (array->n_values);
392  for (i = 0; i < array->n_values; i++)
393    {
394      value = g_value_array_get_nth (array, i);
395      obj = g_value_get_object (value);
396      g_ptr_array_add (return_array, obj);
397      g_object_weak_ref (obj, (GWeakNotify) delete_object_while_in_relation, return_array);
398    }
399     
400  return return_array;
401}
402
403static GValueArray*
404atk_relation_get_value_array_from_ptr_array (GPtrArray *array)
405{
406  int         i;
407  GValueArray *return_array;
408  GValue      *value;
409
410  return_array = g_value_array_new (array->len);
411  for (i = 0; i < array->len; i++)
412    {
413      value = g_new0 (GValue, 1);
414      g_value_init (value, ATK_TYPE_OBJECT);
415      g_value_set_object (value, g_ptr_array_index (array, i));
416      return_array = g_value_array_append (return_array, value);
417    }
418  return return_array;
419}
Note: See TracBrowser for help on using the repository browser.