diff options
author | Travis Reitter <treitter@gmail.com> | 2010-05-29 07:13:51 +0800 |
---|---|---|
committer | Travis Reitter <treitter@gmail.com> | 2010-07-21 07:12:35 +0800 |
commit | d6aa2f99e3e626f81b455c0fa1ff4817a4e4f2f6 (patch) | |
tree | 3db6a726bcc50a3423f601b7975d7abb166cb9a1 /libempathy | |
parent | 57a1f36eaec69df0195e90d8a4b050574a19d6b3 (diff) | |
download | gsoc2013-empathy-d6aa2f99e3e626f81b455c0fa1ff4817a4e4f2f6.tar gsoc2013-empathy-d6aa2f99e3e626f81b455c0fa1ff4817a4e4f2f6.tar.gz gsoc2013-empathy-d6aa2f99e3e626f81b455c0fa1ff4817a4e4f2f6.tar.bz2 gsoc2013-empathy-d6aa2f99e3e626f81b455c0fa1ff4817a4e4f2f6.tar.lz gsoc2013-empathy-d6aa2f99e3e626f81b455c0fa1ff4817a4e4f2f6.tar.xz gsoc2013-empathy-d6aa2f99e3e626f81b455c0fa1ff4817a4e4f2f6.tar.zst gsoc2013-empathy-d6aa2f99e3e626f81b455c0fa1ff4817a4e4f2f6.zip |
Base the contact list around libfolks metacontacts. Not yet to feature-parity
with mainline Empathy.
Diffstat (limited to 'libempathy')
-rw-r--r-- | libempathy/Makefile.am | 2 | ||||
-rw-r--r-- | libempathy/empathy-individual-manager.c | 290 | ||||
-rw-r--r-- | libempathy/empathy-individual-manager.h | 82 | ||||
-rw-r--r-- | libempathy/empathy-utils.c | 35 | ||||
-rw-r--r-- | libempathy/empathy-utils.h | 4 |
5 files changed, 413 insertions, 0 deletions
diff --git a/libempathy/Makefile.am b/libempathy/Makefile.am index 746803e05..ca0df9206 100644 --- a/libempathy/Makefile.am +++ b/libempathy/Makefile.am @@ -44,6 +44,7 @@ libempathy_headers = \ empathy-gsettings.h \ empathy-handler.h \ empathy-idle.h \ + empathy-individual-manager.h \ empathy-irc-network-manager.h \ empathy-irc-network.h \ empathy-irc-server.h \ @@ -80,6 +81,7 @@ libempathy_la_SOURCES = \ empathy-ft-handler.c \ empathy-handler.c \ empathy-idle.c \ + empathy-individual-manager.c \ empathy-irc-network-manager.c \ empathy-irc-network.c \ empathy-irc-server.c \ diff --git a/libempathy/empathy-individual-manager.c b/libempathy/empathy-individual-manager.c new file mode 100644 index 000000000..4b27e74a0 --- /dev/null +++ b/libempathy/empathy-individual-manager.c @@ -0,0 +1,290 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Copyright (C) 2007-2010 Collabora Ltd. + * + * 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 the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Xavier Claessens <xclaesse@gmail.com> + * Travis Reitter <travis.reitter@collabora.co.uk> + */ + +#include <config.h> + +#include <string.h> + +#include <telepathy-glib/account-manager.h> +#include <telepathy-glib/enums.h> +#include <telepathy-glib/proxy-subclass.h> +#include <telepathy-glib/util.h> + +#include <folks/folks.h> + +#include <extensions/extensions.h> + +#include "empathy-individual-manager.h" +#include "empathy-contact-manager.h" +#include "empathy-contact-list.h" +#include "empathy-marshal.h" +#include "empathy-utils.h" + +#define DEBUG_FLAG EMPATHY_DEBUG_CONTACT +#include "empathy-debug.h" + +#define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyIndividualManager) +typedef struct +{ + FolksIndividualAggregator *aggregator; + EmpathyContactManager *contact_manager; + TpProxy *logger; + /* account object path (gchar *) => GHashTable containing favorite contacts + * (contact ID (gchar *) => TRUE) */ + GHashTable *favourites; + TpProxySignalConnection *favourite_contacts_changed_signal; +} EmpathyIndividualManagerPriv; + +G_DEFINE_TYPE (EmpathyIndividualManager, empathy_individual_manager, + G_TYPE_OBJECT); + +static EmpathyIndividualManager *manager_singleton = NULL; + +static void +individual_group_changed_cb (FolksIndividual *individual, + gchar *group, + gboolean is_member, + EmpathyIndividualManager *self) +{ + g_signal_emit_by_name (self, "groups-changed", individual, group, + is_member); +} + +static void +aggregator_individuals_added_cb (FolksIndividualAggregator *aggregator, + GList *individuals, + EmpathyIndividualManager *self) +{ + GList *l; + + for (l = individuals; l; l = l->next) + { + g_signal_connect (l->data, "group-changed", + G_CALLBACK (individual_group_changed_cb), self); + } + + /* TODO: don't hard-code the reason or message */ + g_signal_emit_by_name (self, "members-changed", + "individual(s) added", individuals, NULL, + TP_CHANNEL_GROUP_CHANGE_REASON_NONE, TRUE); +} + +static void +aggregator_individuals_removed_cb (FolksIndividualAggregator *aggregator, + GList *individuals, + EmpathyIndividualManager *self) +{ + GList *l; + + for (l = individuals; l; l = l->next) + { + g_signal_handlers_disconnect_by_func (l->data, + individual_group_changed_cb, self); + } + + /* TODO: don't hard-code the reason or message */ + g_signal_emit_by_name (self, "members-changed", + "individual(s) removed", NULL, individuals, + TP_CHANNEL_GROUP_CHANGE_REASON_NONE, TRUE); +} + +static void +individual_manager_finalize (GObject *object) +{ + EmpathyIndividualManagerPriv *priv = GET_PRIV (object); + + tp_proxy_signal_connection_disconnect ( + priv->favourite_contacts_changed_signal); + + if (priv->logger != NULL) + g_object_unref (priv->logger); + + if (priv->contact_manager != NULL) + g_object_unref (priv->contact_manager); + + if (priv->aggregator != NULL) + g_object_unref (priv->aggregator); + + g_hash_table_destroy (priv->favourites); +} + +static GObject * +individual_manager_constructor (GType type, + guint n_props, + GObjectConstructParam *props) +{ + GObject *retval; + + if (manager_singleton) + { + retval = g_object_ref (manager_singleton); + } + else + { + retval = + G_OBJECT_CLASS (empathy_individual_manager_parent_class)-> + constructor (type, n_props, props); + + manager_singleton = EMPATHY_INDIVIDUAL_MANAGER (retval); + g_object_add_weak_pointer (retval, (gpointer) & manager_singleton); + } + + return retval; +} + +/** + * empathy_individual_manager_initialized: + * + * Reports whether or not the singleton has already been created. + * + * There can be instances where you want to access the #EmpathyIndividualManager + * only if it has been set up for this process. + * + * Returns: %TRUE if the #EmpathyIndividualManager singleton has previously + * been initialized. + */ +gboolean +empathy_individual_manager_initialized (void) +{ + return (manager_singleton != NULL); +} + +static void +empathy_individual_manager_class_init (EmpathyIndividualManagerClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->finalize = individual_manager_finalize; + object_class->constructor = individual_manager_constructor; + + g_signal_new ("groups-changed", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + _empathy_marshal_VOID__OBJECT_STRING_BOOLEAN, + G_TYPE_NONE, 3, FOLKS_TYPE_INDIVIDUAL, G_TYPE_STRING, G_TYPE_BOOLEAN); + + g_signal_new ("members-changed", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + _empathy_marshal_VOID__STRING_OBJECT_OBJECT_UINT, + G_TYPE_NONE, + 4, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_UINT); + + g_type_class_add_private (object_class, + sizeof (EmpathyIndividualManagerPriv)); +} + +static void +empathy_individual_manager_init (EmpathyIndividualManager *self) +{ + EmpathyIndividualManagerPriv *priv = G_TYPE_INSTANCE_GET_PRIVATE (self, + EMPATHY_TYPE_INDIVIDUAL_MANAGER, EmpathyIndividualManagerPriv); + TpDBusDaemon *bus; + GError *error = NULL; + + self->priv = priv; + priv->contact_manager = empathy_contact_manager_dup_singleton (); + + priv->favourites = g_hash_table_new_full (g_str_hash, g_str_equal, + (GDestroyNotify) g_free, (GDestroyNotify) g_hash_table_unref); + + priv->aggregator = folks_individual_aggregator_new (); + if (error == NULL) + { + g_signal_connect (priv->aggregator, "individuals-added", + G_CALLBACK (aggregator_individuals_added_cb), self); + g_signal_connect (priv->aggregator, "individuals-removed", + G_CALLBACK (aggregator_individuals_removed_cb), self); + } + else + { + DEBUG ("Failed to get individual aggregator: %s", error->message); + g_clear_error (&error); + } + + bus = tp_dbus_daemon_dup (&error); + + if (error == NULL) + { + priv->logger = g_object_new (TP_TYPE_PROXY, + "bus-name", "org.freedesktop.Telepathy.Logger", + "object-path", + "/org/freedesktop/Telepathy/Logger", "dbus-daemon", bus, NULL); + g_object_unref (bus); + + tp_proxy_add_interface_by_id (priv->logger, EMP_IFACE_QUARK_LOGGER); + } + else + { + DEBUG ("Failed to get telepathy-logger proxy: %s", error->message); + g_clear_error (&error); + } +} + +EmpathyIndividualManager * +empathy_individual_manager_dup_singleton (void) +{ + return g_object_new (EMPATHY_TYPE_INDIVIDUAL_MANAGER, NULL); +} + +/* TODO: support adding and removing Individuals */ + +GList * +empathy_individual_manager_get_members (EmpathyIndividualManager *self) +{ + EmpathyIndividualManagerPriv *priv = GET_PRIV (self); + GHashTable *individuals; + + g_return_val_if_fail (EMPATHY_IS_INDIVIDUAL_MANAGER (self), NULL); + + individuals = folks_individual_aggregator_get_individuals (priv->aggregator); + return individuals ? g_hash_table_get_values (individuals) : NULL; +} + +FolksIndividual * +empathy_individual_manager_lookup_member (EmpathyIndividualManager *self, + const gchar *id) +{ + EmpathyIndividualManagerPriv *priv = GET_PRIV (self); + GHashTable *individuals; + + g_return_val_if_fail (EMPATHY_IS_INDIVIDUAL_MANAGER (self), NULL); + + individuals = folks_individual_aggregator_get_individuals (priv->aggregator); + if (individuals != NULL) + return g_hash_table_lookup (individuals, id); + + return NULL; +} + +void +empathy_individual_manager_remove (EmpathyIndividualManager *self, + FolksIndividual *individual, + const gchar *message) +{ + /* TODO: implement */ + DEBUG (G_STRLOC ": individual removal not implemented"); +} diff --git a/libempathy/empathy-individual-manager.h b/libempathy/empathy-individual-manager.h new file mode 100644 index 000000000..1823dec5a --- /dev/null +++ b/libempathy/empathy-individual-manager.h @@ -0,0 +1,82 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Copyright (C) 2007-2010 Collabora Ltd. + * + * 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 the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Xavier Claessens <xclaesse@gmail.com> + * Travis Reitter <travis.reitter@collabora.co.uk> + */ + +#ifndef __EMPATHY_INDIVIDUAL_MANAGER_H__ +#define __EMPATHY_INDIVIDUAL_MANAGER_H__ + +#include <glib.h> +#include <folks/folks.h> + +#include "empathy-contact.h" + +G_BEGIN_DECLS +#define EMPATHY_TYPE_INDIVIDUAL_MANAGER (empathy_individual_manager_get_type ()) +#define EMPATHY_INDIVIDUAL_MANAGER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EMPATHY_TYPE_INDIVIDUAL_MANAGER, EmpathyIndividualManager)) +#define EMPATHY_INDIVIDUAL_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), EMPATHY_TYPE_INDIVIDUAL_MANAGER, EmpathyIndividualManagerClass)) +#define EMPATHY_IS_INDIVIDUAL_MANAGER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EMPATHY_TYPE_INDIVIDUAL_MANAGER)) +#define EMPATHY_IS_INDIVIDUAL_MANAGER_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EMPATHY_TYPE_INDIVIDUAL_MANAGER)) +#define EMPATHY_INDIVIDUAL_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EMPATHY_TYPE_INDIVIDUAL_MANAGER, EmpathyIndividualManagerClass)) + typedef enum +{ + EMPATHY_INDIVIDUAL_MANAGER_CAN_ADD = 1 << 0, + EMPATHY_INDIVIDUAL_MANAGER_CAN_REMOVE = 1 << 1, + EMPATHY_INDIVIDUAL_MANAGER_CAN_ALIAS = 1 << 2, + EMPATHY_INDIVIDUAL_MANAGER_CAN_GROUP = 1 << 3, +} EmpathyIndividualManagerFlags; + +typedef struct _EmpathyIndividualManager EmpathyIndividualManager; +typedef struct _EmpathyIndividualManagerClass EmpathyIndividualManagerClass; + +struct _EmpathyIndividualManager +{ + GObject parent; + gpointer priv; +}; + +struct _EmpathyIndividualManagerClass +{ + GObjectClass parent_class; +}; + +GType empathy_individual_manager_get_type (void) G_GNUC_CONST; + +gboolean empathy_individual_manager_initialized (void); + +EmpathyIndividualManager *empathy_individual_manager_dup_singleton (void); + +GList *empathy_individual_manager_get_members ( + EmpathyIndividualManager *manager); + +FolksIndividual *empathy_individual_manager_lookup_member ( + EmpathyIndividualManager *manager, + const gchar *id); + +void empathy_individual_manager_remove (EmpathyIndividualManager *manager, + FolksIndividual *individual, + const gchar *message); + +gboolean empathy_individual_manager_is_favourite ( + EmpathyIndividualManager *manager, + FolksIndividual *individual); + +G_END_DECLS +#endif /* __EMPATHY_INDIVIDUAL_MANAGER_H__ */ diff --git a/libempathy/empathy-utils.c b/libempathy/empathy-utils.c index 1c2d95b09..56da323b9 100644 --- a/libempathy/empathy-utils.c +++ b/libempathy/empathy-utils.c @@ -32,6 +32,9 @@ #include <libxml/uri.h> +#include <folks/folks.h> +#include <folks/folks-telepathy.h> + #include <telepathy-glib/account-manager.h> #include <telepathy-glib/connection.h> #include <telepathy-glib/channel.h> @@ -44,6 +47,7 @@ #include "empathy-dispatch-operation.h" #include "empathy-idle.h" #include "empathy-tp-call.h" +#include "empathy-tp-contact-factory.h" #include <extensions/extensions.h> @@ -558,3 +562,34 @@ empathy_connect_new_account (TpAccount *account, break; } } + +TpConnectionPresenceType +empathy_folks_presence_type_to_tp (FolksPresenceType type) +{ + return (TpConnectionPresenceType) type; +} + +EmpathyContact * +empathy_contact_from_folks_individual (FolksIndividual *individual) +{ + GList *personas, *l; + EmpathyContact *contact = NULL; + + g_return_val_if_fail (FOLKS_IS_INDIVIDUAL (individual), NULL); + + personas = folks_individual_get_personas (individual); + for (l = personas; (l != NULL) && (contact == NULL); l = l->next) + { + TpfPersona *persona = l->data; + + if (TPF_IS_PERSONA (persona)) + { + TpContact *tp_contact; + + tp_contact = tpf_persona_get_contact (persona); + contact = empathy_contact_dup_from_tp_contact (tp_contact); + } + } + + return contact; +} diff --git a/libempathy/empathy-utils.h b/libempathy/empathy-utils.h index 272b66fd8..1ba7e53f8 100644 --- a/libempathy/empathy-utils.h +++ b/libempathy/empathy-utils.h @@ -31,6 +31,7 @@ #include <libxml/parser.h> #include <libxml/tree.h> +#include <folks/folks.h> #include <telepathy-glib/account-manager.h> #include "empathy-contact.h" @@ -89,6 +90,9 @@ gboolean empathy_account_manager_get_accounts_connected (gboolean *connecting); void empathy_connect_new_account (TpAccount *account, TpAccountManager *account_manager); +TpConnectionPresenceType empathy_folks_presence_type_to_tp (FolksPresenceType type); +EmpathyContact * empathy_contact_from_folks_individual (FolksIndividual *individual); + G_END_DECLS #endif /* __EMPATHY_UTILS_H__ */ |