From e0916c3f54502864142b66f9d801881ced52f44f Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 11 Jun 2008 23:37:49 +0000 Subject: [PATCH] =?UTF-8?q?Bug=20503071=20=E2=80=93=20Application=20direct?= =?UTF-8?q?ion=20changes=20to=20right=20to=20left=20even=20if?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 2008-06-11 Behdad Esfahbod Bug 503071 – Application direction changes to right to left even if theres no translation * glib/gi18n-lib.h: * glib/glib.symbols: * glib/gstrfuncs.h: * glib/gstrfuncs.c: Add new functions g_dgettext() and g_dngettext(). * glib/gutils.c (glib_gettext): * glib/gfileutils.c (g_format_size_for_display): * glib/goption.c (dgettext_swapped): Use the new functions. svn path=/trunk/; revision=7020 --- ChangeLog | 16 +++ docs/reference/ChangeLog | 4 + docs/reference/glib/glib-sections.txt | 4 +- glib/gfileutils.c | 2 +- glib/gi18n-lib.h | 2 +- glib/glib.symbols | 2 + glib/goption.c | 2 +- glib/gstrfuncs.c | 139 +++++++++++++++++++++++++- glib/gstrfuncs.h | 7 ++ glib/gutils.c | 2 +- 10 files changed, 171 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4dafd60c3..44d0df16d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,19 @@ +2008-06-11 Behdad Esfahbod + + Bug 503071 – Application direction changes to right to left even if + theres no translation + + * glib/gi18n-lib.h: + * glib/glib.symbols: + * glib/gstrfuncs.h: + * glib/gstrfuncs.c: + Add new functions g_dgettext() and g_dngettext(). + + * glib/gutils.c (glib_gettext): + * glib/gfileutils.c (g_format_size_for_display): + * glib/goption.c (dgettext_swapped): + Use the new functions. + 2008-06-11 Matthias Clasen Bug 502511 – g_assert_cmphex prints invalid message diff --git a/docs/reference/ChangeLog b/docs/reference/ChangeLog index 27336367b..2a66d9ac6 100644 --- a/docs/reference/ChangeLog +++ b/docs/reference/ChangeLog @@ -1,3 +1,7 @@ +2008-06-11 Behdad Esfahbod + + * glib/glib-sections.txt: Add g_dgettext() and g_dngettext(). + 2008-06-11 Matthias Clasen Bug 535418 – Please document which glib version defines goffset diff --git a/docs/reference/glib/glib-sections.txt b/docs/reference/glib/glib-sections.txt index 2dd6ec941..d85930eee 100644 --- a/docs/reference/glib/glib-sections.txt +++ b/docs/reference/glib/glib-sections.txt @@ -2498,8 +2498,10 @@ g_unichar_to_utf8 Q_ C_ N_ -g_strip_context +g_dgettext +g_dngettext g_dpgettext +g_strip_context g_get_language_names diff --git a/glib/gfileutils.c b/glib/gfileutils.c index e0f85ff0b..000e9802f 100644 --- a/glib/gfileutils.c +++ b/glib/gfileutils.c @@ -1823,7 +1823,7 @@ char * g_format_size_for_display (goffset size) { if (size < (goffset) KILOBYTE_FACTOR) - return g_strdup_printf (dngettext(GETTEXT_PACKAGE, "%u byte", "%u bytes",(guint) size), (guint) size); + return g_strdup_printf (g_dngettext(GETTEXT_PACKAGE, "%u byte", "%u bytes",(guint) size), (guint) size); else { gdouble displayed_size; diff --git a/glib/gi18n-lib.h b/glib/gi18n-lib.h index 0d6701756..f5bcc180d 100644 --- a/glib/gi18n-lib.h +++ b/glib/gi18n-lib.h @@ -28,7 +28,7 @@ #error You must define GETTEXT_PACKAGE before including gi18n-lib.h. #endif -#define _(String) dgettext (GETTEXT_PACKAGE, String) +#define _(String) ((char *) g_dgettext (GETTEXT_PACKAGE, String)) #define Q_(String) g_dpgettext (GETTEXT_PACKAGE, String, 0) #define N_(String) (String) #define C_(Context,String) g_dpgettext (GETTEXT_PACKAGE, Context "\004" String, strlen (Context) + 1) diff --git a/glib/glib.symbols b/glib/glib.symbols index 55278cd39..c201aed9b 100644 --- a/glib/glib.symbols +++ b/glib/glib.symbols @@ -1148,6 +1148,8 @@ g_strdown #endif g_strv_length g_strip_context +g_dgettext +g_dngettext g_dpgettext #endif #endif diff --git a/glib/goption.c b/glib/goption.c index f2f822eee..5d3f68421 100644 --- a/glib/goption.c +++ b/glib/goption.c @@ -2058,7 +2058,7 @@ static gchar * dgettext_swapped (const gchar *msgid, const gchar *domainname) { - return dgettext (domainname, msgid); + return g_dgettext (domainname, msgid); } /** diff --git a/glib/gstrfuncs.c b/glib/gstrfuncs.c index 74419d9ad..52595f3ac 100644 --- a/glib/gstrfuncs.c +++ b/glib/gstrfuncs.c @@ -2853,7 +2853,7 @@ g_strv_length (gchar **str_array) * by a \004 character * @msgidoffset: the offset of the message id in @msgctxid * - * This function is a variant of dgettext() which supports + * This function is a variant of g_dgettext() which supports * a disambiguating message context. GNU gettext uses the * '\004' character to separate the message context and * message id in @msgctxtid. @@ -2861,6 +2861,9 @@ g_strv_length (gchar **str_array) * trying to use the deprecated convention of using "|" as a separation * character. * + * This uses g_dgettext() internally. See that functions for differences + * with dgettext() proper. + * * Applications should normally not use this function directly, * but use the C_() macro for translations with context. * @@ -2868,7 +2871,7 @@ g_strv_length (gchar **str_array) * * Since: 2.16 */ -const gchar * +G_CONST_RETURN gchar * g_dpgettext (const gchar *domain, const gchar *msgctxtid, gsize msgidoffset) @@ -2876,7 +2879,7 @@ g_dpgettext (const gchar *domain, const gchar *translation; gchar *sep; - translation = dgettext (domain, msgctxtid); + translation = g_dgettext (domain, msgctxtid); if (translation == msgctxtid) { @@ -2894,7 +2897,7 @@ g_dpgettext (const gchar *domain, strcpy (tmp, msgctxtid); tmp[sep - msgctxtid] = '\004'; - translation = dgettext (domain, tmp); + translation = g_dgettext (domain, tmp); if (translation == tmp) return sep + 1; @@ -2904,6 +2907,134 @@ g_dpgettext (const gchar *domain, return translation; } +static gboolean +_g_dgettext_should_translate (void) +{ + static gsize translate = 0; + enum { + SHOULD_TRANSLATE = 1, + SHOULD_NOT_TRANSLATE = 2 + }; + + if (G_UNLIKELY (g_once_init_enter (&translate))) + { + gboolean should_translate = TRUE; + + const char *default_domain = textdomain (NULL); + const char *translator_comment = gettext (""); + const char *translate_locale = setlocale (LC_MESSAGES, NULL); + + /* We should NOT translate only if all the following hold: + * - user has called textdomain() and set textdomain to non-default + * - default domain has no translations + * - locale does not start with "en_" and is not "C" + * + * Rationale: + * - If text domain is still the default domain, maybe user calls + * it later. Continue with old behavior of translating. + * - If locale starts with "en_", we can continue using the + * translations even if the app doesn't have translations for + * this locale. That is, en_UK and en_CA for example. + * - If locale is "C", maybe user calls setlocale(LC_ALL,"") later. + * Continue with old behavior of translating. + */ + if (0 != strcmp (default_domain, "messages") && + '\0' == *translator_comment && + 0 != strncmp (translate_locale, "en_", 3) && + 0 != strcmp (translate_locale, "C")) + should_translate = FALSE; + + g_once_init_leave (&translate, + should_translate ? + SHOULD_TRANSLATE : + SHOULD_NOT_TRANSLATE); + } + + return translate == SHOULD_TRANSLATE; +} + +/** + * g_dgettext: + * @domain: the translation domain to use, or %NULL to use + * the domain set with textdomain() + * @msgid: message to translate + * + * This function is a wrapper of dgettext() which does not translate + * the message if the default domain as set with textdomain() has no + * translations for the current locale. + * + * The advantage of using this function over dgettext() proper is that + * libraries using this function (like GTK+) will not use translations + * if the application using the library does not have translations for + * the current locale. This results in a consistent English-only + * interface instead of one having partial translations. For this + * feature to work, the call to textdomain() and setlocale() should + * precede any g_dgettext() invocations. For GTK+, it means calling + * textdomain() before gtk_init or its variants. + * + * This function disables translations if and only if upon its first + * call all the following conditions hold: + * + * @domain is not %NULL + * textdomain() has been called to set a default text domain + * there is no translations available for the default text domain + * and the current locale + * current locale is not "C" or any English locales (those + * starting with "en_") + * + * + * Note that this behavior may not be desired for example if an application + * has its untranslated messages in a language other than English. In those + * cases the application should call textdomain() after initializing GTK+. + * + * Applications should normally not use this function directly, + * but use the _() macro for translations. + * + * Returns: The translated string + * + * Since: 2.18 + */ +G_CONST_RETURN gchar * +g_dgettext (const gchar *domain, + const gchar *msgid) +{ + if (domain && G_UNLIKELY (!_g_dgettext_should_translate ())) + return msgid; + + return dgettext (domain, msgid); +} + +/** + * g_dngettext: + * @domain: the translation domain to use, or %NULL to use + * the domain set with textdomain() + * @msgid: message to translate + * @msgid_plural: plural form of the message + * @n: the quantity for which translation is needed + * + * This function is a wrapper of dngettext() which does not translate + * the message if the default domain as set with textdomain() has no + * translations for the current locale. + * + * See g_dgettext() for details of how this differs from dngettext() + * proper. + * + * Returns: The translated string + * + * Since: 2.18 + */ +G_CONST_RETURN gchar * +g_dngettext (const gchar *domain, + const gchar *msgid, + const gchar *msgid_plural, + gulong n) +{ + if (domain && G_UNLIKELY (!_g_dgettext_should_translate ())) + return n == 1 ? msgid : msgid_plural; + + return dngettext (domain, msgid, msgid_plural, n); +} + #define __G_STRFUNCS_C__ #include "galiasdef.c" diff --git a/glib/gstrfuncs.h b/glib/gstrfuncs.h index 0da475b28..4875517b7 100644 --- a/glib/gstrfuncs.h +++ b/glib/gstrfuncs.h @@ -247,6 +247,13 @@ gchar* g_stpcpy (gchar *dest, G_CONST_RETURN gchar *g_strip_context (const gchar *msgid, const gchar *msgval); +G_CONST_RETURN gchar *g_dgettext (const gchar *domain, + const gchar *msgid); + +G_CONST_RETURN gchar *g_dngettext (const gchar *domain, + const gchar *msgid, + const gchar *msgid_plural, + gulong n); G_CONST_RETURN gchar *g_dpgettext (const gchar *domain, const gchar *msgctxtid, gsize msgidoffset); diff --git a/glib/gutils.c b/glib/gutils.c index b2b7dc156..225a9c2bf 100644 --- a/glib/gutils.c +++ b/glib/gutils.c @@ -3283,7 +3283,7 @@ glib_gettext (const gchar *str) _glib_gettext_initialized = TRUE; } - return dgettext (GETTEXT_PACKAGE, str); + return g_dgettext (GETTEXT_PACKAGE, str); } #ifdef G_OS_WIN32