diff options
author | Simon McVittie <simon.mcvittie@collabora.co.uk> | 2013-01-08 12:51:27 +0000 |
---|---|---|
committer | Simon McVittie <simon.mcvittie@collabora.co.uk> | 2013-01-08 15:08:08 +0000 |
commit | 29766a5cfc785bc314b40ec87196e6b78bc0b68a (patch) | |
tree | 3a2f0e0ef3e4c3365de3965ff84dd01fba2c2f8d | |
parent | e31205cc89683f332a1c0fef4edc834d80854d7f (diff) |
Names mixin: add a default implementation of each method
This makes them all mandatory, which is a simplification.
-rw-r--r-- | telepathy-glib/names-mixin.c | 189 |
1 files changed, 125 insertions, 64 deletions
diff --git a/telepathy-glib/names-mixin.c b/telepathy-glib/names-mixin.c index 0179e8e72..80b0f399d 100644 --- a/telepathy-glib/names-mixin.c +++ b/telepathy-glib/names-mixin.c @@ -173,23 +173,41 @@ /** * TpNamesInterface: * @parent: the parent interface - * @request_nickname_async: a #TpNamesInterfaceRequestNicknameAsyncFunc + * @request_nickname_async: virtual function to re-download a contact's + * nickname from the server * @request_nickname_finish: virtual function to interpret the result * of @request_nickname_async - * @set_nickname_async: a #TpNamesInterfaceSetNicknameAsyncFunc + * @set_nickname_async: virtual function to set the user's nickname * @set_nickname_finish: virtual function to interpret the result * of @set_nickname_async - * @set_local_alias_async: a #TpNamesInterfaceSetLocalAliasAsyncFunc + * @set_local_alias_async: virtual function to set a contact's local alias * @set_local_alias_finish: virtual function to interpret the result * of @set_local_alias_async * * Interface structure of virtual methods needed by #TpNamesMixin. * + * The default implementation of @request_nickname_async returns whatever + * nickname was last stored in the mixin by + * tp_names_mixin_nicknames_changed() or tp_names_mixin_one_nickname_changed() + * (or "" if no nickname is stored for that contact), indicating that + * either nicknames are not supported at all, or all nicknames are known + * already. Connection managers for protocols where the user may need to + * "refresh" a contact's nickname by re-querying the server, such as XMPP, + * should override this method. + * * The @request_nickname_finish function has a default implementation, * which assumes that @request_nickname_async uses a #GSimpleAsyncResult * on which it will store the resulting string using * g_simple_async_result_set_op_res_gpointer() before completion. * + * The default implementation of @set_nickname_async raises + * %TP_ERROR_NOT_IMPLEMENTED. Connection managers for protocols where + * the user can change their own nickname should override this method. + * + * The default implementation of @set_local_alias_async raises + * %TP_ERROR_NOT_IMPLEMENTED. Connection managers for protocols where + * aliases can be stored should override this method. + * * The @set_nickname_finish and @set_local_alias functions have a default * implementation, which assumes that the corresponding @async function * uses a #GSimpleAsyncResult. @@ -223,6 +241,61 @@ G_DEFINE_INTERFACE (TpNames, tp_names_interface, TP_TYPE_BASE_CONNECTION) +typedef struct +{ + /* Immutable properties once CONNECTED */ + TpContactMetadataStorageType alias_storage; + + /* TpHandle -> owned string */ + GHashTable *nicknames; + GHashTable *local_aliases; +} TpNamesMixinPrivate; + +#define TP_NAMES_MIXIN_GET_PRIVATE(o) \ + g_object_get_qdata (G_OBJECT (o), tp_names_mixin_get_quark ()) + +static GQuark +tp_names_mixin_get_quark (void) +{ + static GQuark quark = 0; + + if (G_UNLIKELY (quark == 0)) + quark = g_quark_from_static_string ("TpNamesMixin"); + + return quark; +} + +static void tp_names_mixin_private_free (gpointer); + +static void +default_request_nickname_async (TpBaseConnection *base, + TpHandle contact, + GAsyncReadyCallback callback, + gpointer user_data) +{ + TpNamesMixinPrivate *priv = TP_NAMES_MIXIN_GET_PRIVATE (base); + gchar *nickname; + GSimpleAsyncResult *simple; + + /* ignore if called for its side-effects: it has none */ + if (callback == NULL) + return; + + nickname = g_strdup (g_hash_table_lookup (priv->nicknames, + GUINT_TO_POINTER (contact))); + + /* NULL means error here, so avoid it */ + if (nickname == NULL) + nickname = g_strdup (""); + + simple = g_simple_async_result_new (G_OBJECT (base), + callback, user_data, default_request_nickname_async); + + g_simple_async_result_set_op_res_gpointer (simple, nickname, g_free); + g_simple_async_result_complete_in_idle (simple); + g_object_unref (simple); +} + static gchar * default_request_nickname_finish (TpBaseConnection *base, GAsyncResult *result, @@ -231,6 +304,20 @@ default_request_nickname_finish (TpBaseConnection *base, _tp_implement_finish_return_copy_pointer (base, NULL, g_strdup); } +static void +default_set_nickname_async (TpBaseConnection *base, + const gchar *nickname, + GAsyncReadyCallback callback, + gpointer user_data) +{ + if (callback == NULL) + return; + + g_simple_async_report_error_in_idle (G_OBJECT (base), + callback, user_data, TP_ERROR, TP_ERROR_NOT_IMPLEMENTED, + "Setting your nickname is not implemented"); +} + static gboolean default_set_nickname_finish (TpBaseConnection *base, GAsyncResult *result, @@ -239,6 +326,21 @@ default_set_nickname_finish (TpBaseConnection *base, _tp_implement_finish_void (base, NULL); } +static void +default_set_local_alias_async (TpBaseConnection *base, + TpHandle contact, + const gchar *alias, + GAsyncReadyCallback callback, + gpointer user_data) +{ + if (callback == NULL) + return; + + g_simple_async_report_error_in_idle (G_OBJECT (base), + callback, user_data, TP_ERROR, TP_ERROR_NOT_IMPLEMENTED, + "Setting local aliases is not implemented"); +} + static gboolean default_set_local_alias_finish (TpBaseConnection *base, GAsyncResult *result, @@ -250,37 +352,14 @@ default_set_local_alias_finish (TpBaseConnection *base, static void tp_names_interface_default_init (TpNamesInterface *iface) { + iface->request_nickname_async = default_request_nickname_async; iface->request_nickname_finish = default_request_nickname_finish; + iface->set_nickname_async = default_set_nickname_async; iface->set_nickname_finish = default_set_nickname_finish; + iface->set_local_alias_async = default_set_local_alias_async; iface->set_local_alias_finish = default_set_local_alias_finish; } -typedef struct -{ - /* Immutable properties once CONNECTED */ - TpContactMetadataStorageType alias_storage; - - /* TpHandle -> owned string */ - GHashTable *nicknames; - GHashTable *local_aliases; -} TpNamesMixinPrivate; - -#define TP_NAMES_MIXIN_GET_PRIVATE(o) \ - g_object_get_qdata (G_OBJECT (o), tp_names_mixin_get_quark ()) - -static GQuark -tp_names_mixin_get_quark (void) -{ - static GQuark quark = 0; - - if (G_UNLIKELY (quark == 0)) - quark = g_quark_from_static_string ("TpNamesMixin"); - - return quark; -} - -static void tp_names_mixin_private_free (gpointer); - /** * tp_names_mixin_init: * @object: a #TpBaseConnection object that uses this mixin and implements @@ -296,12 +375,20 @@ void tp_names_mixin_init (GObject *object) { TpNamesMixinPrivate *priv; + TpNamesInterface *iface = TP_NAMES_INTERFACE_GET_IFACE (object); g_return_if_fail (TP_IS_BASE_CONNECTION (object)); g_return_if_fail (TP_IS_NAMES_INTERFACE (object)); g_return_if_fail (TP_IS_SVC_CONNECTION_INTERFACE_ALIASING (object) || TP_IS_SVC_CONNECTION_INTERFACE_NAMES (object)); + g_return_if_fail (iface->request_nickname_async != NULL); + g_return_if_fail (iface->request_nickname_finish != NULL); + g_return_if_fail (iface->set_nickname_async != NULL); + g_return_if_fail (iface->set_nickname_finish != NULL); + g_return_if_fail (iface->set_local_alias_async != NULL); + g_return_if_fail (iface->set_local_alias_finish != NULL); + priv = g_slice_new0 (TpNamesMixinPrivate); priv->nicknames = g_hash_table_new_full (NULL, NULL, @@ -393,9 +480,7 @@ tp_names_mixin_set_dbus_property (GObject *object, tp_base_connection_get_self_handle (base), nickname); - if (iface->set_nickname_async != NULL) - iface->set_nickname_async (base, nickname, NULL, NULL); - + iface->set_nickname_async (base, nickname, NULL, NULL); return TRUE; } @@ -481,11 +566,8 @@ implicit_request_nickname (TpBaseConnection *base, { TpNamesInterface *iface = TP_NAMES_INTERFACE_GET_IFACE (base); - if (iface->request_nickname_async != NULL) - { - iface->request_nickname_async (base, contact, - implicit_request_nickname_cb, GUINT_TO_POINTER (contact)); - } + iface->request_nickname_async (base, contact, + implicit_request_nickname_cb, GUINT_TO_POINTER (contact)); } static void @@ -536,12 +618,6 @@ tp_names_mixin_request_nickname (TpSvcConnectionInterfaceNames *dbus_iface, return; } - if (iface->request_nickname_async == NULL) - { - tp_dbus_g_method_return_not_implemented (context); - return; - } - iface->request_nickname_async (base, contact, request_nickname_cb, request_nickname_data_new (contact, context)); @@ -592,16 +668,8 @@ tp_names_mixin_set_local_alias (TpSvcConnectionInterfaceNames *dbus_iface, * the session */ tp_names_mixin_one_local_alias_changed (base, contact, alias); - if (iface->set_local_alias_async != NULL) - { - iface->set_local_alias_async (base, contact, alias, - set_local_alias_cb, context); - } - else - { - /* Let's silently return, we cached the value anyway */ - tp_svc_connection_interface_names_return_from_set_local_alias (context); - } + iface->set_local_alias_async (base, contact, alias, + set_local_alias_cb, context); } /** @@ -765,8 +833,7 @@ tp_names_mixin_aliasing_set_aliases ( tp_names_mixin_one_nickname_changed (base, self_handle, alias); - if (iface->set_nickname_async != NULL) - iface->set_nickname_async (base, alias, NULL, NULL); + iface->set_nickname_async (base, alias, NULL, NULL); } else { @@ -774,8 +841,7 @@ tp_names_mixin_aliasing_set_aliases ( * least the session */ tp_names_mixin_one_local_alias_changed (base, contact, alias); - if (iface->set_local_alias_async != NULL) - iface->set_local_alias_async (base, contact, alias, NULL, NULL); + iface->set_local_alias_async (base, contact, alias, NULL, NULL); } } @@ -927,12 +993,6 @@ tp_names_mixin_aliasing_request_aliases ( return; } - if (iface->request_nickname_async == NULL) - { - tp_dbus_g_method_return_not_implemented (context); - return; - } - request = request_aliases_data_new (contacts, context); for (i = 0; i < contacts->len; i++) { @@ -1321,7 +1381,8 @@ tp_names_mixin_set_storage_type (TpBaseConnection *base, g_return_if_fail (tp_base_connection_get_status (base) != TP_CONNECTION_STATUS_CONNECTED); - g_return_if_fail (iface->set_local_alias_async != NULL || + g_return_if_fail ( + iface->set_local_alias_async != default_set_local_alias_async || alias_storage == TP_CONTACT_METADATA_STORAGE_TYPE_NONE); priv->alias_storage = alias_storage; |