[evolution-data-server] Bug 777207 - Allow e-mail address change for GOA configured accounts
- From: Milan Crha <mcrha src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [evolution-data-server] Bug 777207 - Allow e-mail address change for GOA configured accounts
- Date: Tue, 17 Jan 2017 17:18:08 +0000 (UTC)
commit 68a9a7281fa2e045e1a338e7ad58ea82b8477c55
Author: Milan Crha <mcrha redhat com>
Date: Tue Jan 17 18:18:48 2017 +0100
Bug 777207 - Allow e-mail address change for GOA configured accounts
src/libedataserver/e-source-goa.c | 232 +++++++++++++++++++-
src/libedataserver/e-source-goa.h | 8 +
.../module-gnome-online-accounts.c | 133 ++++++++++--
3 files changed, 351 insertions(+), 22 deletions(-)
---
diff --git a/src/libedataserver/e-source-goa.c b/src/libedataserver/e-source-goa.c
index 980e915..4efccf1 100644
--- a/src/libedataserver/e-source-goa.c
+++ b/src/libedataserver/e-source-goa.c
@@ -47,13 +47,17 @@ struct _ESourceGoaPrivate {
gchar *account_id;
gchar *calendar_url;
gchar *contacts_url;
+ gchar *name;
+ gchar *address;
};
enum {
PROP_0,
PROP_ACCOUNT_ID,
PROP_CALENDAR_URL,
- PROP_CONTACTS_URL
+ PROP_CONTACTS_URL,
+ PROP_NAME,
+ PROP_ADDRESS
};
G_DEFINE_TYPE (
@@ -85,6 +89,18 @@ source_goa_set_property (GObject *object,
E_SOURCE_GOA (object),
g_value_get_string (value));
return;
+
+ case PROP_NAME:
+ e_source_goa_set_name (
+ E_SOURCE_GOA (object),
+ g_value_get_string (value));
+ return;
+
+ case PROP_ADDRESS:
+ e_source_goa_set_address (
+ E_SOURCE_GOA (object),
+ g_value_get_string (value));
+ return;
}
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -117,6 +133,20 @@ source_goa_get_property (GObject *object,
e_source_goa_dup_contacts_url (
E_SOURCE_GOA (object)));
return;
+
+ case PROP_NAME:
+ g_value_take_string (
+ value,
+ e_source_goa_dup_name (
+ E_SOURCE_GOA (object)));
+ return;
+
+ case PROP_ADDRESS:
+ g_value_take_string (
+ value,
+ e_source_goa_dup_address (
+ E_SOURCE_GOA (object)));
+ return;
}
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -132,6 +162,8 @@ source_goa_finalize (GObject *object)
g_free (priv->account_id);
g_free (priv->calendar_url);
g_free (priv->contacts_url);
+ g_free (priv->name);
+ g_free (priv->address);
/* Chain up to parent's finalize() method. */
G_OBJECT_CLASS (e_source_goa_parent_class)->finalize (object);
@@ -191,6 +223,32 @@ e_source_goa_class_init (ESourceGoaClass *class)
G_PARAM_CONSTRUCT |
G_PARAM_STATIC_STRINGS |
E_SOURCE_PARAM_SETTING));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_NAME,
+ g_param_spec_string (
+ "name",
+ "Name",
+ "GNOME Online Account's original Name",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS |
+ E_SOURCE_PARAM_SETTING));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_ADDRESS,
+ g_param_spec_string (
+ "address",
+ "Address",
+ "GNOME Online Account's original Address",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT |
+ G_PARAM_STATIC_STRINGS |
+ E_SOURCE_PARAM_SETTING));
}
static void
@@ -457,3 +515,175 @@ e_source_goa_set_contacts_url (ESourceGoa *extension,
g_object_notify (G_OBJECT (extension), "contacts-url");
}
+
+/**
+ * e_source_goa_get_name:
+ * @extension: an #ESourceGoa
+ *
+ * Returns the original Name of the GNOME Online Account associated
+ * with the #ESource to which @extension belongs. Can be %NULL or an empty
+ * string when not filled.
+ *
+ * Returns: the associated GNOME Online Account's Name
+ *
+ * Since: 3.24
+ **/
+const gchar *
+e_source_goa_get_name (ESourceGoa *extension)
+{
+ g_return_val_if_fail (E_IS_SOURCE_GOA (extension), NULL);
+
+ return extension->priv->name;
+}
+
+/**
+ * e_source_goa_dup_name:
+ * @extension: an #ESourceGoa
+ *
+ * Thread-safe variation of e_source_goa_get_name().
+ * Use this function when accessing @extension from multiple threads.
+ *
+ * The returned string should be freed with g_free() when no longer needed.
+ *
+ * Returns: a newly-allocated copy of #ESourceGoa:name
+ *
+ * Since: 3.24
+ **/
+gchar *
+e_source_goa_dup_name (ESourceGoa *extension)
+{
+ const gchar *protected;
+ gchar *duplicate;
+
+ g_return_val_if_fail (E_IS_SOURCE_GOA (extension), NULL);
+
+ e_source_extension_property_lock (E_SOURCE_EXTENSION (extension));
+
+ protected = e_source_goa_get_name (extension);
+ duplicate = g_strdup (protected);
+
+ e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
+
+ return duplicate;
+}
+
+/**
+ * e_source_goa_set_name:
+ * @extension: an #ESourceGoa
+ * @name: (nullable): the associated GNOME Online Account's Name, or %NULL
+ *
+ * Sets the Name of the GNOME Online Account associated
+ * with the #ESource to which @extension belongs.
+ *
+ * The internal copy of @name is automatically stripped of leading
+ * and trailing whitespace. If the resulting string is empty, %NULL is set
+ * instead.
+ *
+ * Since: 3.24
+ **/
+void
+e_source_goa_set_name (ESourceGoa *extension,
+ const gchar *name)
+{
+ g_return_if_fail (E_IS_SOURCE_GOA (extension));
+
+ e_source_extension_property_lock (E_SOURCE_EXTENSION (extension));
+
+ if (g_strcmp0 (extension->priv->name, name) == 0) {
+ e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
+ return;
+ }
+
+ g_free (extension->priv->name);
+ extension->priv->name = e_util_strdup_strip (name);
+
+ e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
+
+ g_object_notify (G_OBJECT (extension), "name");
+}
+
+/**
+ * e_source_goa_get_address:
+ * @extension: an #ESourceGoa
+ *
+ * Returns the original Address of the GNOME Online Account associated
+ * with the #ESource to which @extension belongs. Can be %NULL or an empty
+ * string when not filled.
+ *
+ * Returns: the associated GNOME Online Account's Address
+ *
+ * Since: 3.24
+ **/
+const gchar *
+e_source_goa_get_address (ESourceGoa *extension)
+{
+ g_return_val_if_fail (E_IS_SOURCE_GOA (extension), NULL);
+
+ return extension->priv->address;
+}
+
+/**
+ * e_source_goa_dup_address:
+ * @extension: an #ESourceGoa
+ *
+ * Thread-safe variation of e_source_goa_get_address().
+ * Use this function when accessing @extension from multiple threads.
+ *
+ * The returned string should be freed with g_free() when no longer needed.
+ *
+ * Returns: a newly-allocated copy of #ESourceGoa:address
+ *
+ * Since: 3.24
+ **/
+gchar *
+e_source_goa_dup_address (ESourceGoa *extension)
+{
+ const gchar *protected;
+ gchar *duplicate;
+
+ g_return_val_if_fail (E_IS_SOURCE_GOA (extension), NULL);
+
+ e_source_extension_property_lock (E_SOURCE_EXTENSION (extension));
+
+ protected = e_source_goa_get_address (extension);
+ duplicate = g_strdup (protected);
+
+ e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
+
+ return duplicate;
+}
+
+/**
+ * e_source_goa_set_address:
+ * @extension: an #ESourceGoa
+ * @address: (nullable): the associated GNOME Online Account's Address, or %NULL
+ *
+ * Sets the Address of the GNOME Online Account associated
+ * with the #ESource to which @extension belongs.
+ *
+ * The internal copy of @address is automatically stripped of leading
+ * and trailing whitespace. If the resulting string is empty, %NULL is set
+ * instead.
+ *
+ * Since: 3.24
+ **/
+void
+e_source_goa_set_address (ESourceGoa *extension,
+ const gchar *address)
+{
+ g_return_if_fail (E_IS_SOURCE_GOA (extension));
+
+ e_source_extension_property_lock (E_SOURCE_EXTENSION (extension));
+
+ if (g_strcmp0 (extension->priv->address, address) == 0) {
+ e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
+ return;
+ }
+
+ g_free (extension->priv->address);
+ extension->priv->address = e_util_strdup_strip (address);
+
+ e_source_extension_property_unlock (E_SOURCE_EXTENSION (extension));
+
+ g_object_notify (G_OBJECT (extension), "address");
+}
diff --git a/src/libedataserver/e-source-goa.h b/src/libedataserver/e-source-goa.h
index 9501f5c..4ed7055 100644
--- a/src/libedataserver/e-source-goa.h
+++ b/src/libedataserver/e-source-goa.h
@@ -90,6 +90,14 @@ const gchar * e_source_goa_get_contacts_url (ESourceGoa *extension);
gchar * e_source_goa_dup_contacts_url (ESourceGoa *extension);
void e_source_goa_set_contacts_url (ESourceGoa *extension,
const gchar *contacts_url);
+const gchar * e_source_goa_get_name (ESourceGoa *extension);
+gchar * e_source_goa_dup_name (ESourceGoa *extension);
+void e_source_goa_set_name (ESourceGoa *extension,
+ const gchar *name);
+const gchar * e_source_goa_get_address (ESourceGoa *extension);
+gchar * e_source_goa_dup_address (ESourceGoa *extension);
+void e_source_goa_set_address (ESourceGoa *extension,
+ const gchar *address);
G_END_DECLS
diff --git a/src/modules/gnome-online-accounts/module-gnome-online-accounts.c
b/src/modules/gnome-online-accounts/module-gnome-online-accounts.c
index 071ec43..3e2cd3c 100644
--- a/src/modules/gnome-online-accounts/module-gnome-online-accounts.c
+++ b/src/modules/gnome-online-accounts/module-gnome-online-accounts.c
@@ -31,6 +31,9 @@
#define E_GNOME_ONLINE_ACCOUNTS(obj) \
(G_TYPE_CHECK_INSTANCE_CAST \
((obj), E_TYPE_GNOME_ONLINE_ACCOUNTS, EGnomeOnlineAccounts))
+#define E_IS_GNOME_ONLINE_ACCOUNTS(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE \
+ ((obj), E_TYPE_GNOME_ONLINE_ACCOUNTS))
#define CAMEL_IMAP_PROVIDER_NAME "imapx"
#define CAMEL_SMTP_PROVIDER_NAME "smtp"
@@ -644,6 +647,76 @@ gnome_online_accounts_config_mail_account (EGnomeOnlineAccounts *extension,
e_server_side_source_set_removable (server_side_source, FALSE);
}
+static gboolean
+e_goa_transform_only_when_original_same_cb (GBinding *binding,
+ const GValue *from_value,
+ GValue *to_value,
+ gpointer user_data)
+{
+ EGnomeOnlineAccounts *extension = user_data;
+ ESourceMailIdentity *mail_identity;
+ ESourceRegistryServer *registry_server;
+ ESource *collection, *source;
+ const gchar *new_value;
+ gboolean to_value_set = FALSE;
+
+ g_return_val_if_fail (E_IS_GNOME_ONLINE_ACCOUNTS (extension), TRUE);
+
+ new_value = g_value_get_string (from_value);
+ if (new_value && !*new_value)
+ new_value = NULL;
+
+ mail_identity = E_SOURCE_MAIL_IDENTITY (g_binding_get_target (binding));
+ source = e_source_extension_ref_source (E_SOURCE_EXTENSION (mail_identity));
+
+ registry_server = gnome_online_accounts_get_server (extension);
+ collection = e_source_registry_server_ref_source (registry_server, e_source_get_parent (source));
+
+ /* The collection can be NULL when the account was just created. */
+ if (source && collection) {
+ ESourceGoa *goa_extension;
+ gchar *set_value = NULL, *old_value = NULL;
+ const gchar *prop_name;
+ gboolean changed;
+
+ g_warn_if_fail (e_source_has_extension (collection, E_SOURCE_EXTENSION_GOA));
+
+ prop_name = g_binding_get_target_property (binding);
+ goa_extension = e_source_get_extension (collection, E_SOURCE_EXTENSION_GOA);
+
+ g_object_get (G_OBJECT (goa_extension), prop_name, &old_value, NULL);
+
+ changed = g_strcmp0 (old_value, new_value) != 0;
+
+ if (changed) {
+ g_object_set (G_OBJECT (goa_extension), prop_name, new_value, NULL);
+
+ g_object_get (G_OBJECT (mail_identity), prop_name, &set_value, NULL);
+
+ if (g_strcmp0 (set_value, old_value) != 0) {
+ to_value_set = TRUE;
+
+ g_value_set_string (to_value, set_value);
+ }
+ } else {
+ g_object_get (G_OBJECT (mail_identity), prop_name, &set_value, NULL);
+ to_value_set = TRUE;
+ g_value_set_string (to_value, set_value);
+ }
+
+ g_free (set_value);
+ g_free (old_value);
+ }
+
+ g_clear_object (&collection);
+ g_clear_object (&source);
+
+ if (!to_value_set)
+ g_value_set_string (to_value, new_value);
+
+ return TRUE;
+}
+
static void
gnome_online_accounts_config_mail_identity (EGnomeOnlineAccounts *extension,
ESource *source,
@@ -665,23 +738,23 @@ gnome_online_accounts_config_mail_identity (EGnomeOnlineAccounts *extension,
extension_name = E_SOURCE_EXTENSION_MAIL_IDENTITY;
mail_identity = e_source_get_extension (source, extension_name);
- tmp = e_source_mail_identity_dup_address (mail_identity);
- if (!tmp || !*tmp) {
- /* Set the Name only if the mail is not set yet, because users can change the Name,
- even to an empty string, but the email is fixed with the one from GoaMail.
- */
- g_free (tmp);
-
- tmp = goa_mail_dup_name (goa_mail);
- if (tmp && *tmp)
- e_source_mail_identity_set_name (mail_identity, tmp);
- }
- g_free (tmp);
+ e_binding_bind_property_full (
+ goa_mail, "name",
+ mail_identity, "name",
+ G_BINDING_SYNC_CREATE,
+ e_goa_transform_only_when_original_same_cb,
+ NULL,
+ g_object_ref (extension),
+ g_object_unref);
- e_binding_bind_property (
+ e_binding_bind_property_full (
goa_mail, "email-address",
mail_identity, "address",
- G_BINDING_SYNC_CREATE);
+ G_BINDING_SYNC_CREATE,
+ e_goa_transform_only_when_original_same_cb,
+ NULL,
+ g_object_ref (extension),
+ g_object_unref);
g_object_unref (goa_mail);
@@ -774,6 +847,7 @@ gnome_online_accounts_create_collection (EGnomeOnlineAccounts *extension,
GoaObject *goa_object)
{
GoaAccount *goa_account;
+ GoaMail *goa_mail;
ESourceRegistryServer *server;
ESource *collection_source;
ESource *mail_account_source = NULL;
@@ -791,17 +865,34 @@ gnome_online_accounts_create_collection (EGnomeOnlineAccounts *extension,
extension, collection_source, goa_object);
parent_uid = e_source_get_uid (collection_source);
- if (goa_object_peek_mail (goa_object)) {
- mail_account_source =
- gnome_online_accounts_new_source (extension);
+ goa_mail = goa_object_get_mail (goa_object);
+ if (goa_mail) {
+ ESourceGoa *goa_extension;
+ gchar *name = NULL, *address = NULL;
+
+ goa_extension = e_source_get_extension (collection_source, E_SOURCE_EXTENSION_GOA);
+
+ g_object_get (G_OBJECT (goa_mail),
+ "name", &name,
+ "email-address", &address,
+ NULL);
+
+ g_object_set (G_OBJECT (goa_extension),
+ "name", name,
+ "address", address,
+ NULL);
+
+ g_object_unref (goa_mail);
+ g_free (name);
+ g_free (address);
+
+ mail_account_source = gnome_online_accounts_new_source (extension);
g_return_if_fail (E_IS_SOURCE (mail_account_source));
- mail_identity_source =
- gnome_online_accounts_new_source (extension);
+ mail_identity_source = gnome_online_accounts_new_source (extension);
g_return_if_fail (E_IS_SOURCE (mail_identity_source));
- mail_transport_source =
- gnome_online_accounts_new_source (extension);
+ mail_transport_source = gnome_online_accounts_new_source (extension);
g_return_if_fail (E_IS_SOURCE (mail_transport_source));
/* Configure parent/child relationships. */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]