[folks] core: Add FavouriteDetails.change_is_favourite()
- From: Philip Withnall <pwithnall src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [folks] core: Add FavouriteDetails.change_is_favourite()
- Date: Fri, 2 Sep 2011 18:31:02 +0000 (UTC)
commit 073dc310a0294bf5c26f2e31ebf4073a543db0f6
Author: Philip Withnall <philip tecnocode co uk>
Date: Sun Aug 28 20:19:09 2011 +0100
core: Add FavouriteDetails.change_is_favourite()
This allows the favouriteness of an implementing class to be changed
asynchronously with proper error notification.
Helps: bgo#657510
backends/telepathy/lib/tpf-persona-store.vala | 8 ++--
backends/telepathy/lib/tpf-persona.vala | 26 ++++++++--
backends/tracker/lib/trf-persona.vala | 41 ++++++++++------
folks/favourite-details.vala | 21 ++++++++
folks/individual.vala | 65 ++++++++++++++++++++-----
po/POTFILES.in | 1 +
po/POTFILES.skip | 1 +
7 files changed, 125 insertions(+), 38 deletions(-)
---
diff --git a/backends/telepathy/lib/tpf-persona-store.vala b/backends/telepathy/lib/tpf-persona-store.vala
index 3346f9e..37532c8 100644
--- a/backends/telepathy/lib/tpf-persona-store.vala
+++ b/backends/telepathy/lib/tpf-persona-store.vala
@@ -1972,17 +1972,16 @@ public class Tpf.PersonaStore : Folks.PersonaStore
* Telepathy logger service, so may fail if that connection is not present.
*/
internal async void change_is_favourite (Folks.Persona persona,
- bool is_favourite)
+ bool is_favourite) throws PropertyError
{
/* It's possible for us to not be able to connect to the logger;
* see _connection_ready_cb() */
if (this._logger == null)
{
- warning (
+ throw new PropertyError.UNKNOWN_ERROR (
/* Translators: "telepathy-logger" is the name of an application,
* and should not be translated. */
_("Failed to change favorite without a connection to the telepathy-logger service."));
- return;
}
try
@@ -1998,7 +1997,8 @@ public class Tpf.PersonaStore : Folks.PersonaStore
}
catch (GLib.Error e)
{
- warning (_("Failed to change a persona's favorite status."));
+ throw new PropertyError.UNKNOWN_ERROR (
+ _("Failed to change a persona's favorite status."));
}
}
diff --git a/backends/telepathy/lib/tpf-persona.vala b/backends/telepathy/lib/tpf-persona.vala
index b5fa21e..73aed69 100644
--- a/backends/telepathy/lib/tpf-persona.vala
+++ b/backends/telepathy/lib/tpf-persona.vala
@@ -163,19 +163,33 @@ public class Tpf.Persona : Folks.Persona,
*
* See { link Folks.FavouriteDetails.is_favourite}.
*/
+ [CCode (notify = false)]
public bool is_favourite
{
get { return this._is_favourite; }
+ set { this.change_is_favourite.begin (value); }
+ }
- set
+ /**
+ * { inheritDoc}
+ *
+ * @since UNRELEASED
+ */
+ public async void change_is_favourite (bool is_favourite) throws PropertyError
+ {
+ if (this._is_favourite == is_favourite)
{
- if (this._is_favourite == value)
- return;
+ return;
+ }
- if (this._is_constructed)
- ((Tpf.PersonaStore) this.store).change_is_favourite (this, value);
- this._is_favourite = value;
+ if (this._is_constructed)
+ {
+ yield ((Tpf.PersonaStore) this.store).change_is_favourite (this,
+ is_favourite);
}
+
+ this._is_favourite = is_favourite;
+ this.notify_property ("is-favourite");
}
/**
diff --git a/backends/tracker/lib/trf-persona.vala b/backends/tracker/lib/trf-persona.vala
index 26ffdbb..0076197 100644
--- a/backends/tracker/lib/trf-persona.vala
+++ b/backends/tracker/lib/trf-persona.vala
@@ -332,23 +332,29 @@ public class Trf.Persona : Folks.Persona,
/**
* Whether this contact is a user-defined favourite.
*/
+ [CCode (notify = false)]
public bool is_favourite
{
get { return this._is_favourite; }
-
- set
- {
- if (this._is_favourite == value)
- return;
-
- /* Note:
- * this property will be set (and notified)
- * once we receive a notification event from Tracker
- */
- ((Trf.PersonaStore) this.store)._set_is_favourite (this, value);
- }
+ set { this.change_is_favourite.begin (value); }
}
+ /**
+ * { inheritDoc}
+ *
+ * @since UNRELEASED
+ */
+ public async void change_is_favourite (bool is_favourite) throws PropertyError
+ {
+ if (this._is_favourite == is_favourite)
+ {
+ return;
+ }
+
+ yield ((Trf.PersonaStore) this.store)._set_is_favourite (this,
+ is_favourite);
+ }
+
private HashSet<string> _local_ids;
private Set<string> _local_ids_ro;
@@ -1259,8 +1265,7 @@ public class Trf.Persona : Folks.Persona,
private void _update_favourite ()
{
var favourite = this._cursor.get_string (Trf.Fields.FAVOURITE).dup ();
-
- this._is_favourite = false;
+ var is_favourite = false;
if (favourite != null)
{
@@ -1270,10 +1275,16 @@ public class Trf.Persona : Folks.Persona,
{
if (int.parse (tag) == favorite_tracker_id)
{
- this._is_favourite = true;
+ is_favourite = true;
}
}
}
+
+ if (is_favourite != this._is_favourite)
+ {
+ this._is_favourite = is_favourite;
+ this.notify_property ("is-favourite");
+ }
}
/**
diff --git a/folks/favourite-details.vala b/folks/favourite-details.vala
index c1f0fa2..8618c1c 100644
--- a/folks/favourite-details.vala
+++ b/folks/favourite-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
@@ -30,4 +31,24 @@ public interface Folks.FavouriteDetails : Object
* Whether this contact is a user-defined favourite.
*/
public abstract bool is_favourite { get; set; }
+
+ /**
+ * Change whether the contact is a user-defined favourite.
+ *
+ * It's preferred to call this rather than setting
+ * { link FavouriteDetails.is_favourite} directly, as this method gives error
+ * notification and will only return once the favouriteness has been written
+ * to the relevant backing store (or the operation's failed).
+ *
+ * @param is_favourite `true` if the contact is a favourite; `false` otherwise
+ * @throws PropertyError if setting the favouriteness failed
+ * @since UNRELEASED
+ */
+ public virtual async void change_is_favourite (bool is_favourite)
+ throws PropertyError
+ {
+ /* Default implementation. */
+ throw new PropertyError.NOT_WRITEABLE (
+ _("Favourite status is not writeable on this contact."));
+ }
}
diff --git a/folks/individual.vala b/folks/individual.vala
index 9823148..850fa64 100644
--- a/folks/individual.vala
+++ b/folks/individual.vala
@@ -492,31 +492,70 @@ public class Folks.Individual : Object,
* This property is `true` if any of this Individual's { link Persona}s are
* favourites).
*/
+ [CCode (notify = false)]
public bool is_favourite
{
get { return this._is_favourite; }
+ set { this.change_is_favourite.begin (value); }
+ }
- set
+ /**
+ * { inheritDoc}
+ *
+ * @since UNRELEASED
+ */
+ public async void change_is_favourite (bool is_favourite) throws PropertyError
+ {
+ if (this._is_favourite == is_favourite)
{
- if (this._is_favourite == value)
- return;
+ return;
+ }
- debug ("Setting '%s' favourite status to %s", this.id,
- value ? "TRUE" : "FALSE");
+ debug ("Setting '%s' favourite status to %sâ", this.id,
+ is_favourite ? "TRUE" : "FALSE");
- this._is_favourite = value;
- foreach (var p in this._persona_set)
+ PropertyError? persona_error = null;
+ var is_favourite_changed = false;
+
+ /* Try to write it to only the Personas which have "is-favourite" as a
+ * writeable property.
+ *
+ * NOTE: We don't check whether the persona's store is writeable, as we
+ * want is-favourite status to propagate to all stores, if possible. This
+ * is one property which is harmless to propagate. */
+ foreach (var p in this._persona_set)
+ {
+ var a = p as FavouriteDetails;
+ if (a != null && "is-favourite" in p.writeable_properties)
{
- if (p is FavouriteDetails)
+ try
{
- SignalHandler.block_by_func (p,
- (void*) this._notify_is_favourite_cb, this);
- ((FavouriteDetails) p).is_favourite = value;
- SignalHandler.unblock_by_func (p,
- (void*) this._notify_is_favourite_cb, this);
+ yield a.change_is_favourite (is_favourite);
+ debug (" written to persona '%s'", p.uid);
+ is_favourite_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;
+ }
}
}
}
+
+ /* Failure? */
+ if (is_favourite_changed == false)
+ {
+ assert (persona_error != null);
+ throw persona_error;
+ }
+
+ /* Update our copy of the property. */
+ this._is_favourite = is_favourite;
+ this.notify_property ("is-favourite");
}
/**
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 72120ca..839882e 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -12,6 +12,7 @@ folks/avatar-details.vala
folks/backend-store.vala
folks/birthday-details.vala
folks/email-details.vala
+folks/favourite-details.vala
folks/im-details.vala
folks/individual-aggregator.vala
folks/postal-address-details.vala
diff --git a/po/POTFILES.skip b/po/POTFILES.skip
index 321fa71..8adfe1c 100644
--- a/po/POTFILES.skip
+++ b/po/POTFILES.skip
@@ -11,6 +11,7 @@ folks/avatar-details.c
folks/backend-store.c
folks/birthday-details.c
folks/email-details.c
+folks/favourite-details.c
folks/im-details.c
folks/individual-aggregator.c
folks/postal-address-details.c
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]