]> rtime.felk.cvut.cz Git - sojka/lightdm.git/commitdiff
Language chooser modifications:
authorGunnar Hjalmarsson <ubuntu@gunnar.cc>
Tue, 29 Nov 2011 04:42:03 +0000 (15:42 +1100)
committerRobert Ancell <robert.ancell@canonical.com>
Tue, 29 Nov 2011 04:42:03 +0000 (15:42 +1100)
  * Save item that is selected from the language chooser also when AccountsService is in use.
  * Use nl_langinfo() to get language and country names for the language chooser labels.
  * Translate language and country names.
  * Handle @variants properly.

liblightdm-gobject/language.c
src/accounts.c
src/accounts.h
src/greeter.c

index edcf9974d990a002f701ef3e81a75fb1126d887b..f0c418a4271816df64fbbc3346c41da5a3172289 100644 (file)
@@ -12,6 +12,8 @@
 #include <string.h>
 #include <locale.h>
 #include <langinfo.h>
+#include <stdio.h>
+#include <glib/gi18n.h>
 
 #include "lightdm/language.h"
 
@@ -39,6 +41,7 @@ static GList *languages = NULL;
 static void
 update_languages (void)
 {
+    gchar *command = "locale -a";
     gchar *stdout_text = NULL, *stderr_text = NULL;
     gint exit_status;
     gboolean result;
@@ -47,14 +50,14 @@ update_languages (void)
     if (have_languages)
         return;
 
-    result = g_spawn_command_line_sync ("locale -a", &stdout_text, &stderr_text, &exit_status, &error);
+    result = g_spawn_command_line_sync (command, &stdout_text, &stderr_text, &exit_status, &error);
     if (error)
     {
-        g_warning ("Failed to run 'locale -a': %s", error->message);
+        g_warning ("Failed to run '%s': %s", command, error->message);
         g_clear_error (&error);
     }
     else if (exit_status != 0)
-        g_warning ("Failed to get languages, locale -a returned %d", exit_status);
+        g_warning ("Failed to get languages, '%s' returned %d", command, exit_status);
     else if (result)
     {
         gchar **tokens;
@@ -71,7 +74,7 @@ update_languages (void)
                 continue;
 
             /* Ignore the non-interesting languages */
-            if (strcmp (code, "C") == 0 || g_str_has_prefix (code, "C.") || strcmp (code, "POSIX") == 0)
+            if (strcmp (command, "locale -a") == 0 && !g_strrstr (code, ".utf8"))
                 continue;
 
             language = g_object_new (LIGHTDM_TYPE_LANGUAGE, "code", code, NULL);
@@ -87,6 +90,66 @@ update_languages (void)
     have_languages = TRUE;
 }
 
+static gboolean
+is_utf8 (const gchar *code)
+{
+    return g_strrstr (code, ".utf8") || g_strrstr (code, ".UTF-8");
+}
+
+/* Get a valid locale name that can be passed to setlocale(), so we always can use nl_langinfo() to get language and country names. */
+static gchar *
+get_locale_name (const gchar *code)
+{
+    gchar *locale = NULL, *language;
+    char *at;
+    static gchar **avail_locales;
+    gint i;
+
+    if (is_utf8 (code))
+        return (gchar *) code;
+
+    if ((at = strchr (code, '@')))
+        language = g_strndup (code, at - code);
+    else
+        language = g_strdup (code);
+
+    if (!avail_locales)
+    {
+        gchar *locales;
+        GError *error = NULL;
+
+        if (g_spawn_command_line_sync ("locale -a", &locales, NULL, NULL, &error))
+        {
+            avail_locales = g_strsplit (g_strchomp (locales), "\n", -1);
+            g_free (locales);
+        }
+        else
+        {
+            g_warning ("Failed to run 'locale -a': %s", error->message);
+            g_clear_error (&error);
+        }
+    }
+
+    if (avail_locales)
+    {
+        for (i = 0; avail_locales[i]; i++)
+        {
+            gchar *loc = avail_locales[i];
+            if (!g_strrstr (loc, ".utf8"))
+                continue;
+            if (g_str_has_prefix (loc, language))
+            {
+                locale = g_strdup (loc);
+                break;
+            }
+        }
+    }
+
+    g_free (language);
+
+    return locale;
+}
+
 /**
  * lightdm_get_language:
  *
@@ -162,16 +225,25 @@ lightdm_language_get_name (LightDMLanguage *language)
 
     if (!priv->name)
     {
-        char *current = setlocale(LC_ALL, NULL);
-        setlocale(LC_ALL, priv->code);
-#ifdef _NL_IDENTIFICATION_LANGUAGE
-        priv->name = g_strdup (nl_langinfo (_NL_IDENTIFICATION_LANGUAGE));
-#else
-        priv->name = g_strdup (priv->code);
-        if (strchr (priv->name, '_'))
-            *strchr (priv->name, '_') = '\0';
-#endif
-        setlocale(LC_ALL, current);
+        gchar *locale = get_locale_name (priv->code);
+        if (locale)
+        {
+            gchar *current = setlocale (LC_ALL, NULL);
+            setlocale (LC_IDENTIFICATION, locale);
+            setlocale (LC_MESSAGES, "");
+
+            gchar *language_en = nl_langinfo (_NL_IDENTIFICATION_LANGUAGE);
+            if (language_en && strlen (language_en) > 0)
+                priv->name = g_strdup (dgettext ("iso_639_3", language_en));
+
+            setlocale (LC_ALL, current);
+        }
+        if (!priv->name)
+        {
+            gchar **tokens = g_strsplit_set (priv->code, "_.@", 2);
+            priv->name = g_strdup (tokens[0]);
+            g_strfreev (tokens);
+        }
     }
 
     return priv->name;
@@ -194,34 +266,32 @@ lightdm_language_get_territory (LightDMLanguage *language)
 
     priv = GET_PRIVATE (language);
 
-    if (!priv->territory)
+    if (!priv->territory && strchr (priv->code, '_'))
     {
-        char *current = setlocale(LC_ALL, NULL);
-        setlocale(LC_ALL, priv->code);
-#ifdef _NL_IDENTIFICATION_TERRITORY
-        priv->territory = g_strdup (nl_langinfo (_NL_IDENTIFICATION_TERRITORY));
-#else
-        if (strchr (priv->code, '_'))
+        gchar *locale = get_locale_name (priv->code);
+        if (locale)
         {
-            priv->territory = g_strdup (strchr (priv->code, '_') + 1);
-            if (strchr (priv->territory, '.'))
-                *strchr (priv->territory, '.') = '\0';
-        }      
-        else
-            priv->territory = g_strdup ("");        
-#endif
-        setlocale(LC_ALL, current);
+            gchar *current = setlocale (LC_ALL, NULL);
+            setlocale (LC_IDENTIFICATION, locale);
+            setlocale (LC_MESSAGES, "");
+
+            gchar *country_en = nl_langinfo (_NL_IDENTIFICATION_TERRITORY);
+            if (country_en && strlen (country_en) > 0 && g_strcmp0 (country_en, "ISO") != 0)
+                priv->territory = g_strdup (dgettext ("iso_3166", country_en));
+
+            setlocale (LC_ALL, current);
+        }
+        if (!priv->territory)
+        {
+            gchar **tokens = g_strsplit_set (priv->code, "_.@", 3);
+            priv->territory = g_strdup (tokens[1]);
+            g_strfreev (tokens);
+        }
     }
 
     return priv->territory;
 }
 
-static gboolean
-is_utf8 (const gchar *code)
-{
-    return g_str_has_suffix (code, ".utf8") || g_str_has_suffix (code, ".UTF-8");
-}
-
 /**
  * lightdm_language_matches:
  * @language: A #LightDMLanguage
index 2504a48b7216d68d9b5dd0acbcd3def77d3473ba..cef5136e036785aeb5acafb2ab9a9f7e93748a24 100644 (file)
@@ -354,11 +354,14 @@ user_get_locale (User *user)
 }
 
 void
-user_set_locale (User *user, const gchar *locale)
+user_set_language (User *user, const gchar *language)
 {
     g_return_if_fail (user != NULL);
-    if (!user->priv->proxy)
-        save_string_to_dmrc (user->priv->name, "Desktop", "Language", locale);
+
+    if (user->priv->proxy)
+        call_method (user->priv->proxy, "SetLanguage", g_variant_new ("(s)", language), "()", NULL);
+    else
+        save_string_to_dmrc (user->priv->name, "Desktop", "Language", language);
 }
 
 void
index 03165b71c0f7c9e85a20aa6f3bf819718051d17e..8bd5247978c5bcf1f19f8a2a91eca04dd88aa907 100644 (file)
@@ -60,7 +60,7 @@ void user_set_xsession (User *user, const gchar *session);
 
 const gchar *user_get_locale (User *user);
 
-void user_set_locale (User *user, const gchar *language);
+void user_set_language (User *user, const gchar *language);
 
 G_END_DECLS
 
index 0fb18ab8eeb435f40052d9ed014fc4749d48274d..68e3c567e02029a49f6e28620ff3d74205c8eb10 100644 (file)
@@ -442,7 +442,7 @@ handle_set_language (Greeter *greeter, const gchar *language)
 
     g_debug ("Greeter sets language %s", language);
     user = pam_session_get_user (greeter->priv->authentication);
-    user_set_locale (user, language);
+    user_set_language (user, language);
 }
 
 static guint32