Revert "Revert "Merge remote-tracking branch 'origin/sandbox/mniesluchow/upstream_2_1...
[platform/upstream/atk.git] / atk / atkvalue.c
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 <string.h>
23 #include <glib/gi18n-lib.h>
24
25 #include "atkvalue.h"
26 #include "atkmarshal.h"
27 #include "atk-enum-types.h"
28 #include "atkprivate.h"
29
30 /**
31  * SECTION:atkvalue
32  * @Short_description: The ATK interface implemented by valuators and
33  *  components which display or select a value from a bounded range of
34  *  values.
35  * @Title:AtkValue
36  *
37  * #AtkValue should be implemented for components which either display
38  * a value from a bounded range, or which allow the user to specify a
39  * value from a bounded range, or both. For instance, most sliders and
40  * range controls, as well as dials, should have #AtkObject
41  * representations which implement #AtkValue on the component's
42  * behalf. #AtKValues may be read-only, in which case attempts to
43  * alter the value return would fail.
44  *
45  * <refsect1 id="current-value-text">
46  * <title>On the subject of current value text</title>
47  * <para>
48  * In addition to providing the current value, implementors can
49  * optionally provide an end-user-consumable textual description
50  * associated with this value. This description should be included
51  * when the numeric value fails to convey the full, on-screen
52  * representation seen by users.
53  * </para>
54  *
55  * <example>
56  * <title>Password strength</title>
57  * A password strength meter whose value changes as the user types
58  * their new password. Red is used for values less than 4.0, yellow
59  * for values between 4.0 and 7.0, and green for values greater than
60  * 7.0. In this instance, value text should be provided by the
61  * implementor. Appropriate value text would be "weak", "acceptable,"
62  * and "strong" respectively.
63  * </example>
64  *
65  * A level bar whose value changes to reflect the battery charge. The
66  * color remains the same regardless of the charge and there is no
67  * on-screen text reflecting the fullness of the battery. In this
68  * case, because the position within the bar is the only indication
69  * the user has of the current charge, value text should not be
70  * provided by the implementor.
71  *
72  * <refsect2 id="implementor-notes">
73  * <title>Implementor Notes</title>
74  * <para>
75  * Implementors should bear in mind that assistive technologies will
76  * likely prefer the value text provided over the numeric value when
77  * presenting a widget's value. As a result, strings not intended for
78  * end users should not be exposed in the value text, and strings
79  * which are exposed should be localized. In the case of widgets which
80  * display value text on screen, for instance through a separate label
81  * in close proximity to the value-displaying widget, it is still
82  * expected that implementors will expose the value text using the
83  * above API.
84  * </para>
85  *
86  * <para>
87  * #AtkValue should NOT be implemented for widgets whose displayed
88  * value is not reflective of a meaningful amount. For instance, a
89  * progress pulse indicator whose value alternates between 0.0 and 1.0
90  * to indicate that some process is still taking place should not
91  * implement #AtkValue because the current value does not reflect
92  * progress towards completion.
93  * </para>
94  * </refsect2>
95  * </refsect1>
96  *
97  * <refsect1 id="ranges">
98  * <title>On the subject of ranges</title>
99  * <para>
100  * In addition to providing the minimum and maximum values,
101  * implementors can optionally provide details about subranges
102  * associated with the widget. These details should be provided by the
103  * implementor when both of the following are communicated visually to
104  * the end user:
105  * </para>
106  * <itemizedlist>
107  *   <listitem>The existence of distinct ranges such as "weak",
108  *   "acceptable", and "strong" indicated by color, bar tick marks,
109  *   and/or on-screen text.</listitem>
110  *   <listitem>Where the current value stands within a given subrange,
111  *   for instance illustrating progression from very "weak" towards
112  *   nearly "acceptable" through changes in shade and/or position on
113  *   the bar within the "weak" subrange.</listitem>
114  * </itemizedlist>
115  * <para>
116  * If both of the above do not apply to the widget, it should be
117  * sufficient to expose the numeric value, along with the value text
118  * if appropriate, to make the widget accessible.
119  * </para>
120  *
121  * <refsect2 id="ranges-implementor-notes">
122  * <title>Implementor Notes</title>
123  * <para>
124  * If providing subrange details is deemed necessary, all possible
125  * values of the widget are expected to fall within one of the
126  * subranges defined by the implementor.
127  * </para>
128  * </refsect2>
129  * </refsect1>
130  *
131  * <refsect1 id="localization">
132  * <title>On the subject of localization of end-user-consumable text
133  * values</title>
134  * <para>
135  * Because value text and subrange descriptors are human-consumable,
136  * implementors are expected to provide localized strings which can be
137  * directly presented to end users via their assistive technology. In
138  * order to simplify this for implementors, implementors can use
139  * atk_value_type_get_localized_name() with the following
140  * already-localized constants for commonly-needed values can be used:
141  * </para>
142  *
143  * <itemizedlist>
144  *   <listitem>ATK_VALUE_VERY_WEAK</listitem>
145  *   <listitem>ATK_VALUE_WEAK</listitem>
146  *   <listitem>ATK_VALUE_ACCEPTABLE</listitem>
147  *   <listitem>ATK_VALUE_STRONG</listitem>
148  *   <listitem>ATK_VALUE_VERY_STRONG</listitem>
149  *   <listitem>ATK_VALUE_VERY_LOW</listitem>
150  *   <listitem>ATK_VALUE_LOW</listitem>
151  *   <listitem>ATK_VALUE_MEDIUM</listitem>
152  *   <listitem>ATK_VALUE_HIGH</listitem>
153  *   <listitem>ATK_VALUE_VERY_HIGH</listitem>
154  *   <listitem>ATK_VALUE_VERY_BAD</listitem>
155  *   <listitem>ATK_VALUE_BAD</listitem>
156  *   <listitem>ATK_VALUE_GOOD</listitem>
157  *   <listitem>ATK_VALUE_VERY_GOOD</listitem>
158  *   <listitem>ATK_VALUE_BEST</listitem>
159  *   <listitem>ATK_VALUE_SUBSUBOPTIMAL</listitem>
160  *   <listitem>ATK_VALUE_SUBOPTIMAL</listitem>
161  *   <listitem>ATK_VALUE_OPTIMAL</listitem>
162  * </itemizedlist>
163  * <para>
164  * Proposals for additional constants, along with their use cases,
165  * should be submitted to the GNOME Accessibility Team.
166  * </para>
167  * </refsect1>
168  *
169  * <refsect1 id="changes">
170  * <title>On the subject of changes</title>
171  * <para>
172  * Note that if there is a textual description associated with the new
173  * numeric value, that description should be included regardless of
174  * whether or not it has also changed.
175  * </para>
176  * </refsect1>
177  */
178
179 static GPtrArray *value_type_names = NULL;
180
181 enum {
182   VALUE_CHANGED,
183   LAST_SIGNAL
184 };
185
186 /* These are listed here for extraction by intltool */
187 #if 0
188 /* Translators: This string describes a range within value-related
189  * widgets such as a password-strength meter. Note that what such a
190  * widget presents is controlled by application developers. Thus
191  * assistive technologies such as screen readers are expected to
192  * present this string alone or as a token in a list.
193  */
194 N_("very weak")
195 /* Translators: This string describes a range within value-related
196  * widgets such as a password-strength meter. Note that what such a
197  * widget presents is controlled by application developers. Thus
198  * assistive technologies such as screen readers are expected to
199  * present this string alone or as a token in a list.
200  */
201 N_("weak")
202 /* Translators: This string describes a range within value-related
203  * widgets such as a password-strength meter. Note that what such a
204  * widget presents is controlled by application developers. Thus
205  * assistive technologies such as screen readers are expected to
206  * present this string alone or as a token in a list.
207  */
208 N_("acceptable")
209 /* Translators: This string describes a range within value-related
210  * widgets such as a password-strength meter. Note that what such a
211  * widget presents is controlled by application developers. Thus
212  * assistive technologies such as screen readers are expected to
213  * present this string alone or as a token in a list.
214  */
215 N_("strong")
216 /* Translators: This string describes a range within value-related
217  * widgets such as a password-strength meter. Note that what such a
218  * widget presents is controlled by application developers. Thus
219  * assistive technologies such as screen readers are expected to
220  * present this string alone or as a token in a list.
221  */
222 N_("very strong")
223 /* Translators: This string describes a range within value-related
224  * widgets such as a volume slider. Note that what such a widget
225  * presents (e.g. temperature, volume, price) is controlled by
226  * application developers. Thus assistive technologies such as screen
227  * readers are expected to present this string alone or as a token in
228  * a list.
229  */
230 N_("very low")
231 /* Translators: This string describes a range within value-related
232  * widgets such as a volume slider. Note that what such a widget
233  * presents (e.g. temperature, volume, price) is controlled by
234  * application developers. Thus assistive technologies such as screen
235  * readers are expected to present this string alone or as a token in
236  * a list.
237  */
238 N_("medium")
239 /* Translators: This string describes a range within value-related
240  * widgets such as a volume slider. Note that what such a widget
241  * presents (e.g. temperature, volume, price) is controlled by
242  * application developers. Thus assistive technologies such as screen
243  * readers are expected to present this string alone or as a token in
244  * a list.
245  */
246 N_("high")
247 /* Translators: This string describes a range within value-related
248  * widgets such as a volume slider. Note that what such a widget
249  * presents (e.g. temperature, volume, price) is controlled by
250  * application developers. Thus assistive technologies such as screen
251  * readers are expected to present this string alone or as a token in
252  * a list.
253  */
254 N_("very high")
255 /* Translators: This string describes a range within value-related
256  * widgets such as a hard drive usage. Note that what such a widget
257  * presents (e.g. hard drive usage, network traffic) is controlled by
258  * application developers. Thus assistive technologies such as screen
259  * readers are expected to present this string alone or as a token in
260  * a list.
261  */
262 N_("very bad")
263 /* Translators: This string describes a range within value-related
264  * widgets such as a hard drive usage. Note that what such a widget
265  * presents (e.g. hard drive usage, network traffic) is controlled by
266  * application developers. Thus assistive technologies such as screen
267  * readers are expected to present this string alone or as a token in
268  * a list.
269  */
270 N_("bad")
271 /* Translators: This string describes a range within value-related
272  * widgets such as a hard drive usage. Note that what such a widget
273  * presents (e.g. hard drive usage, network traffic) is controlled by
274  * application developers. Thus assistive technologies such as screen
275  * readers are expected to present this string alone or as a token in
276  * a list.
277  */
278 N_("good")
279 /* Translators: This string describes a range within value-related
280  * widgets such as a hard drive usage. Note that what such a widget
281  * presents (e.g. hard drive usage, network traffic) is controlled by
282  * application developers. Thus assistive technologies such as screen
283  * readers are expected to present this string alone or as a token in
284  * a list.
285  */
286 N_("very good")
287 /* Translators: This string describes a range within value-related
288  * widgets such as a hard drive usage. Note that what such a widget
289  * presents (e.g. hard drive usage, network traffic) is controlled by
290  * application developers. Thus assistive technologies such as screen
291  * readers are expected to present this string alone or as a token in
292  * a list.
293  */
294 N_("best")
295 #endif
296
297 static void atk_value_base_init (AtkValueIface *class);
298
299 static guint atk_value_signals[LAST_SIGNAL] = {0};
300
301 GType
302 atk_value_get_type (void)
303 {
304   static GType type = 0;
305
306   if (!type) {
307     GTypeInfo tinfo =
308     {
309       sizeof (AtkValueIface),
310       (GBaseInitFunc) atk_value_base_init,
311       (GBaseFinalizeFunc) NULL,
312
313     };
314
315     type = g_type_register_static (G_TYPE_INTERFACE, "AtkValue", &tinfo, 0);
316   }
317
318   return type;
319 }
320
321 static void
322 atk_value_base_init (AtkValueIface *class)
323 {
324   static gboolean initialized = FALSE;
325   if (!initialized)
326     {
327       /**
328        * AtkValue::value-changed:
329        * @atkvalue: the object on which the signal was emitted.
330        * @value: the new value in a numerical form.
331        * @text: human readable text alternative (also called
332        * description) of this object. NULL if not available.
333        *
334        * The 'value-changed' signal is emitted when the current value
335        * that represent the object changes. @value is the numerical
336        * representation of this new value.  @text is the human
337        * readable text alternative of @value, and can be NULL if it is
338        * not available. Note that if there is a textual description
339        * associated with the new numeric value, that description
340        * should be included regardless of whether or not it has also
341        * changed.
342        *
343        * Example: a password meter whose value changes as the user
344        * types their new password. Appropiate value text would be
345        * "weak", "acceptable" and "strong".
346        *
347        * Since: 2.12
348        */
349       atk_value_signals[VALUE_CHANGED] =
350         g_signal_new ("value_changed",
351                       ATK_TYPE_VALUE,
352                       G_SIGNAL_RUN_LAST,
353                       0,
354                       (GSignalAccumulator) NULL, NULL,
355                       atk_marshal_VOID__DOUBLE_STRING,
356                       G_TYPE_NONE,
357                       2, G_TYPE_DOUBLE, G_TYPE_STRING);
358
359       initialized = TRUE;
360     }
361 }
362
363 /**
364  * atk_value_get_current_value:
365  * @obj: a GObject instance that implements AtkValueIface
366  * @value: a #GValue representing the current accessible value
367  *
368  * Gets the value of this object.
369  *
370  * Deprecated: Since 2.12. Use atk_value_get_value_and_text()
371  * instead.
372  **/
373 void
374 atk_value_get_current_value (AtkValue *obj,
375                              GValue   *value)
376 {
377   AtkValueIface *iface;
378
379   g_return_if_fail (value != NULL);
380   g_return_if_fail (ATK_IS_VALUE (obj));
381
382   iface = ATK_VALUE_GET_IFACE (obj);
383
384   if (iface->get_current_value)
385     {
386       if (G_IS_VALUE (value))
387         g_value_unset (value);
388       else
389         memset (value, 0, sizeof (*value));
390
391       (iface->get_current_value) (obj, value);
392     }
393 }
394
395 /**
396  * atk_value_get_maximum_value:
397  * @obj: a GObject instance that implements AtkValueIface
398  * @value: a #GValue representing the maximum accessible value
399  *
400  * Gets the maximum value of this object.
401  *
402  * Deprecated: Since 2.12. Use atk_value_get_range() instead.
403  **/
404 void
405 atk_value_get_maximum_value  (AtkValue *obj,
406                               GValue   *value)
407 {
408   AtkValueIface *iface;
409
410   g_return_if_fail (value != NULL);
411   g_return_if_fail (ATK_IS_VALUE (obj));
412
413   iface = ATK_VALUE_GET_IFACE (obj);
414
415   if (iface->get_maximum_value)
416     {
417       if (G_IS_VALUE (value))
418         g_value_unset (value);
419       else
420         memset (value, 0, sizeof (*value));
421
422       (iface->get_maximum_value) (obj, value);
423     }
424 }
425
426 /**
427  * atk_value_get_minimum_value:
428  * @obj: a GObject instance that implements AtkValueIface
429  * @value: a #GValue representing the minimum accessible value
430  *
431  * Gets the minimum value of this object.
432  *
433  * Deprecated: Since 2.12. Use atk_value_get_range() instead.
434  **/
435 void
436 atk_value_get_minimum_value (AtkValue *obj,
437                              GValue   *value)
438 {
439   AtkValueIface *iface;
440
441   g_return_if_fail (value != NULL);
442   g_return_if_fail (ATK_IS_VALUE (obj));
443
444   iface = ATK_VALUE_GET_IFACE (obj);
445
446   if (iface->get_minimum_value)
447     {
448       if (G_IS_VALUE (value))
449         g_value_unset (value);
450       else
451         memset (value, 0, sizeof (*value));
452
453       (iface->get_minimum_value) (obj, value);
454     }
455 }
456
457 /**
458  * atk_value_get_minimum_increment:
459  * @obj: a GObject instance that implements AtkValueIface
460  * @value: a #GValue representing the minimum increment by which the accessible value may be changed
461  *
462  * Gets the minimum increment by which the value of this object may be changed.  If zero,
463  * the minimum increment is undefined, which may mean that it is limited only by the 
464  * floating point precision of the platform.
465  *
466  * Since: 1.12
467  *
468  * Deprecated: Since 2.12. Use atk_value_get_increment() instead.
469  **/
470 void
471 atk_value_get_minimum_increment (AtkValue *obj,
472                              GValue   *value)
473 {
474   AtkValueIface *iface;
475
476   g_return_if_fail (value != NULL);
477   g_return_if_fail (ATK_IS_VALUE (obj));
478
479   iface = ATK_VALUE_GET_IFACE (obj);
480
481   if (iface->get_minimum_increment)
482     {
483       if (G_IS_VALUE (value))
484         g_value_unset (value);
485       else
486         memset (value, 0, sizeof (*value));
487
488       (iface->get_minimum_increment) (obj, value);
489     }
490 }
491
492 /**
493  * atk_value_set_current_value:
494  * @obj: a GObject instance that implements AtkValueIface
495  * @value: a #GValue which is the desired new accessible value.
496  *
497  * Sets the value of this object.
498  *
499  * Returns: %TRUE if new value is successfully set, %FALSE otherwise.
500  *
501  * Deprecated: Since 2.12. Use atk_value_set_value() instead.
502  **/
503 gboolean
504 atk_value_set_current_value (AtkValue       *obj, 
505                              const GValue   *value)
506 {
507   AtkValueIface *iface;
508
509   g_return_val_if_fail (ATK_IS_VALUE (obj), FALSE);
510   g_return_val_if_fail (G_IS_VALUE (value), FALSE);
511
512   iface = ATK_VALUE_GET_IFACE (obj);
513
514   if (iface->set_current_value)
515     return (iface->set_current_value) (obj, value);
516   else
517     return FALSE;
518 }
519
520
521 /**
522  * atk_value_get_value_and_text:
523  * @obj: a GObject instance that implements AtkValueIface
524  * @value: (out): address of #gdouble to put the current value of @obj
525  * @text: (out) (allow-none): address of #gchar to put the human
526  * readable text alternative for @value
527  *
528  * Gets the current value and the human readable text alternative of
529  * @obj. @text is a newly created string, that must be freed by the
530  * caller. Can be NULL if not descriptor is available.
531  *
532  * Since: 2.12
533  **/
534
535 void
536 atk_value_get_value_and_text (AtkValue *obj,
537                               gdouble *value,
538                               gchar  **text)
539 {
540   AtkValueIface *iface;
541
542   g_return_if_fail (ATK_IS_VALUE (obj));
543
544   iface = ATK_VALUE_GET_IFACE (obj);
545
546   if (iface->get_value_and_text)
547     {
548       (iface->get_value_and_text) (obj, value, text);
549     }
550 }
551
552 /**
553  * atk_value_get_range:
554  * @obj: a GObject instance that implements AtkValueIface
555  *
556  * Gets the range of this object.
557  *
558  * Returns: (nullable) (transfer full): a newly allocated #AtkRange
559  * that represents the minimum, maximum and descriptor (if available)
560  * of @obj. NULL if that range is not defined.
561  *
562  * Since: 2.12
563  **/
564 AtkRange*
565 atk_value_get_range (AtkValue *obj)
566 {
567   AtkValueIface *iface;
568
569   g_return_val_if_fail (ATK_IS_VALUE (obj), NULL);
570
571   iface = ATK_VALUE_GET_IFACE (obj);
572
573   if (iface->get_range)
574     {
575       return (iface->get_range) (obj);
576     }
577   else
578     return NULL;
579 }
580
581 /**
582  * atk_value_get_increment:
583  * @obj: a GObject instance that implements AtkValueIface
584  *
585  * Gets the minimum increment by which the value of this object may be
586  * changed.  If zero, the minimum increment is undefined, which may
587  * mean that it is limited only by the floating point precision of the
588  * platform.
589  *
590  * Return value: the minimum increment by which the value of this
591  * object may be changed. zero if undefined.
592  *
593  * Since: 2.12
594  **/
595 gdouble
596 atk_value_get_increment (AtkValue *obj)
597 {
598   AtkValueIface *iface;
599
600   g_return_val_if_fail (ATK_IS_VALUE (obj), 0);
601
602   iface = ATK_VALUE_GET_IFACE (obj);
603
604   if (iface->get_increment)
605     {
606       return (iface->get_increment) (obj);
607     }
608   else
609     return 0;
610 }
611
612
613 /**
614  * atk_value_get_sub_ranges:
615  * @obj: a GObject instance that implements AtkValueIface
616  *
617  * Gets the list of subranges defined for this object. See #AtkValue
618  * introduction for examples of subranges and when to expose them.
619  *
620  * Returns: (element-type AtkRange) (transfer full): an #GSList of
621  * #AtkRange which each of the subranges defined for this object. Free
622  * the returns list with g_slist_free().
623  *
624  * Since: 2.12
625  **/
626 GSList*
627 atk_value_get_sub_ranges (AtkValue *obj)
628 {
629   AtkValueIface *iface;
630
631   g_return_val_if_fail (ATK_IS_VALUE (obj), NULL);
632
633   iface = ATK_VALUE_GET_IFACE (obj);
634
635   if (iface->get_sub_ranges)
636     {
637       return (iface->get_sub_ranges) (obj);
638     }
639   else
640     return NULL;
641 }
642
643 /**
644  * atk_value_set_value:
645  * @obj: a GObject instance that implements AtkValueIface
646  * @new_value: a double which is the desired new accessible value.
647  *
648  * Sets the value of this object.
649  *
650  * This method is intended to provide a way to change the value of the
651  * object. In any case, it is possible that the value can't be
652  * modified (ie: a read-only component). If the value changes due this
653  * call, it is possible that the text could change, and will trigger
654  * an #AtkValue::value-changed signal emission.
655  *
656  * Note for implementors: the deprecated atk_value_set_current_value()
657  * method returned TRUE or FALSE depending if the value was assigned
658  * or not. In the practice several implementors were not able to
659  * decide it, and returned TRUE in any case. For that reason it is not
660  * required anymore to return if the value was properly assigned or
661  * not.
662  *
663  * Since: 2.12
664  **/
665 void
666 atk_value_set_value (AtkValue     *obj,
667                      const gdouble new_value)
668 {
669   AtkValueIface *iface;
670
671   g_return_if_fail (ATK_IS_VALUE (obj));
672
673   iface = ATK_VALUE_GET_IFACE (obj);
674
675   if (iface->set_value)
676     {
677       (iface->set_value) (obj, new_value);
678     }
679 }
680
681 static void
682 initialize_value_type_names ()
683 {
684   GTypeClass *enum_class;
685   GEnumValue *enum_value;
686   int i;
687   gchar *value_type_name = NULL;
688
689   if (value_type_names)
690     return;
691
692   value_type_names = g_ptr_array_new ();
693   enum_class = g_type_class_ref (ATK_TYPE_VALUE_TYPE);
694   if (!G_IS_ENUM_CLASS(enum_class))
695     return;
696
697   for (i = 0; i < ATK_VALUE_LAST_DEFINED; i++)
698     {
699       enum_value = g_enum_get_value (G_ENUM_CLASS (enum_class), i);
700       value_type_name = g_strdup (enum_value->value_nick);
701       _compact_name (value_type_name);
702       g_ptr_array_add (value_type_names, value_type_name);
703     }
704
705   g_type_class_unref (enum_class);
706 }
707
708 /**
709  * atk_value_type_get_name:
710  * @role: The #AtkValueType whose name is required
711  *
712  * Gets the description string describing the #AtkValueType @value_type.
713  *
714  * Returns: the string describing the #AtkValueType
715  */
716 const gchar*
717 atk_value_type_get_name (AtkValueType value_type)
718 {
719   g_return_val_if_fail (value_type >= 0, NULL);
720
721   if (!value_type_names)
722     initialize_value_type_names ();
723
724   if (value_type < value_type_names->len)
725     return g_ptr_array_index (value_type_names, value_type);
726
727   return NULL;
728 }
729
730 /**
731  * atk_value_type_get_localized_name:
732  * @value_type: The #AtkValueType whose localized name is required
733  *
734  * Gets the localized description string describing the #AtkValueType @value_type.
735  *
736  * Returns: the localized string describing the #AtkValueType
737  **/
738 const gchar*
739 atk_value_type_get_localized_name (AtkValueType value_type)
740 {
741   _gettext_initialization ();
742
743   return dgettext (GETTEXT_PACKAGE, atk_value_type_get_name (value_type));
744 }