[folks] core: Add GroupDetails.change_groups()
- From: Philip Withnall <pwithnall src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [folks] core: Add GroupDetails.change_groups()
- Date: Fri, 2 Sep 2011 18:32:07 +0000 (UTC)
commit 6166dda19b16af130b61f61f3ae3b2a92a49cba7
Author: Philip Withnall <philip tecnocode co uk>
Date: Tue Aug 30 23:24:58 2011 +0100
core: Add GroupDetails.change_groups()
This allows the groups of an implementing class to all be changed
simultaneously, asynchronously and with proper error notification.
Closes: bgo#657510
NEWS | 2 +
backends/eds/lib/edsf-persona-store.vala | 6 ++--
backends/eds/lib/edsf-persona.vala | 17 +++++++---
backends/telepathy/lib/tpf-persona.vala | 46 +++++++++++++++------------
folks/group-details.vala | 20 ++++++++++++
folks/individual.vala | 51 +++++++++++++++++++++++++++---
6 files changed, 109 insertions(+), 33 deletions(-)
---
diff --git a/NEWS b/NEWS
index c7f8104..0889982 100644
--- a/NEWS
+++ b/NEWS
@@ -6,12 +6,14 @@ Bugs fixed:
* Bug 653777 â Would be nice to have a helper function to create a writable
persona
* Bug 657635 â Linking personas from different (e-d-s) stores is not working
+* Bug 657510 â Add asynchronous property setter methods
API changes:
* Add PersonaStore:always-writeable-properties property
* Add IndividualAggregatorError.PROPERTY_NOT_WRITEABLE error
* Add IndividualAggregator.ensure_individual_property_writeable()
* Add Folks.PropertyError
+* Add *Details.change_*() virtual methods
Overview of changes from libfolks 0.6.0 to libfolks 0.6.1
=========================================================
diff --git a/backends/eds/lib/edsf-persona-store.vala b/backends/eds/lib/edsf-persona-store.vala
index 9cf9274..92cad0a 100644
--- a/backends/eds/lib/edsf-persona-store.vala
+++ b/backends/eds/lib/edsf-persona-store.vala
@@ -1193,7 +1193,7 @@ public class Edsf.PersonaStore : Folks.PersonaStore
}
internal async void _set_groups (Edsf.Persona persona,
- Set<string> groups)
+ Set<string> groups) throws PropertyError
{
if (this._groups_supported == false)
{
@@ -1207,9 +1207,9 @@ public class Edsf.PersonaStore : Folks.PersonaStore
yield this._set_contact_groups (contact, groups);
yield this._addressbook.modify_contact (contact, null);
}
- catch (GLib.Error error)
+ catch (GLib.Error e)
{
- GLib.warning ("Can't update groups: %s\n", error.message);
+ throw this.e_client_error_to_property_error ("groups", e);
}
}
diff --git a/backends/eds/lib/edsf-persona.vala b/backends/eds/lib/edsf-persona.vala
index e7ed2ed..a5c17de 100644
--- a/backends/eds/lib/edsf-persona.vala
+++ b/backends/eds/lib/edsf-persona.vala
@@ -500,10 +500,7 @@ public class Edsf.Persona : Folks.Persona,
public Set<string> groups
{
get { return this._groups_ro; }
- set
- {
- ((Edsf.PersonaStore) this.store)._set_groups (this, value);
- }
+ set { this.change_groups.begin (value); }
}
/**
@@ -537,7 +534,17 @@ public class Edsf.Persona : Folks.Persona,
new_groups.add (group);
}
- this.groups = new_groups;
+ yield this.change_groups (new_groups);
+ }
+
+ /**
+ * { inheritDoc}
+ *
+ * @since UNRELEASED
+ */
+ public async void change_groups (Set<string> groups) throws PropertyError
+ {
+ yield ((Edsf.PersonaStore) this.store)._set_groups (this, groups);
}
/**
diff --git a/backends/telepathy/lib/tpf-persona.vala b/backends/telepathy/lib/tpf-persona.vala
index 73aed69..f80ba44 100644
--- a/backends/telepathy/lib/tpf-persona.vala
+++ b/backends/telepathy/lib/tpf-persona.vala
@@ -209,29 +209,11 @@ public class Tpf.Persona : Folks.Persona,
*
* See { link Folks.GroupDetails.groups}.
*/
+ [CCode (notify = false)]
public Set<string> groups
{
get { return this._groups_ro; }
-
- set
- {
- foreach (var group in value)
- {
- if (this._groups.contains (group) == false)
- this._change_group (group, true);
- }
-
- foreach (var group in this._groups)
- {
- if (value.contains (group) == false)
- this._change_group (group, true);
- }
-
- /* Since we're only changing the members of this._groups, rather than
- * replacing it with a new instance, we have to manually emit the
- * notification. */
- this.notify_property ("groups");
- }
+ set { this.change_groups.begin (value); }
}
/**
@@ -270,6 +252,30 @@ public class Tpf.Persona : Folks.Persona,
}
/**
+ * { inheritDoc}
+ *
+ * @since UNRELEASED
+ */
+ public async void change_groups (Set<string> groups) throws PropertyError
+ {
+ Tpf.PersonaStore store = (Tpf.PersonaStore) this.store;
+
+ foreach (var group1 in groups)
+ {
+ if (this._groups.contains (group1) == false)
+ yield store._change_group_membership (this, group1, true);
+ }
+
+ foreach (var group2 in this._groups)
+ {
+ if (groups.contains (group2) == false)
+ yield store._change_group_membership (this, group2, false);
+ }
+
+ this.notify_property ("groups");
+ }
+
+ /**
* The Telepathy contact represented by this persona.
*
* Note that this may be `null` if the { link PersonaStore} providing this
diff --git a/folks/group-details.vala b/folks/group-details.vala
index 44c5aa2..b283ef8 100644
--- a/folks/group-details.vala
+++ b/folks/group-details.vala
@@ -147,4 +147,24 @@ public interface Folks.GroupDetails : Object
* @since 0.1.11
*/
public async signal void group_changed (string group, bool is_member);
+
+ /**
+ * Change the contact's groups.
+ *
+ * It's preferred to call this rather than setting { link GroupDetails.groups}
+ * directly, as this method gives error notification and will only return once
+ * the groups have been written to the relevant backing store (or the
+ * operation's failed).
+ *
+ * @param groups the complete set of groups the contact should be a member of
+ * @throws PropertyError if setting the groups failed
+ * @since UNRELEASED
+ */
+ public virtual async void change_groups (Set<string> groups)
+ throws PropertyError
+ {
+ /* Default implementation. */
+ throw new PropertyError.NOT_WRITEABLE (
+ _("Groups are not writeable on this contact."));
+ }
}
diff --git a/folks/individual.vala b/folks/individual.vala
index 9a2f212..d418032 100644
--- a/folks/individual.vala
+++ b/folks/individual.vala
@@ -564,19 +564,60 @@ public class Folks.Individual : Object,
/**
* { inheritDoc}
*/
+ [CCode (notify = false)]
public Set<string> groups
{
get { return this._groups_ro; }
+ set { this.change_groups.begin (value); }
+ }
+
+ /**
+ * { inheritDoc}
+ *
+ * @since UNRELEASED
+ */
+ public async void change_groups (Set<string> groups) throws PropertyError
+ {
+ debug ("Setting '%s' groupsâ", this.id);
- set
+ PropertyError? persona_error = null;
+ var groups_changed = false;
+
+ /* Try to write it to only the Personas which have "groups" as a
+ * writeable property. */
+ foreach (var p in this._persona_set)
{
- foreach (var p in this._persona_set)
+ var g = p as GroupDetails;
+ if (g != null && p.store.is_writeable == true &&
+ "groups" in p.writeable_properties)
{
- if (p is GroupDetails && ((Persona) p).store.is_writeable == true)
- ((GroupDetails) p).groups = value;
+ try
+ {
+ yield g.change_groups (groups);
+ debug (" written to persona '%s'", p.uid);
+ groups_changed = true;
+ }
+ catch (PropertyError e)
+ {
+ /* Store the first error so we can throw it if setting the
+ * property fails on every other persona. */
+ if (persona_error == null)
+ {
+ persona_error = e;
+ }
+ }
}
- this._update_groups ();
}
+
+ /* Failure? */
+ if (groups_changed == false)
+ {
+ assert (persona_error != null);
+ throw persona_error;
+ }
+
+ /* Update our copy of the property. */
+ this._update_groups ();
}
/**
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]