[folks] core: Add ImDetails.change_im_addresses()



commit e390bdd7b7a2b57260f94e0c0559d3a6f340d14c
Author: Philip Withnall <philip tecnocode co uk>
Date:   Sat Aug 27 17:11:00 2011 +0100

    core: Add ImDetails.change_im_addresses()
    
    This allows the IM addresses of an implementing class to be changed
    asynchronously with proper error notification.
    
    Helps: bgo#657510

 backends/eds/lib/edsf-persona-store.vala   |    6 +-
 backends/eds/lib/edsf-persona.vala         |   16 +++-
 backends/key-file/kf-persona.vala          |  111 +++++++++++++++-------------
 backends/libsocialweb/lib/swf-persona.vala |    3 +-
 backends/telepathy/lib/tpf-persona.vala    |    3 +-
 backends/tracker/lib/trf-persona.vala      |   19 ++++-
 folks/im-details.vala                      |   21 +++++
 folks/individual.vala                      |    3 +-
 8 files changed, 117 insertions(+), 65 deletions(-)
---
diff --git a/backends/eds/lib/edsf-persona-store.vala b/backends/eds/lib/edsf-persona-store.vala
index 12b7ceb..bd9077c 100644
--- a/backends/eds/lib/edsf-persona-store.vala
+++ b/backends/eds/lib/edsf-persona-store.vala
@@ -1118,7 +1118,7 @@ public class Edsf.PersonaStore : Folks.PersonaStore
     }
 
   internal async void _set_im_fds  (Edsf.Persona persona,
-      MultiMap<string, ImFieldDetails> im_fds)
+      MultiMap<string, ImFieldDetails> im_fds) throws PropertyError
     {
       if (Utils.multi_map_str_afd_equal (persona.im_addresses, im_fds))
         return;
@@ -1129,9 +1129,9 @@ public class Edsf.PersonaStore : Folks.PersonaStore
           yield this._set_contact_im_fds (contact, im_fds);
           yield this._addressbook.modify_contact (contact, null);
         }
-      catch (GLib.Error error)
+      catch (GLib.Error e)
         {
-          GLib.warning ("Can't update IM addresses: %s\n", error.message);
+          throw this.e_client_error_to_property_error ("im-addresses", e);
         }
     }
 
diff --git a/backends/eds/lib/edsf-persona.vala b/backends/eds/lib/edsf-persona.vala
index 523b8c2..c9e8bed 100644
--- a/backends/eds/lib/edsf-persona.vala
+++ b/backends/eds/lib/edsf-persona.vala
@@ -380,10 +380,18 @@ public class Edsf.Persona : Folks.Persona,
   public MultiMap<string, ImFieldDetails> im_addresses
     {
       get { return this._im_addresses; }
-      set
-        {
-          ((Edsf.PersonaStore) this.store)._set_im_fds (this, value);
-        }
+      set { this.change_im_addresses.begin (value); }
+    }
+
+  /**
+   * { inheritDoc}
+   *
+   * @since UNRELEASED
+   */
+  public async void change_im_addresses (
+      MultiMap<string, ImFieldDetails> im_addresses) throws PropertyError
+    {
+      yield ((Edsf.PersonaStore) this.store)._set_im_fds (this, im_addresses);
     }
 
   private HashSet<string> _groups;
diff --git a/backends/key-file/kf-persona.vala b/backends/key-file/kf-persona.vala
index 4845bf7..11622b8 100644
--- a/backends/key-file/kf-persona.vala
+++ b/backends/key-file/kf-persona.vala
@@ -103,72 +103,83 @@ public class Folks.Backends.Kf.Persona : Folks.Persona,
   /**
    * { inheritDoc}
    */
+  [CCode (notify = false)]
   public MultiMap<string, ImFieldDetails> im_addresses
     {
-      get
-        { return this._im_addresses; }
+      get { return this._im_addresses; }
+      set { this.change_im_addresses.begin (value); }
+    }
 
-      set
+  /**
+   * { inheritDoc}
+   *
+   * @since UNRELEASED
+   */
+  public async void change_im_addresses (
+      MultiMap<string, ImFieldDetails> im_addresses) throws PropertyError
+    {
+      /* Remove the current IM addresses from the key file */
+      foreach (var protocol1 in this._im_addresses.get_keys ())
         {
-          /* Remove the current IM addresses from the key file */
-          foreach (var protocol in this._im_addresses.get_keys ())
+          try
             {
-              try
-                {
-                  this._key_file.remove_key (this.display_id, protocol);
-                }
-              catch (KeyFileError e)
-                {
-                  /* Ignore the error, since it's just a group or key not found
-                   * error. */
-                }
+              this._key_file.remove_key (this.display_id, protocol1);
             }
+          catch (KeyFileError e1)
+            {
+              /* Ignore the error, since it's just a group or key not found
+               * error. */
+            }
+        }
 
-          /* Add the new IM addresses to the key file and build a normalised
-           * table of them to set as the new property value */
-          var im_addresses = new HashMultiMap<string, ImFieldDetails> (
-              null, null,
-              (GLib.HashFunc) ImFieldDetails.hash,
-              (GLib.EqualFunc) ImFieldDetails.equal);
+      /* Add the new IM addresses to the key file and build a normalised
+       * table of them to set as the new property value */
+      var new_im_addresses = new HashMultiMap<string, ImFieldDetails> (
+          null, null,
+          (GLib.HashFunc) ImFieldDetails.hash,
+          (GLib.EqualFunc) ImFieldDetails.equal);
 
-          foreach (var protocol in value.get_keys ())
-            {
-              var addresses = value.get (protocol);
-              var normalised_addresses = new HashSet<string> ();
+      foreach (var protocol2 in im_addresses.get_keys ())
+        {
+          var addresses = im_addresses.get (protocol2);
+          var normalised_addresses = new HashSet<string> ();
 
-              foreach (var im_fd in addresses)
+          foreach (var im_fd in addresses)
+            {
+              string normalised_address;
+              try
                 {
-                  string normalised_address;
-                  try
-                    {
-                      normalised_address = ImDetails.normalise_im_address (
-                          im_fd.value, protocol);
-                    }
-                  catch (ImDetailsError e)
-                    {
-                      /* Somehow an error has crept into the user's
-                       * relationships.ini. Warn of it and ignore the IM
-                       * address. */
-                      warning (e.message);
-                      continue;
-                    }
-
-                  normalised_addresses.add (normalised_address);
-                  var new_im_fd = new ImFieldDetails (normalised_address);
-                  im_addresses.set (protocol, new_im_fd);
+                  normalised_address = ImDetails.normalise_im_address (
+                      im_fd.value, protocol2);
+                }
+               catch (ImDetailsError e2)
+                {
+                  throw new PropertyError.INVALID_VALUE (
+                      /* Translators: this is an error message for if the user
+                       * provides an invalid IM address. The first parameter is
+                       * an IM address (e.g. âfoo jabber orgâ), the second is
+                       * the name of a protocol (e.g. âjabberâ) and the third is
+                       * an error message. */
+                      _("Invalid IM address â%sâ for protocol â%sâ: %s"),
+                      im_fd.value, protocol2, e2.message);
                 }
 
-              string[] addrs = (string[]) normalised_addresses.to_array ();
-              addrs.length = normalised_addresses.size;
-
-              this._key_file.set_string_list (this.display_id, protocol, addrs);
+              normalised_addresses.add (normalised_address);
+              var new_im_fd = new ImFieldDetails (normalised_address);
+              new_im_addresses.set (protocol2, new_im_fd);
             }
 
-          this._im_addresses = im_addresses;
+          string[] addrs = (string[]) normalised_addresses.to_array ();
+          addrs.length = normalised_addresses.size;
 
-          /* Get the PersonaStore to save the key file */
-          ((Kf.PersonaStore) this.store).save_key_file.begin ();
+          this._key_file.set_string_list (this.display_id, protocol2, addrs);
         }
+
+      /* Get the PersonaStore to save the key file */
+      yield ((Kf.PersonaStore) this.store).save_key_file ();
+
+      this._im_addresses = new_im_addresses;
+      this.notify_property ("im-addresses");
     }
 
   /**
diff --git a/backends/libsocialweb/lib/swf-persona.vala b/backends/libsocialweb/lib/swf-persona.vala
index ba84326..91fdbf2 100644
--- a/backends/libsocialweb/lib/swf-persona.vala
+++ b/backends/libsocialweb/lib/swf-persona.vala
@@ -136,10 +136,11 @@ public class Swf.Persona : Folks.Persona,
   /**
    * { inheritDoc}
    */
+  [CCode (notify = false)]
   public MultiMap<string, ImFieldDetails> im_addresses
     {
       get { return this._im_addresses; }
-      private set {}
+      set { this.change_im_addresses.begin (value); }
     }
 
   /**
diff --git a/backends/telepathy/lib/tpf-persona.vala b/backends/telepathy/lib/tpf-persona.vala
index 307a451..279bf62 100644
--- a/backends/telepathy/lib/tpf-persona.vala
+++ b/backends/telepathy/lib/tpf-persona.vala
@@ -176,10 +176,11 @@ public class Tpf.Persona : Folks.Persona,
    *
    * See { link Folks.ImDetails.im_addresses}.
    */
+  [CCode (notify = false)]
   public MultiMap<string, ImFieldDetails> im_addresses
     {
       get { return this._im_addresses; }
-      private set {}
+      set { this.change_im_addresses.begin (value); }
     }
 
   /**
diff --git a/backends/tracker/lib/trf-persona.vala b/backends/tracker/lib/trf-persona.vala
index 0203e92..7b202be 100644
--- a/backends/tracker/lib/trf-persona.vala
+++ b/backends/tracker/lib/trf-persona.vala
@@ -284,14 +284,23 @@ public class Trf.Persona : Folks.Persona,
   /**
    * { inheritDoc}
    */
+  [CCode (notify = false)]
   public MultiMap<string, ImFieldDetails> im_addresses
     {
       get { return this._im_addresses; }
-      public set
-        {
-          ((Trf.PersonaStore) this.store)._set_im_addresses (this,
-              value);
-        }
+      set { this.change_im_addresses.begin (value); }
+    }
+
+  /**
+   * { inheritDoc}
+   *
+   * @since UNRELEASED
+   */
+  public async void change_im_addresses (
+      MultiMap<string, ImFieldDetails> im_addresses) throws PropertyError
+    {
+      yield ((Trf.PersonaStore) this.store)._set_im_addresses (this,
+          im_addresses);
     }
 
   /**
diff --git a/folks/im-details.vala b/folks/im-details.vala
index 4536ba6..11cab04 100644
--- a/folks/im-details.vala
+++ b/folks/im-details.vala
@@ -1,5 +1,6 @@
 /*
  * Copyright (C) 2010 Collabora Ltd.
+ * Copyright (C) 2011 Philip Withnall
  *
  * This library is free software: you can redistribute it and/or modify
  * it under the terms of the GNU Lesser General Public License as published by
@@ -110,6 +111,26 @@ public interface Folks.ImDetails : Object
     }
 
   /**
+   * Change the contact's set of IM addresses.
+   *
+   * It's preferred to call this rather than setting
+   * { link ImDetails.im_addresses} directly, as this method gives error
+   * notification and will only return once the IM addresses have been written
+   * to the relevant backing store (or the operation's failed).
+   *
+   * @param im_addresses the new map of protocols to IM addresses
+   * @throws PropertyError if setting the IM addresses failed
+   * @since UNRELEASED
+   */
+  public virtual async void change_im_addresses (
+      MultiMap<string, ImFieldDetails> im_addresses) throws PropertyError
+    {
+      /* Default implementation. */
+      throw new PropertyError.NOT_WRITEABLE (
+          _("IM addresses are not writeable on this contact."));
+    }
+
+  /**
    * Normalise an IM address so that it's suitable for string comparison.
    *
    * IM addresses for various protocols can be represented in different ways,
diff --git a/folks/individual.vala b/folks/individual.vala
index d55e6de..a1ebb3d 100644
--- a/folks/individual.vala
+++ b/folks/individual.vala
@@ -517,10 +517,11 @@ public class Folks.Individual : Object,
   /**
    * { inheritDoc}
    */
+  [CCode (notify = false)]
   public MultiMap<string, ImFieldDetails> im_addresses
     {
       get { return this._im_addresses; }
-      private set {}
+      set { this.change_im_addresses.begin (value); } /* not writeable */
     }
 
   /**



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