Bug 503071 – Application direction changes to right to left even if
authorBehdad Esfahbod <behdad@gnome.org>
Wed, 11 Jun 2008 23:37:49 +0000 (23:37 +0000)
committerBehdad Esfahbod <behdad@src.gnome.org>
Wed, 11 Jun 2008 23:37:49 +0000 (23:37 +0000)
2008-06-11  Behdad Esfahbod  <behdad@gnome.org>

        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
docs/reference/ChangeLog
docs/reference/glib/glib-sections.txt
glib/gfileutils.c
glib/gi18n-lib.h
glib/glib.symbols
glib/goption.c
glib/gstrfuncs.c
glib/gstrfuncs.h
glib/gutils.c

index 4dafd60..44d0df1 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,19 @@
+2008-06-11  Behdad Esfahbod  <behdad@gnome.org>
+
+       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  <mclasen@redhat.com>
 
        Bug 502511 – g_assert_cmphex prints invalid message
index 2733636..2a66d9a 100644 (file)
@@ -1,3 +1,7 @@
+2008-06-11  Behdad Esfahbod  <behdad@gnome.org>
+
+       * glib/glib-sections.txt: Add g_dgettext() and g_dngettext().
+
 2008-06-11  Matthias Clasen  <mclasen@redhat.com>
 
        Bug 535418 – Please document which glib version defines goffset
index 2dd6ec9..d85930e 100644 (file)
@@ -2498,8 +2498,10 @@ g_unichar_to_utf8
 Q_
 C_
 N_
-g_strip_context
+g_dgettext
+g_dngettext
 g_dpgettext
+g_strip_context
 <SUBSECTION>
 g_get_language_names
 </SECTION>
index e0f85ff..000e980 100644 (file)
@@ -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;
index 0d67017..f5bcc18 100644 (file)
@@ -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)
index 55278cd..c201aed 100644 (file)
@@ -1148,6 +1148,8 @@ g_strdown
 #endif
 g_strv_length
 g_strip_context
+g_dgettext
+g_dngettext
 g_dpgettext
 #endif
 #endif
index f2f822e..5d3f684 100644 (file)
@@ -2058,7 +2058,7 @@ static gchar *
 dgettext_swapped (const gchar *msgid, 
                  const gchar *domainname)
 {
-  return dgettext (domainname, msgid);
+  return g_dgettext (domainname, msgid);
 }
 
 /**
index 74419d9..52595f3 100644 (file)
@@ -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:
+ * <itemizedlist>
+ * <listitem>@domain is not %NULL</listitem>
+ * <listitem>textdomain() has been called to set a default text domain</listitem>
+ * <listitem>there is no translations available for the default text domain
+ *           and the current locale</listitem>
+ * <listitem>current locale is not "C" or any English locales (those
+ *           starting with "en_")</listitem>
+ * </itemizedlist>
+ *
+ * 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"
index 0da475b..4875517 100644 (file)
@@ -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);
index b2b7dc1..225a9c2 100644 (file)
@@ -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