Description: Addition of FormatsLocale property and SetFormatsLocale method.
Forwarded: https://bugs.freedesktop.org/42857
Author: Gunnar Hjalmarsson <ubuntu@gunnar.cc>
Last-Update: 2011-11-12

Index: accountsservice-0.6.35/data/org.freedesktop.Accounts.User.xml
===================================================================
--- accountsservice-0.6.35.orig/data/org.freedesktop.Accounts.User.xml	2013-11-13 15:16:36.076124828 +0100
+++ accountsservice-0.6.35/data/org.freedesktop.Accounts.User.xml	2013-11-13 15:16:36.064124828 +0100
@@ -150,6 +150,41 @@
     </doc:doc>
   </method>
 
+  <method name="SetFormatsLocale">
+    <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+    <arg name="formats_locale" direction="in" type="s">
+      <doc:doc>
+        <doc:summary>
+          The new regional formats, as a locale specification like "de_DE.UTF-8".
+        </doc:summary>
+      </doc:doc>
+    </arg>
+    <doc:doc>
+      <doc:description>
+        <doc:para>
+          Sets the users regional formats.
+        </doc:para>
+      </doc:description>
+      <doc:permission>
+        The caller needs one of the following PolicyKit authorizations:
+        <doc:list>
+          <doc:item>
+            <doc:term>org.freedesktop.accounts.change-own-user-data</doc:term>
+            <doc:definition>To change his own language</doc:definition>
+          </doc:item>
+          <doc:item>
+            <doc:term>org.freedesktop.accounts.user-administration</doc:term>
+            <doc:definition>To change the language of another user</doc:definition>
+          </doc:item>
+        </doc:list>
+      </doc:permission>
+      <doc:errors>
+        <doc:error name="org.freedesktop.Accounts.Error.PermissionDenied">if the caller lacks the appropriate PolicyKit authorization</doc:error>
+        <doc:error name="org.freedesktop.Accounts.Error.Failed">if the operation failed</doc:error>
+      </doc:errors>
+    </doc:doc>
+  </method>
+
   <method name="SetXSession">
     <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
     <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="user_set_x_session"/>
@@ -621,6 +656,16 @@
         </doc:para>
       </doc:description>
     </doc:doc>
+  </property>
+
+  <property name="FormatsLocale" type="s" access="read">
+    <doc:doc>
+      <doc:description>
+        <doc:para>
+          The users regional formats, as a locale specification like "de_DE.UTF-8".
+        </doc:para>
+      </doc:description>
+    </doc:doc>
   </property>
 
   <property name="XSession" type="s" access="read">
Index: accountsservice-0.6.35/src/libaccountsservice/act-user.c
===================================================================
--- accountsservice-0.6.35.orig/src/libaccountsservice/act-user.c	2013-11-13 15:16:36.076124828 +0100
+++ accountsservice-0.6.35/src/libaccountsservice/act-user.c	2013-11-13 15:16:36.068124828 +0100
@@ -93,6 +93,7 @@
         PROP_LOGIN_HISTORY,
         PROP_ICON_FILE,
         PROP_LANGUAGE,
+        PROP_FORMATS_LOCALE,
         PROP_X_SESSION,
         PROP_IS_LOADED
 };
@@ -122,6 +123,7 @@
         char           *location;
         char           *icon_file;
         char           *language;
+        char           *formats_locale;
         char           *x_session;
         GList          *our_sessions;
         GList          *other_sessions;
@@ -308,6 +310,9 @@
         case PROP_LANGUAGE:
                 g_value_set_string (value, user->language);
                 break;
+        case PROP_FORMATS_LOCALE:
+                g_value_set_string (value, user->formats_locale);
+                break;
         case PROP_X_SESSION:
                 g_value_set_string (value, user->x_session);
                 break;
@@ -464,6 +469,13 @@
                                                               NULL,
                                                               G_PARAM_READABLE));
         g_object_class_install_property (gobject_class,
+                                         PROP_FORMATS_LOCALE,
+                                         g_param_spec_string ("formats_locale",
+                                                              "Regional Formats",
+                                                              "User's regional formats.",
+                                                              NULL,
+                                                              G_PARAM_READABLE));
+        g_object_class_install_property (gobject_class,
                                          PROP_X_SESSION,
                                          g_param_spec_string ("x-session",
                                                               "X session",
@@ -583,6 +595,7 @@
         g_free (user->location);
         if (user->login_history)
           g_variant_unref (user->login_history);
+        g_free (user->formats_locale);
 
         if (user->accounts_proxy != NULL) {
                 g_object_unref (user->accounts_proxy);
@@ -1052,6 +1065,22 @@
 }
 
 /**
+ * act_user_get_formats_locale:
+ * @user: a #ActUser
+ *
+ * Returns the path to the configured formats locale of @user.
+ *
+ * Returns: (transfer none): a path to an icon
+ */
+const char *
+act_user_get_formats_locale (ActUser *user)
+{
+        g_return_val_if_fail (ACT_IS_USER (user), NULL);
+
+        return user->formats_locale;
+}
+
+/**
  * act_user_get_x_session:
  * @user: a #ActUser
  *
@@ -1279,6 +1308,17 @@
                         user->language = g_strdup (new_language);
                         g_object_notify (G_OBJECT (user), "language");
                 }
+
+        } else if (strcmp (key, "FormatsLocale") == 0) {
+                const char *new_formats_locale;
+
+                new_formats_locale = g_variant_get_string (value, NULL);
+                if (g_strcmp0 (user->formats_locale, new_formats_locale) != 0) {
+                        g_free (user->formats_locale);
+                        user->formats_locale = g_strdup (new_formats_locale);
+                        g_object_notify (G_OBJECT (user), "formats_locale");
+                }
+
         } else if (strcmp (key, "XSession") == 0) {
                 const char *new_x_session;
 
@@ -1603,6 +1643,35 @@
                 g_error_free (error);
                 return;
         }
+}
+
+/**
+ * act_user_set_formats_locale:
+ * @user: the user object to alter.
+ * @formats_locale: a locale (e.g. en_US.utf8)
+ *
+ * Assigns a new formats locale for @user.
+ *
+ * Note this function is synchronous and ignores errors.
+ **/
+void
+act_user_set_formats_locale (ActUser    *user,
+                             const char *formats_locale)
+{
+        GError *error = NULL;
+
+        g_return_if_fail (ACT_IS_USER (user));
+        g_return_if_fail (formats_locale != NULL);
+        g_return_if_fail (ACCOUNTS_IS_USER (user->accounts_proxy));
+
+        if (!accounts_user_call_set_formats_locale_sync (user->accounts_proxy,
+                                                         formats_locale,
+                                                         NULL,
+                                                         &error)) {
+                g_warning ("SetFormatsLocale call failed: %s", error->message);
+                g_error_free (error);
+                return;
+        }
 }
 
 /**
Index: accountsservice-0.6.35/src/libaccountsservice/act-user.h
===================================================================
--- accountsservice-0.6.35.orig/src/libaccountsservice/act-user.h	2013-11-13 15:16:36.076124828 +0100
+++ accountsservice-0.6.35/src/libaccountsservice/act-user.h	2013-11-13 15:16:36.068124828 +0100
@@ -77,6 +77,7 @@
 gboolean       act_user_is_nonexistent            (ActUser   *user);
 const char    *act_user_get_icon_file             (ActUser   *user);
 const char    *act_user_get_language              (ActUser   *user);
+const char    *act_user_get_formats_locale        (ActUser   *user);
 const char    *act_user_get_x_session             (ActUser   *user);
 const char    *act_user_get_primary_session_id    (ActUser   *user);
 
@@ -88,6 +89,8 @@
                                                    const char *email);
 void           act_user_set_language              (ActUser    *user,
                                                    const char *language);
+void           act_user_set_formats_locale        (ActUser    *user,
+                                                   const char *formats_locale);
 void           act_user_set_x_session             (ActUser    *user,
                                                    const char *x_session);
 void           act_user_set_location              (ActUser    *user,
Index: accountsservice-0.6.35/src/user.c
===================================================================
--- accountsservice-0.6.35.orig/src/user.c	2013-11-13 15:16:36.076124828 +0100
+++ accountsservice-0.6.35/src/user.c	2013-11-13 15:16:36.072124828 +0100
@@ -58,6 +58,7 @@
         PROP_SHELL,
         PROP_EMAIL,
         PROP_LANGUAGE,
+        PROP_FORMATS_LOCALE,
         PROP_X_SESSION,
         PROP_LOCATION,
         PROP_LOGIN_FREQUENCY,
@@ -93,6 +94,7 @@
         gchar        *shell;
         gchar        *email;
         gchar        *language;
+        gchar        *formats_locale;
         gchar        *x_session;
         gchar        *location;
         guint64       login_frequency;
@@ -322,6 +324,13 @@
                 g_object_notify (G_OBJECT (user), "language");
         }
 
+        s = g_key_file_get_string (keyfile, "User", "FormatsLocale", NULL);
+        if (s != NULL) {
+                g_free (user->formats_locale);
+                user->formats_locale = s;
+                g_object_notify (G_OBJECT (user), "formats-locale");
+        }
+
         s = g_key_file_get_string (keyfile, "User", "XSession", NULL);
         if (s != NULL) {
                 g_free (user->x_session);
@@ -405,6 +414,9 @@
         if (user->language)
                 g_key_file_set_string (keyfile, "User", "Language", user->language);
 
+        if (user->formats_locale)
+                g_key_file_set_string (keyfile, "User", "FormatsLocale", user->formats_locale);
+
         if (user->x_session)
                 g_key_file_set_string (keyfile, "User", "XSession", user->x_session);
 
@@ -1106,6 +1118,61 @@
 }
 
 static void
+user_change_formats_locale_authorized_cb (Daemon                *daemon,
+                                          User                  *user,
+                                          GDBusMethodInvocation *context,
+                                          gpointer               data)
+
+{
+        gchar *formats_locale = data;
+
+        if (g_strcmp0 (user->formats_locale, formats_locale) != 0) {
+                g_free (user->formats_locale);
+                user->formats_locale = g_strdup (formats_locale);
+
+                save_extra_data (user);
+
+                accounts_user_emit_changed (ACCOUNTS_USER (user));
+
+                g_object_notify (G_OBJECT (user), "formats_locale");
+        }
+
+        accounts_user_complete_set_formats_locale (ACCOUNTS_USER (user), context);
+}
+
+gboolean
+user_set_formats_locale (AccountsUser          *auser,
+                         GDBusMethodInvocation *context,
+                         const gchar           *formats_locale)
+{
+        User *user = (User*)auser;
+
+        int uid;
+        const gchar *action_id;
+
+        if (!get_caller_uid (context, &uid)) {
+                throw_error (context, ERROR_FAILED, "identifying caller failed");
+                return FALSE;
+        }
+
+        if (user->uid == (uid_t) uid)
+                action_id = "org.freedesktop.accounts.change-own-user-data";
+        else
+                action_id = "org.freedesktop.accounts.user-administration";
+
+        daemon_local_check_auth (user->daemon,
+                                 user,
+                                 action_id,
+                                 TRUE,
+                                 user_change_formats_locale_authorized_cb,
+                                 context,
+                                 g_strdup (formats_locale),
+                                 (GDestroyNotify) g_free);
+
+        return TRUE;
+}
+
+static void
 user_change_x_session_authorized_cb (Daemon                *daemon,
                                      User                  *user,
                                      GDBusMethodInvocation *context,
@@ -2106,6 +2173,7 @@
         g_free (user->default_icon_file);
         g_free (user->email);
         g_free (user->language);
+        g_free (user->formats_locale);
         g_free (user->x_session);
         g_free (user->location);
         g_free (user->password_hint);
@@ -2132,6 +2200,9 @@
         case PROP_LANGUAGE:
                 user->language = g_value_dup_string (value);
                 break;
+        case PROP_FORMATS_LOCALE:
+                user->formats_locale = g_value_dup_string (value);
+                break;
         case PROP_X_SESSION:
                 user->x_session = g_value_dup_string (value);
                 break;
@@ -2200,6 +2271,9 @@
         case PROP_LANGUAGE:
                 g_value_set_string (value, user->language);
                 break;
+        case PROP_FORMATS_LOCALE:
+                g_value_set_string (value, user->formats_locale);
+                break;
         case PROP_X_SESSION:
                 g_value_set_string (value, user->x_session);
                 break;
@@ -2263,6 +2337,7 @@
         iface->handle_set_account_type = user_set_account_type;
         iface->handle_set_automatic_login = user_set_automatic_login;
         iface->handle_set_email = user_set_email;
+        iface->handle_set_formats_locale = user_set_formats_locale;
         iface->handle_set_home_directory = user_set_home_directory;
         iface->handle_set_icon_file = user_set_icon_file;
         iface->handle_set_language = user_set_language;
@@ -2309,6 +2384,7 @@
         user->default_icon_file = NULL;
         user->email = NULL;
         user->language = NULL;
+        user->formats_locale = NULL;
         user->x_session = NULL;
         user->location = NULL;
         user->password_mode = PASSWORD_MODE_REGULAR;
