[folks] eds: Add support for contact groups/categories



commit d4931a0105291eb87ee127d88e79f5c166eba938
Author: Philip Withnall <philip tecnocode co uk>
Date:   Wed Jul 13 23:06:50 2011 +0100

    eds: Add support for contact groups/categories

 backends/eds/lib/edsf-persona-store.vala |   64 ++++++++++++++++++-
 backends/eds/lib/edsf-persona.vala       |  104 ++++++++++++++++++++++++++++++
 2 files changed, 167 insertions(+), 1 deletions(-)
---
diff --git a/backends/eds/lib/edsf-persona-store.vala b/backends/eds/lib/edsf-persona-store.vala
index 413cc1e..35caad7 100644
--- a/backends/eds/lib/edsf-persona-store.vala
+++ b/backends/eds/lib/edsf-persona-store.vala
@@ -42,6 +42,7 @@ public class Edsf.PersonaStore : Folks.PersonaStore
   private string _addressbook_uri = null;
   private E.Source _source;
   private string _query_str;
+  private bool _groups_supported = false;
 
   /**
    * The type of persona store this is.
@@ -100,7 +101,7 @@ public class Edsf.PersonaStore : Folks.PersonaStore
    */
   public override MaybeBool can_group_personas
     {
-      get { return MaybeBool.FALSE; }
+      get { return this._groups_supported ? MaybeBool.TRUE : MaybeBool.FALSE; }
     }
 
   /**
@@ -410,6 +411,29 @@ public class Edsf.PersonaStore : Folks.PersonaStore
                   "Couldn't open addressbook\n");
             }
 
+          /* Determine which fields the address book supports. This is necessary
+           * to work out whether we can support groups. */
+          string supported_fields;
+          try
+            {
+              yield this._addressbook.get_backend_property ("supported-fields",
+                  out supported_fields, null);
+
+              /* We get a comma-separated list of fields back. */
+              if (supported_fields != null)
+                {
+                  string[] fields = supported_fields.split (",");
+
+                  this._groups_supported =
+                      (Contact.field_name (ContactField.CATEGORIES) in fields);
+                }
+            }
+          catch (GLib.Error e5)
+            {
+              throw new PersonaStoreError.INVALID_ARGUMENT (
+                  "Couldn't get address book capabilities: %s", e5.message);
+            }
+
           bool got_view = false;
           try
             {
@@ -783,6 +807,44 @@ public class Edsf.PersonaStore : Folks.PersonaStore
        }
     }
 
+  internal async void _set_groups (Edsf.Persona persona,
+      Set<string> groups)
+    {
+      if (this._groups_supported == false)
+        {
+          /* Give up. */
+          return;
+        }
+
+      try
+        {
+          E.Contact contact = ((Edsf.Persona) persona).contact;
+          yield this._set_contact_groups (contact, groups);
+          yield this._addressbook.modify_contact (contact);
+        }
+      catch (GLib.Error error)
+        {
+          GLib.warning ("Can't update groups: %s\n", error.message);
+        }
+    }
+
+  private async void _set_contact_groups (E.Contact contact, Set<string> groups)
+    {
+      var categories = new GLib.List<string> ();
+
+      foreach (var group in groups)
+        {
+          if (group == "")
+            {
+              continue;
+            }
+
+          categories.prepend (group);
+        }
+
+      contact.set (ContactField.CATEGORY_LIST, categories);
+    }
+
   private void _contacts_added_cb (GLib.List<E.Contact> contacts)
     {
       var added_personas = new HashSet<Persona> ();
diff --git a/backends/eds/lib/edsf-persona.vala b/backends/eds/lib/edsf-persona.vala
index 8cf04f2..36b6e41 100644
--- a/backends/eds/lib/edsf-persona.vala
+++ b/backends/eds/lib/edsf-persona.vala
@@ -33,6 +33,7 @@ public class Edsf.Persona : Folks.Persona,
     AvatarDetails,
     EmailDetails,
     GenderDetails,
+    GroupDetails,
     ImDetails,
     LocalIdDetails,
     NameDetails,
@@ -292,6 +293,57 @@ public class Edsf.Persona : Folks.Persona,
         }
     }
 
+  private HashSet<string> _groups;
+  private Set<string> _groups_ro;
+
+  /**
+   * { inheritDoc}
+   *
+   * @since 0.5.UNRELEASED
+   */
+  public Set<string> groups
+    {
+      get { return this._groups_ro; }
+      set
+        {
+          ((Edsf.PersonaStore) this.store)._set_groups (this, value);
+        }
+    }
+
+  /**
+   * { inheritDoc}
+   *
+   * @since 0.5.UNRELEASED
+   */
+  public async void change_group (string group, bool is_member)
+      throws GLib.Error
+    {
+      /* Nothing to do? */
+      if ((is_member == true && this._groups.contains (group) == true) ||
+          (is_member == false && this._groups.contains (group) == false))
+        {
+          return;
+        }
+
+      /* Replace the current set of groups with a modified one. */
+      var new_groups = new HashSet<string> ();
+      foreach (var category_name in this._groups)
+        {
+          new_groups.add (category_name);
+        }
+
+      if (is_member == false)
+        {
+          new_groups.remove (group);
+        }
+      else
+        {
+          new_groups.add (group);
+        }
+
+      this.groups = new_groups;
+    }
+
   /**
    * Build a IID.
    *
@@ -366,6 +418,8 @@ public class Edsf.Persona : Folks.Persona,
       this._local_ids = new HashSet<string> ();
       this._local_ids_ro = this._local_ids.read_only_view;
       this._web_service_addresses = new HashMultiMap<string, string> ();
+      this._groups = new HashSet<string> ();
+      this._groups_ro = this._groups.read_only_view;
 
       this._update (contact);
     }
@@ -432,6 +486,7 @@ public class Edsf.Persona : Folks.Persona,
       this._update_addresses ();
       this._update_emails ();
       this._update_im_addresses ();
+      this._update_groups ();
       this._update_notes ();
       this._update_local_ids ();
       this._update_web_services_addresses ();
@@ -627,6 +682,55 @@ public class Edsf.Persona : Folks.Persona,
       this.notify_property ("im-addresses");
     }
 
+  private void _update_groups ()
+    {
+      unowned GLib.List<string> category_names =
+          (GLib.List<string>) this._contact.get (E.ContactField.CATEGORY_LIST);
+      var new_categories = new HashSet<string> ();
+      var added_categories = new LinkedList<string> ();
+
+      foreach (var category_name in category_names)
+        {
+          new_categories.add (category_name);
+
+          /* Is this a new category? */
+          if (!this._groups.contains (category_name))
+            {
+              added_categories.add (category_name);
+            }
+        }
+
+      /* Work out which categories have been removed. */
+      var removed_categories = new LinkedList<string> ();
+
+      foreach (var category_name in this._groups)
+        {
+          if (!new_categories.contains (category_name))
+            {
+              removed_categories.add (category_name);
+            }
+        }
+
+      /* Make the changes to this._groups and emit signals. */
+      foreach (var category_name in removed_categories)
+        {
+          this.group_changed (category_name, false);
+          this._groups.remove (category_name);
+        }
+
+      foreach (var category_name in added_categories)
+        {
+          this._groups.add (category_name);
+          this.group_changed (category_name, true);
+        }
+
+      /* Notify if anything's changed. */
+      if (added_categories.size != 0 || removed_categories.size != 0)
+        {
+          this.notify_property ("groups");
+        }
+   }
+
   /**
    * Get the avatars content
    *



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