1
/* ATK -  Accessibility Toolkit
2
 * Copyright 2001, 2002, 2003 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 "config.h"
21

            
22
#include <glib/gi18n-lib.h>
23
#include <string.h>
24

            
25
#include "atk-enum-types.h"
26
#include "atkmarshal.h"
27
#include "atkprivate.h"
28
#include "atkvalue.h"
29

            
30
/**
31
 * AtkValue:
32
 *
33
 * The ATK interface implemented by valuators and components which display or select a value from a bounded range of values.
34
 *
35
 * #AtkValue should be implemented for components which either display
36
 * a value from a bounded range, or which allow the user to specify a
37
 * value from a bounded range, or both. For instance, most sliders and
38
 * range controls, as well as dials, should have #AtkObject
39
 * representations which implement #AtkValue on the component's
40
 * behalf. #AtKValues may be read-only, in which case attempts to
41
 * alter the value return would fail.
42
 *
43
 * <refsect1 id="current-value-text">
44
 * <title>On the subject of current value text</title>
45
 * <para>
46
 * In addition to providing the current value, implementors can
47
 * optionally provide an end-user-consumable textual description
48
 * associated with this value. This description should be included
49
 * when the numeric value fails to convey the full, on-screen
50
 * representation seen by users.
51
 * </para>
52
 *
53
 * <example>
54
 * <title>Password strength</title>
55
 * A password strength meter whose value changes as the user types
56
 * their new password. Red is used for values less than 4.0, yellow
57
 * for values between 4.0 and 7.0, and green for values greater than
58
 * 7.0. In this instance, value text should be provided by the
59
 * implementor. Appropriate value text would be "weak", "acceptable,"
60
 * and "strong" respectively.
61
 * </example>
62
 *
63
 * A level bar whose value changes to reflect the battery charge. The
64
 * color remains the same regardless of the charge and there is no
65
 * on-screen text reflecting the fullness of the battery. In this
66
 * case, because the position within the bar is the only indication
67
 * the user has of the current charge, value text should not be
68
 * provided by the implementor.
69
 *
70
 * <refsect2 id="implementor-notes">
71
 * <title>Implementor Notes</title>
72
 * <para>
73
 * Implementors should bear in mind that assistive technologies will
74
 * likely prefer the value text provided over the numeric value when
75
 * presenting a widget's value. As a result, strings not intended for
76
 * end users should not be exposed in the value text, and strings
77
 * which are exposed should be localized. In the case of widgets which
78
 * display value text on screen, for instance through a separate label
79
 * in close proximity to the value-displaying widget, it is still
80
 * expected that implementors will expose the value text using the
81
 * above API.
82
 * </para>
83
 *
84
 * <para>
85
 * #AtkValue should NOT be implemented for widgets whose displayed
86
 * value is not reflective of a meaningful amount. For instance, a
87
 * progress pulse indicator whose value alternates between 0.0 and 1.0
88
 * to indicate that some process is still taking place should not
89
 * implement #AtkValue because the current value does not reflect
90
 * progress towards completion.
91
 * </para>
92
 * </refsect2>
93
 * </refsect1>
94
 *
95
 * <refsect1 id="ranges">
96
 * <title>On the subject of ranges</title>
97
 * <para>
98
 * In addition to providing the minimum and maximum values,
99
 * implementors can optionally provide details about subranges
100
 * associated with the widget. These details should be provided by the
101
 * implementor when both of the following are communicated visually to
102
 * the end user:
103
 * </para>
104
 * <itemizedlist>
105
 *   <listitem>The existence of distinct ranges such as "weak",
106
 *   "acceptable", and "strong" indicated by color, bar tick marks,
107
 *   and/or on-screen text.</listitem>
108
 *   <listitem>Where the current value stands within a given subrange,
109
 *   for instance illustrating progression from very "weak" towards
110
 *   nearly "acceptable" through changes in shade and/or position on
111
 *   the bar within the "weak" subrange.</listitem>
112
 * </itemizedlist>
113
 * <para>
114
 * If both of the above do not apply to the widget, it should be
115
 * sufficient to expose the numeric value, along with the value text
116
 * if appropriate, to make the widget accessible.
117
 * </para>
118
 *
119
 * <refsect2 id="ranges-implementor-notes">
120
 * <title>Implementor Notes</title>
121
 * <para>
122
 * If providing subrange details is deemed necessary, all possible
123
 * values of the widget are expected to fall within one of the
124
 * subranges defined by the implementor.
125
 * </para>
126
 * </refsect2>
127
 * </refsect1>
128
 *
129
 * <refsect1 id="localization">
130
 * <title>On the subject of localization of end-user-consumable text
131
 * values</title>
132
 * <para>
133
 * Because value text and subrange descriptors are human-consumable,
134
 * implementors are expected to provide localized strings which can be
135
 * directly presented to end users via their assistive technology. In
136
 * order to simplify this for implementors, implementors can use
137
 * atk_value_type_get_localized_name() with the following
138
 * already-localized constants for commonly-needed values can be used:
139
 * </para>
140
 *
141
 * <itemizedlist>
142
 *   <listitem>ATK_VALUE_VERY_WEAK</listitem>
143
 *   <listitem>ATK_VALUE_WEAK</listitem>
144
 *   <listitem>ATK_VALUE_ACCEPTABLE</listitem>
145
 *   <listitem>ATK_VALUE_STRONG</listitem>
146
 *   <listitem>ATK_VALUE_VERY_STRONG</listitem>
147
 *   <listitem>ATK_VALUE_VERY_LOW</listitem>
148
 *   <listitem>ATK_VALUE_LOW</listitem>
149
 *   <listitem>ATK_VALUE_MEDIUM</listitem>
150
 *   <listitem>ATK_VALUE_HIGH</listitem>
151
 *   <listitem>ATK_VALUE_VERY_HIGH</listitem>
152
 *   <listitem>ATK_VALUE_VERY_BAD</listitem>
153
 *   <listitem>ATK_VALUE_BAD</listitem>
154
 *   <listitem>ATK_VALUE_GOOD</listitem>
155
 *   <listitem>ATK_VALUE_VERY_GOOD</listitem>
156
 *   <listitem>ATK_VALUE_BEST</listitem>
157
 *   <listitem>ATK_VALUE_SUBSUBOPTIMAL</listitem>
158
 *   <listitem>ATK_VALUE_SUBOPTIMAL</listitem>
159
 *   <listitem>ATK_VALUE_OPTIMAL</listitem>
160
 * </itemizedlist>
161
 * <para>
162
 * Proposals for additional constants, along with their use cases,
163
 * should be submitted to the GNOME Accessibility Team.
164
 * </para>
165
 * </refsect1>
166
 *
167
 * <refsect1 id="changes">
168
 * <title>On the subject of changes</title>
169
 * <para>
170
 * Note that if there is a textual description associated with the new
171
 * numeric value, that description should be included regardless of
172
 * whether or not it has also changed.
173
 * </para>
174
 * </refsect1>
175
 */
176

            
177
static GPtrArray *value_type_names = NULL;
178

            
179
enum
180
{
181
  VALUE_CHANGED,
182
  LAST_SIGNAL
183
};
184

            
185
/* These are listed here for extraction by intltool */
186
#if 0
187
/* Translators: This string describes a range within value-related
188
 * widgets such as a password-strength meter. Note that what such a
189
 * widget presents is controlled by application developers. Thus
190
 * assistive technologies such as screen readers are expected to
191
 * present this string alone or as a token in a list.
192
 */
193
N_("very weak")
194
/* Translators: This string describes a range within value-related
195
 * widgets such as a password-strength meter. Note that what such a
196
 * widget presents is controlled by application developers. Thus
197
 * assistive technologies such as screen readers are expected to
198
 * present this string alone or as a token in a list.
199
 */
200
N_("weak")
201
/* Translators: This string describes a range within value-related
202
 * widgets such as a password-strength meter. Note that what such a
203
 * widget presents is controlled by application developers. Thus
204
 * assistive technologies such as screen readers are expected to
205
 * present this string alone or as a token in a list.
206
 */
207
N_("acceptable")
208
/* Translators: This string describes a range within value-related
209
 * widgets such as a password-strength meter. Note that what such a
210
 * widget presents is controlled by application developers. Thus
211
 * assistive technologies such as screen readers are expected to
212
 * present this string alone or as a token in a list.
213
 */
214
N_("strong")
215
/* Translators: This string describes a range within value-related
216
 * widgets such as a password-strength meter. Note that what such a
217
 * widget presents is controlled by application developers. Thus
218
 * assistive technologies such as screen readers are expected to
219
 * present this string alone or as a token in a list.
220
 */
221
N_("very strong")
222
/* Translators: This string describes a range within value-related
223
 * widgets such as a volume slider. Note that what such a widget
224
 * presents (e.g. temperature, volume, price) is controlled by
225
 * application developers. Thus assistive technologies such as screen
226
 * readers are expected to present this string alone or as a token in
227
 * a list.
228
 */
229
N_("very low")
230
/* Translators: This string describes a range within value-related
231
 * widgets such as a volume slider. Note that what such a widget
232
 * presents (e.g. temperature, volume, price) is controlled by
233
 * application developers. Thus assistive technologies such as screen
234
 * readers are expected to present this string alone or as a token in
235
 * a list.
236
 */
237
N_("medium")
238
/* Translators: This string describes a range within value-related
239
 * widgets such as a volume slider. Note that what such a widget
240
 * presents (e.g. temperature, volume, price) is controlled by
241
 * application developers. Thus assistive technologies such as screen
242
 * readers are expected to present this string alone or as a token in
243
 * a list.
244
 */
245
N_("high")
246
/* Translators: This string describes a range within value-related
247
 * widgets such as a volume slider. Note that what such a widget
248
 * presents (e.g. temperature, volume, price) is controlled by
249
 * application developers. Thus assistive technologies such as screen
250
 * readers are expected to present this string alone or as a token in
251
 * a list.
252
 */
253
N_("very high")
254
/* Translators: This string describes a range within value-related
255
 * widgets such as a hard drive usage. Note that what such a widget
256
 * presents (e.g. hard drive usage, network traffic) is controlled by
257
 * application developers. Thus assistive technologies such as screen
258
 * readers are expected to present this string alone or as a token in
259
 * a list.
260
 */
261
N_("very bad")
262
/* Translators: This string describes a range within value-related
263
 * widgets such as a hard drive usage. Note that what such a widget
264
 * presents (e.g. hard drive usage, network traffic) is controlled by
265
 * application developers. Thus assistive technologies such as screen
266
 * readers are expected to present this string alone or as a token in
267
 * a list.
268
 */
269
N_("bad")
270
/* Translators: This string describes a range within value-related
271
 * widgets such as a hard drive usage. Note that what such a widget
272
 * presents (e.g. hard drive usage, network traffic) is controlled by
273
 * application developers. Thus assistive technologies such as screen
274
 * readers are expected to present this string alone or as a token in
275
 * a list.
276
 */
277
N_("good")
278
/* Translators: This string describes a range within value-related
279
 * widgets such as a hard drive usage. Note that what such a widget
280
 * presents (e.g. hard drive usage, network traffic) is controlled by
281
 * application developers. Thus assistive technologies such as screen
282
 * readers are expected to present this string alone or as a token in
283
 * a list.
284
 */
285
N_("very good")
286
/* Translators: This string describes a range within value-related
287
 * widgets such as a hard drive usage. Note that what such a widget
288
 * presents (e.g. hard drive usage, network traffic) is controlled by
289
 * application developers. Thus assistive technologies such as screen
290
 * readers are expected to present this string alone or as a token in
291
 * a list.
292
 */
293
N_("best")
294
#endif
295

            
296
static void atk_value_base_init (AtkValueIface *class);
297

            
298
static guint atk_value_signals[LAST_SIGNAL] = { 0 };
299

            
300
GType
301
1928
atk_value_get_type (void)
302
{
303
  static GType type = 0;
304

            
305
1928
  if (!type)
306
    {
307
162
      GTypeInfo tinfo = {
308
        sizeof (AtkValueIface),
309
        (GBaseInitFunc) atk_value_base_init,
310
        (GBaseFinalizeFunc) NULL,
311

            
312
      };
313

            
314
162
      type = g_type_register_static (G_TYPE_INTERFACE, "AtkValue", &tinfo, 0);
315
    }
316

            
317
1928
  return type;
318
}
319

            
320
static void
321
331
atk_value_base_init (AtkValueIface *class)
322
{
323
  static gboolean initialized = FALSE;
324
331
  if (!initialized)
325
    {
326
      /**
327
       * AtkValue::value-changed:
328
       * @atkvalue: the object on which the signal was emitted.
329
       * @value: the new value in a numerical form.
330
       * @text: human readable text alternative (also called
331
       * description) of this object. NULL if not available.
332
       *
333
       * The 'value-changed' signal is emitted when the current value
334
       * that represent the object changes. @value is the numerical
335
       * representation of this new value.  @text is the human
336
       * readable text alternative of @value, and can be NULL if it is
337
       * not available. Note that if there is a textual description
338
       * associated with the new numeric value, that description
339
       * should be included regardless of whether or not it has also
340
       * changed.
341
       *
342
       * Example: a password meter whose value changes as the user
343
       * types their new password. Appropiate value text would be
344
       * "weak", "acceptable" and "strong".
345
       *
346
       * Since: 2.12
347
       */
348
162
      atk_value_signals[VALUE_CHANGED] =
349
162
          g_signal_new ("value_changed",
350
                        ATK_TYPE_VALUE,
351
                        G_SIGNAL_RUN_LAST,
352
                        0,
353
                        (GSignalAccumulator) NULL, NULL,
354
                        atk_marshal_VOID__DOUBLE_STRING,
355
                        G_TYPE_NONE,
356
                        2, G_TYPE_DOUBLE, G_TYPE_STRING);
357

            
358
162
      initialized = TRUE;
359
    }
360
331
}
361

            
362
/**
363
 * atk_value_get_current_value:
364
 * @obj: a GObject instance that implements AtkValueIface
365
 * @value: (out): a #GValue representing the current accessible value
366
 *
367
 * Gets the value of this object.
368
 *
369
 * Deprecated: Since 2.12. Use atk_value_get_value_and_text()
370
 * instead.
371
 **/
372
void
373
atk_value_get_current_value (AtkValue *obj,
374
                             GValue *value)
375
{
376
  AtkValueIface *iface;
377

            
378
  g_return_if_fail (value != NULL);
379
  g_return_if_fail (ATK_IS_VALUE (obj));
380

            
381
  iface = ATK_VALUE_GET_IFACE (obj);
382

            
383
  if (iface->get_current_value)
384
    {
385
      if (G_IS_VALUE (value))
386
        g_value_unset (value);
387
      else
388
        memset (value, 0, sizeof (*value));
389

            
390
      (iface->get_current_value) (obj, value);
391
    }
392
}
393

            
394
/**
395
 * atk_value_get_maximum_value:
396
 * @obj: a GObject instance that implements AtkValueIface
397
 * @value: (out): a #GValue representing the maximum accessible value
398
 *
399
 * Gets the maximum value of this object.
400
 *
401
 * Deprecated: Since 2.12. Use atk_value_get_range() instead.
402
 **/
403
void
404
atk_value_get_maximum_value (AtkValue *obj,
405
                             GValue *value)
406
{
407
  AtkValueIface *iface;
408

            
409
  g_return_if_fail (value != NULL);
410
  g_return_if_fail (ATK_IS_VALUE (obj));
411

            
412
  iface = ATK_VALUE_GET_IFACE (obj);
413

            
414
  if (iface->get_maximum_value)
415
    {
416
      if (G_IS_VALUE (value))
417
        g_value_unset (value);
418
      else
419
        memset (value, 0, sizeof (*value));
420

            
421
      (iface->get_maximum_value) (obj, value);
422
    }
423
}
424

            
425
/**
426
 * atk_value_get_minimum_value:
427
 * @obj: a GObject instance that implements AtkValueIface
428
 * @value: (out): a #GValue representing the minimum accessible value
429
 *
430
 * Gets the minimum value of this object.
431
 *
432
 * Deprecated: Since 2.12. Use atk_value_get_range() instead.
433
 **/
434
void
435
atk_value_get_minimum_value (AtkValue *obj,
436
                             GValue *value)
437
{
438
  AtkValueIface *iface;
439

            
440
  g_return_if_fail (value != NULL);
441
  g_return_if_fail (ATK_IS_VALUE (obj));
442

            
443
  iface = ATK_VALUE_GET_IFACE (obj);
444

            
445
  if (iface->get_minimum_value)
446
    {
447
      if (G_IS_VALUE (value))
448
        g_value_unset (value);
449
      else
450
        memset (value, 0, sizeof (*value));
451

            
452
      (iface->get_minimum_value) (obj, value);
453
    }
454
}
455

            
456
/**
457
 * atk_value_get_minimum_increment:
458
 * @obj: a GObject instance that implements AtkValueIface
459
 * @value: (out): a #GValue representing the minimum increment by which the accessible value may be changed
460
 *
461
 * Gets the minimum increment by which the value of this object may be changed.  If zero,
462
 * the minimum increment is undefined, which may mean that it is limited only by the
463
 * floating point precision of the platform.
464
 *
465
 * Since: 1.12
466
 *
467
 * Deprecated: Since 2.12. Use atk_value_get_increment() instead.
468
 **/
469
void
470
atk_value_get_minimum_increment (AtkValue *obj,
471
                                 GValue *value)
472
{
473
  AtkValueIface *iface;
474

            
475
  g_return_if_fail (value != NULL);
476
  g_return_if_fail (ATK_IS_VALUE (obj));
477

            
478
  iface = ATK_VALUE_GET_IFACE (obj);
479

            
480
  if (iface->get_minimum_increment)
481
    {
482
      if (G_IS_VALUE (value))
483
        g_value_unset (value);
484
      else
485
        memset (value, 0, sizeof (*value));
486

            
487
      (iface->get_minimum_increment) (obj, value);
488
    }
489
}
490

            
491
/**
492
 * atk_value_set_current_value:
493
 * @obj: a GObject instance that implements AtkValueIface
494
 * @value: a #GValue which is the desired new accessible value.
495
 *
496
 * Sets the value of this object.
497
 *
498
 * Returns: %TRUE if new value is successfully set, %FALSE otherwise.
499
 *
500
 * Deprecated: Since 2.12. Use atk_value_set_value() instead.
501
 **/
502
gboolean
503
atk_value_set_current_value (AtkValue *obj,
504
                             const GValue *value)
505
{
506
  AtkValueIface *iface;
507

            
508
  g_return_val_if_fail (ATK_IS_VALUE (obj), FALSE);
509
  g_return_val_if_fail (G_IS_VALUE (value), FALSE);
510

            
511
  iface = ATK_VALUE_GET_IFACE (obj);
512

            
513
  if (iface->set_current_value)
514
    return (iface->set_current_value) (obj, value);
515
  else
516
    return FALSE;
517
}
518

            
519
/**
520
 * atk_value_get_value_and_text:
521
 * @obj: a GObject instance that implements AtkValueIface
522
 * @value: (out): address of #gdouble to put the current value of @obj
523
 * @text: (out) (allow-none): address of #gchar to put the human
524
 * readable text alternative for @value
525
 *
526
 * Gets the current value and the human readable text alternative of
527
 * @obj. @text is a newly created string, that must be freed by the
528
 * caller. Can be NULL if no descriptor is available.
529
 *
530
 * Since: 2.12
531
 **/
532

            
533
void
534
3
atk_value_get_value_and_text (AtkValue *obj,
535
                              gdouble *value,
536
                              gchar **text)
537
{
538
  AtkValueIface *iface;
539

            
540
3
  g_return_if_fail (ATK_IS_VALUE (obj));
541

            
542
3
  iface = ATK_VALUE_GET_IFACE (obj);
543

            
544
3
  if (iface->get_value_and_text)
545
    {
546
3
      (iface->get_value_and_text) (obj, value, text);
547
    }
548
  else
549
    {
550
      *value = 0.0;
551
      if (text)
552
        *text = NULL;
553
    }
554
}
555

            
556
/**
557
 * atk_value_get_range:
558
 * @obj: a GObject instance that implements AtkValueIface
559
 *
560
 * Gets the range of this object.
561
 *
562
 * Returns: (nullable) (transfer full): a newly allocated #AtkRange
563
 * that represents the minimum, maximum and descriptor (if available)
564
 * of @obj. NULL if that range is not defined.
565
 *
566
 * Since: 2.12
567
 **/
568
AtkRange *
569
2
atk_value_get_range (AtkValue *obj)
570
{
571
  AtkValueIface *iface;
572

            
573
2
  g_return_val_if_fail (ATK_IS_VALUE (obj), NULL);
574

            
575
2
  iface = ATK_VALUE_GET_IFACE (obj);
576

            
577
2
  if (iface->get_range)
578
    {
579
2
      return (iface->get_range) (obj);
580
    }
581
  else
582
    return NULL;
583
}
584

            
585
/**
586
 * atk_value_get_increment:
587
 * @obj: a GObject instance that implements AtkValueIface
588
 *
589
 * Gets the minimum increment by which the value of this object may be
590
 * changed.  If zero, the minimum increment is undefined, which may
591
 * mean that it is limited only by the floating point precision of the
592
 * platform.
593
 *
594
 * Return value: the minimum increment by which the value of this
595
 * object may be changed. zero if undefined.
596
 *
597
 * Since: 2.12
598
 **/
599
gdouble
600
1
atk_value_get_increment (AtkValue *obj)
601
{
602
  AtkValueIface *iface;
603

            
604
1
  g_return_val_if_fail (ATK_IS_VALUE (obj), 0);
605

            
606
1
  iface = ATK_VALUE_GET_IFACE (obj);
607

            
608
1
  if (iface->get_increment)
609
    {
610
1
      return (iface->get_increment) (obj);
611
    }
612
  else
613
    return 0;
614
}
615

            
616
/**
617
 * atk_value_get_sub_ranges:
618
 * @obj: a GObject instance that implements AtkValueIface
619
 *
620
 * Gets the list of subranges defined for this object. See #AtkValue
621
 * introduction for examples of subranges and when to expose them.
622
 *
623
 * Returns: (element-type AtkRange) (transfer full): an #GSList of
624
 * #AtkRange which each of the subranges defined for this object. Free
625
 * the returns list with g_slist_free().
626
 *
627
 * Since: 2.12
628
 **/
629
GSList *
630
atk_value_get_sub_ranges (AtkValue *obj)
631
{
632
  AtkValueIface *iface;
633

            
634
  g_return_val_if_fail (ATK_IS_VALUE (obj), NULL);
635

            
636
  iface = ATK_VALUE_GET_IFACE (obj);
637

            
638
  if (iface->get_sub_ranges)
639
    {
640
      return (iface->get_sub_ranges) (obj);
641
    }
642
  else
643
    return NULL;
644
}
645

            
646
/**
647
 * atk_value_set_value:
648
 * @obj: a GObject instance that implements AtkValueIface
649
 * @new_value: a double which is the desired new accessible value.
650
 *
651
 * Sets the value of this object.
652
 *
653
 * This method is intended to provide a way to change the value of the
654
 * object. In any case, it is possible that the value can't be
655
 * modified (ie: a read-only component). If the value changes due this
656
 * call, it is possible that the text could change, and will trigger
657
 * an #AtkValue::value-changed signal emission.
658
 *
659
 * Note for implementors: the deprecated atk_value_set_current_value()
660
 * method returned TRUE or FALSE depending if the value was assigned
661
 * or not. In the practice several implementors were not able to
662
 * decide it, and returned TRUE in any case. For that reason it is not
663
 * required anymore to return if the value was properly assigned or
664
 * not.
665
 *
666
 * Since: 2.12
667
 **/
668
void
669
8
atk_value_set_value (AtkValue *obj,
670
                     const gdouble new_value)
671
{
672
  AtkValueIface *iface;
673

            
674
8
  g_return_if_fail (ATK_IS_VALUE (obj));
675

            
676
8
  iface = ATK_VALUE_GET_IFACE (obj);
677

            
678
8
  if (iface->set_value)
679
    {
680
8
      (iface->set_value) (obj, new_value);
681
    }
682
}
683

            
684
static void
685
1
initialize_value_type_names ()
686
{
687
  GTypeClass *enum_class;
688
  GEnumValue *enum_value;
689
  int i;
690
1
  gchar *value_type_name = NULL;
691

            
692
1
  if (value_type_names)
693
    return;
694

            
695
1
  value_type_names = g_ptr_array_new ();
696
1
  enum_class = g_type_class_ref (ATK_TYPE_VALUE_TYPE);
697
1
  if (!G_IS_ENUM_CLASS (enum_class))
698
    return;
699

            
700
16
  for (i = 0; i < ATK_VALUE_LAST_DEFINED; i++)
701
    {
702
15
      enum_value = g_enum_get_value (G_ENUM_CLASS (enum_class), i);
703
15
      value_type_name = g_strdup (enum_value->value_nick);
704
15
      _compact_name (value_type_name);
705
15
      g_ptr_array_add (value_type_names, value_type_name);
706
    }
707

            
708
1
  g_type_class_unref (enum_class);
709
}
710

            
711
/**
712
 * atk_value_type_get_name:
713
 * @value_type: The #AtkValueType whose name is required
714
 *
715
 * Gets the description string describing the #AtkValueType @value_type.
716
 *
717
 * Returns: the string describing the #AtkValueType
718
 */
719
const gchar *
720
7
atk_value_type_get_name (AtkValueType value_type)
721
{
722
  g_return_val_if_fail (value_type >= 0, NULL);
723

            
724
7
  if (!value_type_names)
725
1
    initialize_value_type_names ();
726

            
727
7
  if (value_type < value_type_names->len)
728
7
    return g_ptr_array_index (value_type_names, value_type);
729

            
730
  return NULL;
731
}
732

            
733
/**
734
 * atk_value_type_get_localized_name:
735
 * @value_type: The #AtkValueType whose localized name is required
736
 *
737
 * Gets the localized description string describing the #AtkValueType @value_type.
738
 *
739
 * Returns: the localized string describing the #AtkValueType
740
 **/
741
const gchar *
742
7
atk_value_type_get_localized_name (AtkValueType value_type)
743
{
744
7
  _gettext_initialization ();
745

            
746
7
  return dgettext (GETTEXT_PACKAGE, atk_value_type_get_name (value_type));
747
}