[folks] core: Add AvatarDetails.change_avatar()



commit a1db7b08184ee325bd5e8b22d6c361b784a3a2f2
Author: Philip Withnall <philip tecnocode co uk>
Date:   Sun Aug 28 19:33:18 2011 +0100

    core: Add AvatarDetails.change_avatar()
    
    This allows the avatar of an implementing class to be changed asynchronously
    with proper error notification.
    
    Helps: bgo#657510

 backends/eds/lib/edsf-persona-store.vala   |   29 +++++++++++++++++++++------
 backends/eds/lib/edsf-persona.vala         |   19 ++++++++++++-----
 backends/libsocialweb/lib/swf-persona.vala |   19 ++++++++++++++---
 backends/telepathy/lib/tpf-persona.vala    |   18 +++++++++++++---
 backends/tracker/lib/trf-persona.vala      |   16 +++++++++++---
 folks/avatar-details.vala                  |   22 +++++++++++++++++++++
 folks/individual.vala                      |   16 ++++++++++++--
 po/POTFILES.in                             |    1 +
 po/POTFILES.skip                           |    1 +
 9 files changed, 113 insertions(+), 28 deletions(-)
---
diff --git a/backends/eds/lib/edsf-persona-store.vala b/backends/eds/lib/edsf-persona-store.vala
index bd9077c..f665a5c 100644
--- a/backends/eds/lib/edsf-persona-store.vala
+++ b/backends/eds/lib/edsf-persona-store.vala
@@ -272,8 +272,16 @@ public class Edsf.PersonaStore : Folks.PersonaStore
             }
           else if (k == Folks.PersonaStore.detail_key (PersonaDetail.AVATAR))
             {
-              var avatar = (LoadableIcon?) v.get_object ();
-              yield this._set_contact_avatar (contact, avatar);
+              try
+                {
+                  var avatar = (LoadableIcon?) v.get_object ();
+                  yield this._set_contact_avatar (contact, avatar);
+                }
+              catch (PropertyError e1)
+                {
+                  warning ("Couldn't set avatar on the EContact: %s",
+                      e1.message);
+                }
             }
           else if (k == Folks.PersonaStore.detail_key (
                 PersonaDetail.IM_ADDRESSES))
@@ -683,6 +691,7 @@ public class Edsf.PersonaStore : Folks.PersonaStore
     }
 
   internal async void _set_avatar (Edsf.Persona persona, LoadableIcon? avatar)
+      throws PropertyError
     {
       /* Return early if there will be no change */
       if ((persona.avatar == null && avatar == null) ||
@@ -697,9 +706,13 @@ public class Edsf.PersonaStore : Folks.PersonaStore
           yield this._set_contact_avatar (contact, avatar);
           yield this._addressbook.modify_contact (contact, null);
         }
-      catch (GLib.Error e)
+      catch (PropertyError e1)
+        {
+          throw e1;
+        }
+      catch (GLib.Error e2)
         {
-          GLib.warning ("Can't update avatar: %s\n", e.message);
+          throw this.e_client_error_to_property_error ("avatar", e2);
         }
     }
 
@@ -867,7 +880,7 @@ public class Edsf.PersonaStore : Folks.PersonaStore
     }
 
   private async void _set_contact_avatar (E.Contact contact,
-      LoadableIcon? avatar)
+      LoadableIcon? avatar) throws PropertyError
     {
       if (avatar == null)
         {
@@ -905,8 +918,10 @@ public class Edsf.PersonaStore : Folks.PersonaStore
             }
           catch (GLib.Error e1)
             {
-              warning ("Couldn't set avatar on the EContact : %s",
-                  e1.message);
+              /* Loading/Reading the avatar failed. */
+              throw new PropertyError.INVALID_VALUE (
+                  /* Translators: the parameter is an error message. */
+                  _("Can't update avatar: %s"), e1.message);
             }
         }
     }
diff --git a/backends/eds/lib/edsf-persona.vala b/backends/eds/lib/edsf-persona.vala
index c9e8bed..208b2d2 100644
--- a/backends/eds/lib/edsf-persona.vala
+++ b/backends/eds/lib/edsf-persona.vala
@@ -267,13 +267,20 @@ public class Edsf.Persona : Folks.Persona,
   public LoadableIcon? avatar
     {
       get { return this._avatar; }
-      set
+      set { this.change_avatar.begin (value); }
+    }
+
+  /**
+   * { inheritDoc}
+   *
+   * @since UNRELEASED
+   */
+  public async void change_avatar (LoadableIcon? avatar) throws PropertyError
+    {
+      if (this._avatar == null ||
+          !this._avatar.equal (avatar))
         {
-          if (this._avatar == null ||
-              !this._avatar.equal (value))
-            {
-              ((Edsf.PersonaStore) this.store)._set_avatar (this, value);
-            }
+          yield ((Edsf.PersonaStore) this.store)._set_avatar (this, avatar);
         }
     }
 
diff --git a/backends/libsocialweb/lib/swf-persona.vala b/backends/libsocialweb/lib/swf-persona.vala
index 91fdbf2..b16ee6a 100644
--- a/backends/libsocialweb/lib/swf-persona.vala
+++ b/backends/libsocialweb/lib/swf-persona.vala
@@ -69,6 +69,8 @@ public class Swf.Persona : Folks.Persona,
       get { return this._writeable_properties; }
     }
 
+  private LoadableIcon? _avatar = null;
+
   /**
    * An avatar for the Persona.
    *
@@ -76,7 +78,12 @@ public class Swf.Persona : Folks.Persona,
    *
    * @since 0.6.0
    */
-  public LoadableIcon? avatar { get; private set; }
+  [CCode (notify = false)]
+  public LoadableIcon? avatar
+    {
+      get { return this._avatar; }
+      set { this.change_avatar.begin (value); } /* not writeable */
+    }
 
   /**
    * { inheritDoc}
@@ -292,12 +299,16 @@ public class Swf.Persona : Folks.Persona,
       if (avatar_path != null)
         {
           var icon = new FileIcon (File.new_for_path (avatar_path));
-          if (this.avatar == null || !this.avatar.equal (icon))
-            this.avatar = icon;
+          if (this._avatar == null || !this._avatar.equal (icon))
+            {
+              this._avatar = icon;
+              this.notify_property ("avatar");
+            }
         }
       else
         {
-          this.avatar = null;
+          this._avatar = null;
+          this.notify_property ("avatar");
         }
 
       var structured_name = new StructuredName.simple (
diff --git a/backends/telepathy/lib/tpf-persona.vala b/backends/telepathy/lib/tpf-persona.vala
index 279bf62..b5fa21e 100644
--- a/backends/telepathy/lib/tpf-persona.vala
+++ b/backends/telepathy/lib/tpf-persona.vala
@@ -66,6 +66,8 @@ public class Tpf.Persona : Folks.Persona,
    */
   public bool is_in_contact_list { get; set; }
 
+  private LoadableIcon? _avatar = null;
+
   /**
    * An avatar for the Persona.
    *
@@ -73,7 +75,12 @@ public class Tpf.Persona : Folks.Persona,
    *
    * @since 0.6.0
    */
-  public LoadableIcon? avatar { get; private set; }
+  [CCode (notify = false)]
+  public LoadableIcon? avatar
+    {
+      get { return this._avatar; }
+      set { this.change_avatar.begin (value); } /* not writeable */
+    }
 
   /**
    * The Persona's presence type.
@@ -423,7 +430,7 @@ public class Tpf.Persona : Folks.Persona,
       this._alias = alias;
       this._is_favourite = is_favourite;
       this.is_in_contact_list = is_in_contact_list;
-      this.avatar = avatar;
+      this._avatar = avatar;
 
       // Make the persona appear offline
       this.presence_type = PresenceType.OFFLINE;
@@ -506,7 +513,10 @@ public class Tpf.Persona : Folks.Persona,
       if (file != null)
         icon = new FileIcon (file);
 
-      if (this.avatar == null || icon == null || !this.avatar.equal (icon))
-        this.avatar = (LoadableIcon) icon;
+      if (this._avatar == null || icon == null || !this._avatar.equal (icon))
+        {
+          this._avatar = (LoadableIcon) icon;
+          this.notify_property ("avatar");
+        }
     }
 }
diff --git a/backends/tracker/lib/trf-persona.vala b/backends/tracker/lib/trf-persona.vala
index 7b202be..d84b676 100644
--- a/backends/tracker/lib/trf-persona.vala
+++ b/backends/tracker/lib/trf-persona.vala
@@ -142,13 +142,21 @@ public class Trf.Persona : Folks.Persona,
    *
    * @since 0.6.0
    */
+  [CCode (notify = false)]
   public LoadableIcon? avatar
     {
       get { return this._avatar; }
-      public set
-        {
-          ((Trf.PersonaStore) this.store)._set_avatar (this, value);
-        }
+      set { this.change_avatar.begin (value); }
+    }
+
+  /**
+   * { inheritDoc}
+   *
+   * @since UNRELEASED
+   */
+  public async void change_avatar (LoadableIcon? avatar) throws PropertyError
+    {
+      yield ((Trf.PersonaStore) this.store)._set_avatar (this, avatar);
     }
 
   private StructuredName _structured_name;
diff --git a/folks/avatar-details.vala b/folks/avatar-details.vala
index b69608a..7e9feed 100644
--- a/folks/avatar-details.vala
+++ b/folks/avatar-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
@@ -16,6 +17,7 @@
  *
  * Authors:
  *       Travis Reitter <travis reitter collabora co uk>
+ *       Philip Withnall <philip tecnocode co uk>
  */
 
 using GLib;
@@ -36,4 +38,24 @@ public interface Folks.AvatarDetails : Object
    * @since 0.6.0
    */
   public abstract LoadableIcon? avatar { get; set; }
+
+  /**
+   * Change the contact's avatar.
+   *
+   * It's preferred to call this rather than setting
+   * { link AvatarDetails.avatar} directly, as this method gives error
+   * notification and will only return once the avatar has been written to the
+   * relevant backing store (or the operation's failed).
+   *
+   * @param avatar the new avatar (or `null` to unset the avatar)
+   * @throws PropertyError if setting the avatar failed
+   * @since UNRELEASED
+   */
+  public virtual async void change_avatar (LoadableIcon? avatar)
+      throws PropertyError
+    {
+      /* Default implementation. */
+      throw new PropertyError.NOT_WRITEABLE (
+          _("Avatar is not writeable on this contact."));
+    }
 }
diff --git a/folks/individual.vala b/folks/individual.vala
index a1ebb3d..ac0bc3c 100644
--- a/folks/individual.vala
+++ b/folks/individual.vala
@@ -115,12 +115,19 @@ public class Folks.Individual : Object,
    */
   public TrustLevel trust_level { get; private set; }
 
+  private LoadableIcon? _avatar = null;
+
   /**
    * { inheritDoc}
    *
    * @since 0.6.0
    */
-  public LoadableIcon? avatar { get; private set; }
+  [CCode (notify = false)]
+  public LoadableIcon? avatar
+    {
+      get { return this._avatar; }
+      set { this.change_avatar.begin (value); } /* not writeable */
+    }
 
   /**
    * { inheritDoc}
@@ -1072,8 +1079,11 @@ public class Folks.Individual : Object,
         }
 
       /* only notify if the value has changed */
-      if (this.avatar == null || !this.avatar.equal (avatar))
-        this.avatar = avatar;
+      if (this._avatar == null || !this._avatar.equal (avatar))
+        {
+          this._avatar = avatar;
+          this.notify_property ("avatar");
+        }
     }
 
   private void _update_trust_level ()
diff --git a/po/POTFILES.in b/po/POTFILES.in
index f477b87..640e25a 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -8,6 +8,7 @@ backends/telepathy/lib/tpf-persona-store.vala
 backends/telepathy/lib/tpf-persona.vala
 backends/tracker/lib/trf-persona-store.vala
 folks/alias-details.vala
+folks/avatar-details.vala
 folks/backend-store.vala
 folks/im-details.vala
 folks/individual-aggregator.vala
diff --git a/po/POTFILES.skip b/po/POTFILES.skip
index f8ac551..898acd8 100644
--- a/po/POTFILES.skip
+++ b/po/POTFILES.skip
@@ -7,6 +7,7 @@ backends/telepathy/lib/tpf-persona.c
 backends/tracker/lib/trf-persona-store.c
 docs/gtk-doc/folks-telepathy/ccomments/tp-lowlevel.c
 folks/alias-details.c
+folks/avatar-details.c
 folks/backend-store.c
 folks/im-details.c
 folks/individual-aggregator.c



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