[gnome-initial-setup] language: Actually set the new language on the created user



commit 9e4f72d0da38d10d21bd3fef5845c3d17767c666
Author: Michael Wood <michael g wood intel com>
Date:   Wed Apr 24 20:13:41 2013 +0100

    language: Actually set the new language on the created user
    
    Also if the system mode is active set the system locale.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=698611

 configure.ac                                       |    2 +
 data/20-gnome-initial-setup.rules                  |    1 +
 gnome-initial-setup/gis-driver.c                   |   15 +++
 gnome-initial-setup/gis-driver.h                   |    5 +
 .../pages/account/gis-account-page.c               |    2 +
 .../pages/language/gis-language-page.c             |  134 +++++++++++++++++++-
 6 files changed, 155 insertions(+), 4 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 54f862f..fe4520f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -20,6 +20,7 @@ GTK_REQUIRED_VERSION=3.7.11
 PANGO_REQUIRED_VERSION=1.32.5
 IBUS_REQUIRED_VERSION=1.4.99
 GNOME_DESKTOP_REQUIRED_VERSION=3.7.5
+POLKIT_REQUIRED_VERSION=0.103
 
 # EggListBox submodule
 prev_top_build_prefix=$ac_top_build_prefix
@@ -35,6 +36,7 @@ PKG_CHECK_MODULES(INITIAL_SETUP,
                   libnm-glib >= $NETWORK_MANAGER_REQUIRED_VERSION
                   libnm-util >= $NETWORK_MANAGER_REQUIRED_VERSION
                   libnm-gtk >= $NETWORK_MANAGER_REQUIRED_VERSION
+                  polkit-gobject-1 >= $POLKIT_REQUIRED_VERSION
                   accountsservice
                   gnome-desktop-3.0 >= $GNOME_DESKTOP_REQUIRED_VERSION
                   gstreamer-1.0
diff --git a/data/20-gnome-initial-setup.rules b/data/20-gnome-initial-setup.rules
index 487fc63..826323c 100644
--- a/data/20-gnome-initial-setup.rules
+++ b/data/20-gnome-initial-setup.rules
@@ -10,6 +10,7 @@ polkit.addRule(function(action, subject) {
         return undefined;
 
     var actionMatches = (action.id === 'org.freedesktop.udisks2.filesystem-mount-system' ||
+                         action.id == 'org.freedesktop.set-locale' ||
                          action.id.indexOf('org.freedesktop.accounts.') === 0 ||
                          action.id.indexOf('org.freedesktop.timedate1.') === 0 ||
                          action.id.indexOf('org.freedesktop.RealtimeKit1.') === 0);
diff --git a/gnome-initial-setup/gis-driver.c b/gnome-initial-setup/gis-driver.c
index ee31c3b..49ca273 100644
--- a/gnome-initial-setup/gis-driver.c
+++ b/gnome-initial-setup/gis-driver.c
@@ -74,6 +74,7 @@ struct _GisDriverPrivate {
 
   ActUser *user_account;
   const gchar *user_password;
+  const gchar *lang_id;
 
   GisDriverMode mode;
 };
@@ -121,6 +122,20 @@ gis_driver_get_assistant (GisDriver *driver)
 }
 
 void
+gis_driver_set_user_language (GisDriver *driver, const gchar *lang_id)
+{
+  GisDriverPrivate *priv = driver->priv;
+  priv->lang_id = lang_id;
+}
+
+const gchar *
+gis_driver_get_user_language (GisDriver *driver)
+{
+  GisDriverPrivate *priv = driver->priv;
+  return priv->lang_id;
+}
+
+void
 gis_driver_set_user_permissions (GisDriver   *driver,
                                  ActUser     *user,
                                  const gchar *password)
diff --git a/gnome-initial-setup/gis-driver.h b/gnome-initial-setup/gis-driver.h
index 1ca43b8..e38f795 100644
--- a/gnome-initial-setup/gis-driver.h
+++ b/gnome-initial-setup/gis-driver.h
@@ -74,6 +74,11 @@ void gis_driver_get_user_permissions (GisDriver    *driver,
                                       ActUser     **user,
                                       const gchar **password);
 
+void gis_driver_set_user_language (GisDriver   *driver,
+                                   const gchar *lang_id);
+
+const gchar *gis_driver_get_user_language (GisDriver   *driver);
+
 GisDriverMode gis_driver_get_mode (GisDriver *driver);
 
 void gis_driver_add_page (GisDriver *driver,
diff --git a/gnome-initial-setup/pages/account/gis-account-page.c 
b/gnome-initial-setup/pages/account/gis-account-page.c
index 058d11f..ed0d20e 100644
--- a/gnome-initial-setup/pages/account/gis-account-page.c
+++ b/gnome-initial-setup/pages/account/gis-account-page.c
@@ -444,6 +444,8 @@ create_user (GisAccountPage *page)
   error = NULL;
 
   priv->act_user = act_user_manager_create_user (priv->act_client, username, fullname, priv->account_type, 
&error);
+  act_user_set_language (priv->act_user, gis_driver_get_user_language (GIS_PAGE (page)->driver));
+
   if (error != NULL) {
     g_warning ("Failed to create user: %s", error->message);
     g_error_free (error);
diff --git a/gnome-initial-setup/pages/language/gis-language-page.c 
b/gnome-initial-setup/pages/language/gis-language-page.c
index 5cbf4c8..4fce033 100644
--- a/gnome-initial-setup/pages/language/gis-language-page.c
+++ b/gnome-initial-setup/pages/language/gis-language-page.c
@@ -19,6 +19,9 @@
  *
  * Written by:
  *     Jasper St. Pierre <jstpierre mecheye net>
+ *     Michael Wood <michael g wood intel com>
+ *
+ * Based on gnome-control-center cc-region-panel.c
  */
 
 /* Language page {{{1 */
@@ -30,6 +33,8 @@
 #include "cc-language-chooser.h"
 #include "gis-language-page.h"
 
+#include <act/act-user-manager.h>
+#include <polkit/polkit.h>
 #include <locale.h>
 #include <gtk/gtk.h>
 
@@ -40,19 +45,110 @@ G_DEFINE_TYPE (GisLanguagePage, gis_language_page, GIS_TYPE_PAGE);
 struct _GisLanguagePagePrivate
 {
   GtkWidget *language_chooser;
+  GDBusProxy *localed;
+  GPermission *permission;
+  const gchar *new_locale_id;
+
+  GCancellable *cancellable;
 };
 
 #define OBJ(type,name) ((type)gtk_builder_get_object(GIS_PAGE (page)->builder,(name)))
 #define WID(name) OBJ(GtkWidget*,name)
 
 static void
+set_localed_locale (GisLanguagePage *self)
+{
+  GisLanguagePagePrivate *priv = self->priv;
+  GVariantBuilder *b;
+  gchar *s;
+
+  b = g_variant_builder_new (G_VARIANT_TYPE ("as"));
+  s = g_strconcat ("LANG=", priv->new_locale_id, NULL);
+  g_variant_builder_add (b, "s", s);
+  g_free (s);
+
+  g_dbus_proxy_call (priv->localed,
+                     "SetLocale",
+                     g_variant_new ("(asb)", b, TRUE),
+                     G_DBUS_CALL_FLAGS_NONE,
+                     -1, NULL, NULL, NULL);
+  g_variant_builder_unref (b);
+}
+
+static void
+change_locale_permission_acquired (GObject      *source,
+                                   GAsyncResult *res,
+                                   gpointer      data)
+{
+  GisLanguagePagePrivate *priv;
+  GError *error = NULL;
+  gboolean allowed;
+
+  priv = GIS_LANGUAGE_PAGE (data)->priv;
+
+  allowed = g_permission_acquire_finish (priv->permission, res, &error);
+  if (error) {
+      if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+        g_warning ("Failed to acquire permission: %s\n", error->message);
+      g_error_free (error);
+      return;
+  }
+
+  if (allowed)
+    set_localed_locale (GIS_LANGUAGE_PAGE (data));
+}
+
+static void
 language_changed (CcLanguageChooser  *chooser,
                   GParamSpec         *pspec,
                   GisLanguagePage    *page)
 {
-  const char *new_locale_id = cc_language_chooser_get_language (chooser);
-  setlocale (LC_MESSAGES, new_locale_id);
-  gis_driver_locale_changed (GIS_PAGE (page)->driver);
+  GisLanguagePagePrivate *priv = page->priv;
+  ActUser *user;
+  GisDriver *driver;
+
+  priv->new_locale_id = cc_language_chooser_get_language (chooser);
+  driver = GIS_PAGE (page)->driver;
+
+  setlocale (LC_MESSAGES, priv->new_locale_id);
+  gis_driver_locale_changed (driver);
+
+  if (gis_driver_get_mode (driver) == GIS_DRIVER_MODE_NEW_USER &&
+      g_permission_get_can_acquire (priv->permission)) {
+
+      g_permission_acquire_async (priv->permission,
+                                  NULL,
+                                  change_locale_permission_acquired,
+                                  page);
+  }
+  user = act_user_manager_get_user (act_user_manager_get_default (),
+                                    g_get_user_name ());
+  act_user_set_language (user, priv->new_locale_id);
+
+  gis_driver_set_user_language (driver, priv->new_locale_id);
+}
+
+static void
+localed_proxy_ready (GObject      *source,
+                     GAsyncResult *res,
+                     gpointer      data)
+{
+  GisLanguagePage *self = data;
+  GisLanguagePagePrivate *priv;
+  GDBusProxy *proxy;
+  GError *error = NULL;
+
+  proxy = g_dbus_proxy_new_finish (res, &error);
+
+  if (!proxy) {
+      if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+        g_warning ("Failed to contact localed: %s\n", error->message);
+      g_error_free (error);
+      return;
+  }
+
+  priv = self->priv;
+  priv->localed = proxy;
 }
 
 static void
@@ -60,6 +156,7 @@ gis_language_page_constructed (GObject *object)
 {
   GisLanguagePage *page = GIS_LANGUAGE_PAGE (object);
   GisLanguagePagePrivate *priv = page->priv;
+  GDBusConnection *bus;
 
   g_type_ensure (CC_TYPE_LANGUAGE_CHOOSER);
 
@@ -71,8 +168,26 @@ gis_language_page_constructed (GObject *object)
   g_signal_connect (priv->language_chooser, "notify::language",
                     G_CALLBACK (language_changed), page);
 
-  gis_page_set_complete (GIS_PAGE (page), TRUE);
 
+  /* If we're in new user mode then we're manipulating system settings */
+  if (gis_driver_get_mode (GIS_PAGE (page)->driver) == GIS_DRIVER_MODE_NEW_USER)
+    {
+      priv->permission = polkit_permission_new_sync ("org.freedesktop.locale1.set-locale", NULL, NULL, NULL);
+
+      bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL);
+      g_dbus_proxy_new (bus,
+                        G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES,
+                        NULL,
+                        "org.freedesktop.locale1",
+                        "/org/freedesktop/locale1",
+                        "org.freedesktop.locale1",
+                        priv->cancellable,
+                        (GAsyncReadyCallback) localed_proxy_ready,
+                        object);
+      g_object_unref (bus);
+  }
+
+  gis_page_set_complete (GIS_PAGE (page), TRUE);
   gtk_widget_show (GTK_WIDGET (page));
 }
 
@@ -83,6 +198,16 @@ gis_language_page_locale_changed (GisPage *page)
 }
 
 static void
+gis_language_page_dispose (GObject *object)
+{
+  GisLanguagePage *page = GIS_LANGUAGE_PAGE (object);
+  GisLanguagePagePrivate *priv = page->priv;
+
+  g_clear_object (&priv->permission);
+  g_clear_object (&priv->localed);
+}
+
+static void
 gis_language_page_class_init (GisLanguagePageClass *klass)
 {
   GisPageClass *page_class = GIS_PAGE_CLASS (klass);
@@ -91,6 +216,7 @@ gis_language_page_class_init (GisLanguagePageClass *klass)
   page_class->page_id = PAGE_ID;
   page_class->locale_changed = gis_language_page_locale_changed;
   object_class->constructed = gis_language_page_constructed;
+  object_class->dispose = gis_language_page_dispose;
 
   g_type_class_add_private (object_class, sizeof(GisLanguagePagePrivate));
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]