[gnome-initial-setup/wip/pwithnall/misc-fixes: 30/70] timezone: set default 12h/24h from locale




commit 67a21dcd74e97f20abeca8a102c9106e35af4d95
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.
    
    This commit contains code from Cosimo Cecchi, Joaquim Rocha, and Philip
    Chimento.
    
    Upstream issue:
    https://gitlab.gnome.org/GNOME/gnome-initial-setup/issues/14
    
    (Rebase 3.38: Fix minor rebase conflicts.)

 .../pages/language/gis-language-page.c             | 76 +++++++++++++++++++++-
 .../pages/timezone/gis-timezone-page.c             | 15 +++--
 2 files changed, 84 insertions(+), 7 deletions(-)
---
diff --git a/gnome-initial-setup/pages/language/gis-language-page.c 
b/gnome-initial-setup/pages/language/gis-language-page.c
index 9f2beb73..f5c5e70b 100644
--- a/gnome-initial-setup/pages/language/gis-language-page.c
+++ b/gnome-initial-setup/pages/language/gis-language-page.c
@@ -36,11 +36,19 @@
 #include "gis-page-util.h"
 #include "gis-language-page.h"
 
+#include <errno.h>
+#include <langinfo.h>
+#include <locale.h>
+
 #include <act/act-user-manager.h>
+#include <gdesktop-enums.h>
 #include <polkit/polkit.h>
-#include <locale.h>
 #include <gtk/gtk.h>
 
+#define CLOCK_SCHEMA "org.gnome.desktop.interface"
+#define CLOCK_FORMAT_KEY "clock-format"
+#define DEFAULT_CLOCK_FORMAT G_DESKTOP_CLOCK_FORMAT_24H
+
 struct _GisLanguagePagePrivate
 {
   GtkWidget *logo;
@@ -59,6 +67,8 @@ typedef struct _GisLanguagePagePrivate GisLanguagePagePrivate;
 
 G_DEFINE_TYPE_WITH_PRIVATE (GisLanguagePage, gis_language_page, GIS_TYPE_PAGE);
 
+G_DEFINE_AUTO_CLEANUP_FREE_FUNC(locale_t, freelocale, NULL)
+
 static void
 set_localed_locale (GisLanguagePage *self)
 {
@@ -113,6 +123,68 @@ user_loaded (GObject    *object,
   g_free (new_locale_id);
 }
 
+static GDesktopClockFormat
+get_default_time_format (const gchar *lang_id)
+{
+  const char *ampm, *nl_fmt;
+  locale_t undef_locale;
+
+  if (lang_id == NULL)
+    {
+      undef_locale = uselocale ((locale_t) 0);
+      if (undef_locale == (locale_t) 0)
+        {
+          g_warning ("Failed to detect current locale: %s", g_strerror (errno));
+          return DEFAULT_CLOCK_FORMAT;
+        }
+    }
+  else
+    {
+      undef_locale = newlocale (LC_MESSAGES_MASK | LC_TIME_MASK, lang_id, (locale_t) 0);
+      if (undef_locale == (locale_t) 0)
+        {
+          g_warning ("Failed to create locale %s: %s", lang_id, g_strerror (errno));
+          return DEFAULT_CLOCK_FORMAT;
+        }
+    }
+
+  /* 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 DEFAULT_CLOCK_FORMAT;
+    }
+
+  /* Default 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 DEFAULT_CLOCK_FORMAT;
+
+  /* Fall back to 24 hour specifically 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;
+}
+
+static void
+set_time_format (const char *lang_id)
+{
+  g_autoptr(GSettings) settings = g_settings_new (CLOCK_SCHEMA);
+  GDesktopClockFormat clock_format = get_default_time_format (lang_id);
+  g_settings_set_enum (settings, CLOCK_FORMAT_KEY, clock_format);
+}
+
 static void
 language_changed (CcLanguageChooser  *chooser,
                   GParamSpec         *pspec,
@@ -128,6 +200,7 @@ language_changed (CcLanguageChooser  *chooser,
 
   gis_driver_set_user_language (driver, priv->new_locale_id, TRUE);
   gtk_widget_set_default_direction (gtk_get_locale_direction ());
+  set_time_format (priv->new_locale_id);
 
   if (gis_driver_get_mode (driver) == GIS_DRIVER_MODE_NEW_USER) {
       if (g_permission_get_allowed (priv->permission)) {
@@ -232,6 +305,7 @@ gis_language_page_constructed (GObject *object)
   G_OBJECT_CLASS (gis_language_page_parent_class)->constructed (object);
 
   update_distro_logo (page);
+  set_time_format (NULL);
 
   g_signal_connect (priv->language_chooser, "notify::language",
                     G_CALLBACK (language_changed), page);
diff --git a/gnome-initial-setup/pages/timezone/gis-timezone-page.c 
b/gnome-initial-setup/pages/timezone/gis-timezone-page.c
index 855cb484..ddebfd5c 100644
--- a/gnome-initial-setup/pages/timezone/gis-timezone-page.c
+++ b/gnome-initial-setup/pages/timezone/gis-timezone-page.c
@@ -74,7 +74,7 @@ struct _GisTimezonePagePrivate
   GCancellable *dtm_cancellable;
 
   GnomeWallClock *clock;
-  GDesktopClockFormat clock_format;
+  GSettings *clock_settings;
   gboolean in_search;
 
   gulong search_entry_text_changed_id;
@@ -278,9 +278,12 @@ update_timezone (GisTimezonePage *page, TzLocation *location)
   char *time_label;
   GTimeZone *zone;
   GDateTime *date;
+  GDesktopClockFormat clock_format;
   gboolean use_ampm;
 
-  if (priv->clock_format == G_DESKTOP_CLOCK_FORMAT_12H)
+  clock_format = g_settings_get_enum (priv->clock_settings, CLOCK_FORMAT_KEY);
+
+  if (clock_format == G_DESKTOP_CLOCK_FORMAT_12H)
     use_ampm = TRUE;
   else
     use_ampm = FALSE;
@@ -405,7 +408,6 @@ 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;
 
   G_OBJECT_CLASS (gis_timezone_page_parent_class)->constructed (object);
 
@@ -426,9 +428,7 @@ 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_settings = g_settings_new (CLOCK_SCHEMA);
 
   set_location (page, NULL);
 
@@ -443,6 +443,8 @@ gis_timezone_page_constructed (GObject *object)
                     G_CALLBACK (map_location_changed), page);
   g_signal_connect (GTK_WIDGET (page), "parent-set",
                     G_CALLBACK (page_added), NULL);
+  g_signal_connect (priv->clock_settings, "notify::" CLOCK_FORMAT_KEY,
+                    G_CALLBACK (update_timezone), page);
 
   gtk_widget_show (GTK_WIDGET (page));
 }
@@ -463,6 +465,7 @@ gis_timezone_page_dispose (GObject *object)
 
   g_clear_object (&priv->dtm);
   g_clear_object (&priv->clock);
+  g_clear_object (&priv->clock_settings);
 
   G_OBJECT_CLASS (gis_timezone_page_parent_class)->dispose (object);
 }


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