summaryrefslogtreecommitdiffstats
path: root/gnome-initial-setup/pages/language/gis-language-page.c
diff options
context:
space:
mode:
Diffstat (limited to 'gnome-initial-setup/pages/language/gis-language-page.c')
-rw-r--r--gnome-initial-setup/pages/language/gis-language-page.c312
1 files changed, 312 insertions, 0 deletions
diff --git a/gnome-initial-setup/pages/language/gis-language-page.c b/gnome-initial-setup/pages/language/gis-language-page.c
new file mode 100644
index 0000000..f62b2ad
--- /dev/null
+++ b/gnome-initial-setup/pages/language/gis-language-page.c
@@ -0,0 +1,312 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+/*
+ * Copyright (C) 2012 Red Hat
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * 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 */
+
+#define PAGE_ID "language"
+
+#define GNOME_SYSTEM_LOCALE_DIR "org.gnome.system.locale"
+#define REGION_KEY "region"
+
+#include "config.h"
+#include "language-resources.h"
+#include "gis-welcome-widget.h"
+#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>
+
+struct _GisLanguagePagePrivate
+{
+ GtkWidget *logo;
+ GtkWidget *welcome_widget;
+ GtkWidget *language_chooser;
+
+ GDBusProxy *localed;
+ GPermission *permission;
+ const gchar *new_locale_id;
+
+ GCancellable *cancellable;
+};
+typedef struct _GisLanguagePagePrivate GisLanguagePagePrivate;
+
+G_DEFINE_TYPE_WITH_PRIVATE (GisLanguagePage, gis_language_page, GIS_TYPE_PAGE);
+
+static void
+set_localed_locale (GisLanguagePage *self)
+{
+ GisLanguagePagePrivate *priv = gis_language_page_get_instance_private (self);
+ 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)
+{
+ GisLanguagePage *page = GIS_LANGUAGE_PAGE (data);
+ GisLanguagePagePrivate *priv = gis_language_page_get_instance_private (page);
+ GError *error = NULL;
+ gboolean allowed;
+
+ 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", error->message);
+ g_error_free (error);
+ return;
+ }
+
+ if (allowed)
+ set_localed_locale (page);
+}
+
+static void
+user_loaded (GObject *object,
+ GParamSpec *pspec,
+ gpointer user_data)
+{
+ gchar *new_locale_id = user_data;
+
+ act_user_set_language (ACT_USER (object), new_locale_id);
+
+ g_free (new_locale_id);
+}
+
+static void
+language_changed (CcLanguageChooser *chooser,
+ GParamSpec *pspec,
+ GisLanguagePage *page)
+{
+ GisLanguagePagePrivate *priv = gis_language_page_get_instance_private (page);
+ GisDriver *driver;
+ GSettings *region_settings;
+ ActUser *user;
+
+ priv->new_locale_id = cc_language_chooser_get_language (chooser);
+ driver = GIS_PAGE (page)->driver;
+
+ gis_driver_set_user_language (driver, priv->new_locale_id, TRUE);
+ gtk_widget_set_default_direction (gtk_get_locale_direction ());
+
+ if (gis_driver_get_mode (driver) == GIS_DRIVER_MODE_NEW_USER) {
+ if (g_permission_get_allowed (priv->permission)) {
+ set_localed_locale (page);
+ }
+ else if (g_permission_get_can_acquire (priv->permission)) {
+ g_permission_acquire_async (priv->permission,
+ NULL,
+ change_locale_permission_acquired,
+ page);
+ }
+ }
+
+ /* Ensure we won't override the selected language for format strings */
+ region_settings = g_settings_new (GNOME_SYSTEM_LOCALE_DIR);
+ g_settings_reset (region_settings, REGION_KEY);
+ g_object_unref (region_settings);
+
+ user = act_user_manager_get_user (act_user_manager_get_default (),
+ g_get_user_name ());
+ if (act_user_is_loaded (user))
+ act_user_set_language (user, priv->new_locale_id);
+ else
+ g_signal_connect (user,
+ "notify::is-loaded",
+ G_CALLBACK (user_loaded),
+ g_strdup (priv->new_locale_id));
+
+ gis_welcome_widget_show_locale (GIS_WELCOME_WIDGET (priv->welcome_widget),
+ priv->new_locale_id);
+}
+
+static void
+localed_proxy_ready (GObject *source,
+ GAsyncResult *res,
+ gpointer data)
+{
+ GisLanguagePage *self = data;
+ GisLanguagePagePrivate *priv = gis_language_page_get_instance_private (self);
+ 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", error->message);
+ g_error_free (error);
+ return;
+ }
+
+ priv->localed = proxy;
+}
+
+static void
+update_distro_logo (GisLanguagePage *page)
+{
+ GisLanguagePagePrivate *priv = gis_language_page_get_instance_private (page);
+ g_autofree char *id = g_get_os_info (G_OS_INFO_KEY_ID);
+ gsize i;
+
+ static const struct {
+ const char *id;
+ const char *logo;
+ } id_to_logo[] = {
+ { "debian", "emblem-debian" },
+ { "fedora", "fedora-logo-icon" },
+ { "ubuntu", "ubuntu-logo-icon" },
+ { "openSUSE Tumbleweed", "opensuse-logo-icon" },
+ { "openSUSE Leap", "opensuse-logo-icon" },
+ { "SLED", "suse-logo-icon" },
+ { "SLES", "suse-logo-icon" },
+ };
+
+ for (i = 0; i < G_N_ELEMENTS (id_to_logo); i++)
+ {
+ if (g_strcmp0 (id, id_to_logo[i].id) == 0)
+ {
+ g_object_set (priv->logo, "icon-name", id_to_logo[i].logo, NULL);
+ break;
+ }
+ }
+}
+
+static void
+language_confirmed (CcLanguageChooser *chooser,
+ GisLanguagePage *page)
+{
+ gis_assistant_next_page (gis_driver_get_assistant (GIS_PAGE (page)->driver));
+}
+
+static void
+gis_language_page_constructed (GObject *object)
+{
+ GisLanguagePage *page = GIS_LANGUAGE_PAGE (object);
+ GisLanguagePagePrivate *priv = gis_language_page_get_instance_private (page);
+ GDBusConnection *bus;
+
+ g_type_ensure (CC_TYPE_LANGUAGE_CHOOSER);
+
+ G_OBJECT_CLASS (gis_language_page_parent_class)->constructed (object);
+
+ update_distro_logo (page);
+
+ g_signal_connect (priv->language_chooser, "notify::language",
+ G_CALLBACK (language_changed), page);
+ g_signal_connect (priv->language_chooser, "confirm",
+ G_CALLBACK (language_confirmed), page);
+
+ /* 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));
+}
+
+static void
+gis_language_page_locale_changed (GisPage *page)
+{
+ gis_page_set_title (GIS_PAGE (page), _("Welcome"));
+}
+
+static void
+gis_language_page_dispose (GObject *object)
+{
+ GisLanguagePage *page = GIS_LANGUAGE_PAGE (object);
+ GisLanguagePagePrivate *priv = gis_language_page_get_instance_private (page);
+
+ g_clear_object (&priv->permission);
+ g_clear_object (&priv->localed);
+ g_clear_object (&priv->cancellable);
+
+ G_OBJECT_CLASS (gis_language_page_parent_class)->dispose (object);
+}
+
+static void
+gis_language_page_class_init (GisLanguagePageClass *klass)
+{
+ GisPageClass *page_class = GIS_PAGE_CLASS (klass);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ gtk_widget_class_set_template_from_resource (GTK_WIDGET_CLASS (klass), "/org/gnome/initial-setup/gis-language-page.ui");
+
+ gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisLanguagePage, welcome_widget);
+ gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisLanguagePage, language_chooser);
+ gtk_widget_class_bind_template_child_private (GTK_WIDGET_CLASS (klass), GisLanguagePage, logo);
+
+ 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;
+}
+
+static void
+gis_language_page_init (GisLanguagePage *page)
+{
+ g_resources_register (language_get_resource ());
+ g_type_ensure (GIS_TYPE_WELCOME_WIDGET);
+ g_type_ensure (CC_TYPE_LANGUAGE_CHOOSER);
+
+ gtk_widget_init_template (GTK_WIDGET (page));
+}
+
+GisPage *
+gis_prepare_language_page (GisDriver *driver)
+{
+ return g_object_new (GIS_TYPE_LANGUAGE_PAGE,
+ "driver", driver,
+ NULL);
+}