[gnome-initial-setup/various-improvements: 34/35] timezone: set default 12h/24h from locale



commit 43c6537410ac0fc756a65846c6f18c59192cc003
Author: Cosimo Cecchi <cosimoc gnome org>
Date:   Wed Jun 7 12:17:31 2017 -0700

    timezone: set default 12h/24h from locale
    
    Instead of always using the default setting of 24h.
    
    We take care to use the locale that the user has previously chosen
    inside gnome-initial-setup, and not the initial (global) locale.
    
    This commit contains code from Cosimo Cecchi, Joaquim Rocha, and Philip
    Chimento.

 gnome-initial-setup/gis-driver.c                   | 78 +++++++++++++++++++++-
 gnome-initial-setup/gis-driver.h                   |  4 ++
 .../pages/timezone/gis-timezone-page.c             | 13 ++--
 3 files changed, 90 insertions(+), 5 deletions(-)
---
diff --git a/gnome-initial-setup/gis-driver.c b/gnome-initial-setup/gis-driver.c
index 64fe7ba..c445314 100644
--- a/gnome-initial-setup/gis-driver.c
+++ b/gnome-initial-setup/gis-driver.c
@@ -24,6 +24,7 @@
 #include "gnome-initial-setup.h"
 
 #include <errno.h>
+#include <langinfo.h>
 #include <locale.h>
 #include <stdlib.h>
 #include <gdm/gdm-client.h>
@@ -92,6 +93,8 @@ typedef struct _GisDriverPrivate GisDriverPrivate;
 
 G_DEFINE_TYPE_WITH_PRIVATE(GisDriver, gis_driver, GTK_TYPE_APPLICATION)
 
+G_DEFINE_AUTO_CLEANUP_FREE_FUNC(locale_t, freelocale, NULL)
+
 static void
 gis_driver_dispose (GObject *object)
 {
@@ -199,7 +202,7 @@ gis_driver_set_user_language (GisDriver *driver, const gchar *lang_id, gboolean
 
   if (update_locale)
     {
-      locale_t locale = newlocale (LC_MESSAGES_MASK, lang_id, (locale_t) 0);
+      locale_t locale = newlocale (LC_MESSAGES_MASK | LC_TIME_MASK, lang_id, (locale_t) 0);
       if (locale == (locale_t) 0)
         {
           g_warning ("Failed to create locale %s: %s", lang_id, g_strerror (errno));
@@ -223,6 +226,79 @@ gis_driver_get_user_language (GisDriver *driver)
   return priv->lang_id;
 }
 
+/*
+ * gis_driver_get_default_time_format:
+ * @self: the #GisDriver
+ * @chosen_from_locale_page: return location for a boolean
+ *
+ * Gets the default time format corresponding to the current locale.
+ *
+ * If the current locale was a result of choosing a locale in the langauge page
+ * of gnome-initial-setup, sets @chosen_from_locale_page to %TRUE.
+ * Otherwise, if the current locale is taken from the environment, sets
+ * @chosen_from_locale_page to %FALSE.
+ *
+ * If @chosen_from_locale_page is %FALSE, then callers should not clobber the
+ * clock format setting in the user's environment.
+ *
+ * Returns: #G_DESKTOP_CLOCK_FORMAT_12H or #G_DESKTOP_CLOCK_FORMAT_24H
+ */
+GDesktopClockFormat
+gis_driver_get_default_time_format (GisDriver *self,
+                                    gboolean  *chosen_from_locale_page)
+{
+  const char *ampm, *nl_fmt;
+  GisDriverPrivate *priv = gis_driver_get_instance_private (self);
+  locale_t undef_locale = priv->locale;
+
+  g_return_val_if_fail (chosen_from_locale_page != NULL,
+                        G_DESKTOP_CLOCK_FORMAT_24H);
+
+  if (undef_locale == (locale_t) 0)
+    {
+      undef_locale = uselocale ((locale_t) 0);
+      *chosen_from_locale_page = FALSE;
+    }
+  else
+    {
+      *chosen_from_locale_page = TRUE;
+    }
+
+  if (undef_locale == (locale_t) 0)
+    {
+      g_warning ("Failed to get current locale: %s", g_strerror (errno));
+      return G_DESKTOP_CLOCK_FORMAT_24H;
+    }
+
+  /* It's necessary to duplicate the locale because undef_locale might be
+   * LC_GLOBAL_LOCALE, and duplocale() will make a concrete locale. Passing
+   * LC_GLOBAL_LOCALE to nl_langinfo_l() is undefined behaviour. */
+  g_auto(locale_t) locale = duplocale (undef_locale);
+  if (locale == (locale_t) 0)
+    {
+      g_warning ("Failed to copy current locale: %s", g_strerror (errno));
+      return G_DESKTOP_CLOCK_FORMAT_24H;
+    }
+
+  /* Default to 24 hour if we can't get the format from the locale */
+  nl_fmt = nl_langinfo_l (T_FMT, locale);
+  if (nl_fmt == NULL || *nl_fmt == '\0')
+    return G_DESKTOP_CLOCK_FORMAT_24H;
+
+  /* Default to 24 hour if AM/PM is not available in the locale */
+  ampm = nl_langinfo_l (AM_STR, locale);
+  if (ampm == NULL || ampm[0] == '\0')
+    return G_DESKTOP_CLOCK_FORMAT_24H;
+
+  /* Parse out any formats that use 12h format. See stftime(3). */
+  if (g_str_has_prefix (nl_fmt, "%I") ||
+      g_str_has_prefix (nl_fmt, "%l") ||
+      g_str_has_prefix (nl_fmt, "%r"))
+    return G_DESKTOP_CLOCK_FORMAT_12H;
+  else
+    return G_DESKTOP_CLOCK_FORMAT_24H;
+}
+
 void
 gis_driver_set_username (GisDriver *driver, const gchar *username)
 {
diff --git a/gnome-initial-setup/gis-driver.h b/gnome-initial-setup/gis-driver.h
index 1184582..946438d 100644
--- a/gnome-initial-setup/gis-driver.h
+++ b/gnome-initial-setup/gis-driver.h
@@ -25,6 +25,7 @@
 #include "gis-assistant.h"
 #include "gis-page.h"
 #include <act/act-user-manager.h>
+#include <gdesktop-enums.h>
 #include <gdm/gdm-client.h>
 
 G_BEGIN_DECLS
@@ -86,6 +87,9 @@ void gis_driver_set_user_language (GisDriver   *driver,
 
 const gchar *gis_driver_get_user_language (GisDriver *driver);
 
+GDesktopClockFormat gis_driver_get_default_time_format (GisDriver *self,
+                                                        gboolean  *chosen_from_locale_page);
+
 void gis_driver_set_username (GisDriver   *driver,
                               const gchar *username);
 const gchar *gis_driver_get_username (GisDriver *driver);
diff --git a/gnome-initial-setup/pages/timezone/gis-timezone-page.c 
b/gnome-initial-setup/pages/timezone/gis-timezone-page.c
index 7bf4e90..ee89dd9 100644
--- a/gnome-initial-setup/pages/timezone/gis-timezone-page.c
+++ b/gnome-initial-setup/pages/timezone/gis-timezone-page.c
@@ -395,7 +395,7 @@ gis_timezone_page_constructed (GObject *object)
   GisTimezonePage *page = GIS_TIMEZONE_PAGE (object);
   GisTimezonePagePrivate *priv = gis_timezone_page_get_instance_private (page);
   GError *error;
-  GSettings *settings;
+  gboolean chosen_from_locale_page;
 
   G_OBJECT_CLASS (gis_timezone_page_parent_class)->constructed (object);
 
@@ -414,9 +414,14 @@ gis_timezone_page_constructed (GObject *object)
   priv->clock = g_object_new (GNOME_TYPE_WALL_CLOCK, NULL);
   g_signal_connect (priv->clock, "notify::clock", G_CALLBACK (on_clock_changed), page);
 
-  settings = g_settings_new (CLOCK_SCHEMA);
-  priv->clock_format = g_settings_get_enum (settings, CLOCK_FORMAT_KEY);
-  g_object_unref (settings);
+  priv->clock_format = gis_driver_get_default_time_format (GIS_PAGE (page)->driver,
+                                                           &chosen_from_locale_page);
+  if (chosen_from_locale_page)
+    {
+      g_message ("Chosen from locale page, updating settings");
+      g_autoptr(GSettings) settings = g_settings_new (CLOCK_SCHEMA);
+      g_settings_set_enum (settings, CLOCK_FORMAT_KEY, priv->clock_format);
+    }
 
   priv->geoclue_cancellable = g_cancellable_new ();
 


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