* 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>
*/
#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 "empathy-contact-manager.h"
-#include "empathy-account-manager.h"
-#include "empathy-contact-monitor.h"
#include "empathy-contact-list.h"
#include "empathy-utils.h"
#define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyContactManager)
typedef struct {
+ /* Owned (TpConnection *) => Owned (TpContactList *)
+ The contact list associated with each connected connection */
GHashTable *lists;
- EmpathyAccountManager *account_manager;
- EmpathyContactMonitor *contact_monitor;
+ TpAccountManager *account_manager;
} EmpathyContactManagerPriv;
static void contact_manager_iface_init (EmpathyContactListIface *iface);
contact, group, is_member);
}
-static void
-contact_manager_disconnect_foreach (gpointer key,
- gpointer value,
- gpointer user_data)
-{
- EmpathyTpContactList *list = value;
- EmpathyContactManager *manager = user_data;
-
- /* Disconnect signals from the list */
- g_signal_handlers_disconnect_by_func (list,
- contact_manager_members_changed_cb,
- manager);
- g_signal_handlers_disconnect_by_func (list,
- contact_manager_pendings_changed_cb,
- manager);
- g_signal_handlers_disconnect_by_func (list,
- contact_manager_groups_changed_cb,
- manager);
-}
-
static void
contact_manager_invalidated_cb (TpProxy *connection,
guint domain,
list = g_hash_table_lookup (priv->lists, connection);
if (list) {
empathy_tp_contact_list_remove_all (list);
- g_hash_table_remove (priv->lists, connection);
+ g_hash_table_remove (priv->lists, connection);
}
}
static void
-contact_manager_new_connection_cb (EmpathyAccountManager *account_manager,
- TpConnection *connection,
+contact_manager_disconnect_foreach (gpointer key,
+ gpointer value,
+ gpointer user_data)
+{
+ TpConnection *connection = key;
+ EmpathyTpContactList *list = value;
+ EmpathyContactManager *manager = user_data;
+
+ /* Disconnect signals from the list */
+ g_signal_handlers_disconnect_by_func (list,
+ contact_manager_members_changed_cb,
+ manager);
+ g_signal_handlers_disconnect_by_func (list,
+ contact_manager_pendings_changed_cb,
+ manager);
+ g_signal_handlers_disconnect_by_func (list,
+ contact_manager_groups_changed_cb,
+ manager);
+ g_signal_handlers_disconnect_by_func (connection,
+ contact_manager_invalidated_cb,
+ manager);
+}
+
+static void
+contact_manager_status_changed_cb (TpAccount *account,
+ guint old_status,
+ guint new_status,
+ guint reason,
+ gchar *dbus_error_name,
+ GHashTable *details,
EmpathyContactManager *self)
{
EmpathyContactManagerPriv *priv = GET_PRIV (self);
EmpathyTpContactList *list;
+ TpConnection *connection;
- if (g_hash_table_lookup (priv->lists, connection)) {
+ if (new_status == TP_CONNECTION_STATUS_DISCONNECTED)
+ /* No point to start tracking a connection which is about to die */
+ return;
+
+ connection = tp_account_get_connection (account);
+
+ if (connection == NULL || g_hash_table_lookup (priv->lists, connection)) {
return;
}
self);
}
+static void
+contact_manager_validity_changed_cb (TpAccountManager *account_manager,
+ TpAccount *account,
+ gboolean valid,
+ EmpathyContactManager *manager)
+{
+ if (valid) {
+ tp_g_signal_connect_object (account, "status-changed",
+ G_CALLBACK (contact_manager_status_changed_cb),
+ manager, 0);
+ }
+}
+
static void
contact_manager_finalize (GObject *object)
{
object);
g_hash_table_destroy (priv->lists);
- g_signal_handlers_disconnect_by_func (priv->account_manager,
- contact_manager_new_connection_cb,
- object);
g_object_unref (priv->account_manager);
-
- if (priv->contact_monitor) {
- g_object_unref (priv->contact_monitor);
- }
}
static GObject *
return retval;
}
+/**
+ * empathy_contact_manager_initialized:
+ *
+ * Reports whether or not the singleton has already been created.
+ *
+ * There can be instances where you want to access the #EmpathyContactManager
+ * only if it has been set up for this process.
+ *
+ * Returns: %TRUE if the #EmpathyContactManager singleton has previously
+ * been initialized.
+ */
+gboolean
+empathy_contact_manager_initialized (void)
+{
+ return (manager_singleton != NULL);
+}
+
static void
empathy_contact_manager_class_init (EmpathyContactManagerClass *klass)
{
g_type_class_add_private (object_class, sizeof (EmpathyContactManagerPriv));
}
+static void
+account_manager_prepared_cb (GObject *source_object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GList *accounts, *l;
+ EmpathyContactManager *manager = user_data;
+ TpAccountManager *account_manager = TP_ACCOUNT_MANAGER (source_object);
+ GError *error = NULL;
+
+ if (!tp_proxy_prepare_finish (account_manager, result, &error)) {
+ DEBUG ("Failed to prepare account manager: %s", error->message);
+ g_error_free (error);
+ return;
+ }
+
+ accounts = tp_account_manager_get_valid_accounts (account_manager);
+
+ for (l = accounts; l != NULL; l = l->next) {
+ TpAccount *account = l->data;
+ TpConnection *conn = tp_account_get_connection (account);
+
+ if (conn != NULL) {
+ contact_manager_status_changed_cb (account, 0, 0, 0,
+ NULL, NULL, manager);
+ }
+
+ tp_g_signal_connect_object (account, "status-changed",
+ G_CALLBACK (contact_manager_status_changed_cb),
+ manager, 0);
+ }
+ g_list_free (accounts);
+
+ tp_g_signal_connect_object (account_manager, "account-validity-changed",
+ G_CALLBACK (contact_manager_validity_changed_cb),
+ manager, 0);
+}
+
static void
empathy_contact_manager_init (EmpathyContactManager *manager)
{
- GList *connections, *l;
EmpathyContactManagerPriv *priv = G_TYPE_INSTANCE_GET_PRIVATE (manager,
EMPATHY_TYPE_CONTACT_MANAGER, EmpathyContactManagerPriv);
empathy_proxy_equal,
(GDestroyNotify) g_object_unref,
(GDestroyNotify) g_object_unref);
- priv->account_manager = empathy_account_manager_dup_singleton ();
- priv->contact_monitor = NULL;
-
- g_signal_connect (priv->account_manager, "new-connection",
- G_CALLBACK (contact_manager_new_connection_cb),
- manager);
-
- /* Get ContactList for existing connections */
- connections = empathy_account_manager_dup_connections (priv->account_manager);
- for (l = connections; l; l = l->next) {
- contact_manager_new_connection_cb (priv->account_manager,
- l->data, manager);
- g_object_unref (l->data);
- }
- g_list_free (connections);
+
+ priv->account_manager = tp_account_manager_dup ();
+
+ tp_proxy_prepare_async (priv->account_manager, NULL,
+ account_manager_prepared_cb, manager);
}
EmpathyContactManager *
return contacts;
}
-static EmpathyContactMonitor *
-contact_manager_get_monitor (EmpathyContactList *manager)
-{
- EmpathyContactManagerPriv *priv = GET_PRIV (manager);
-
- if (priv->contact_monitor == NULL) {
- priv->contact_monitor = empathy_contact_monitor_new_for_iface (manager);
- }
-
- return priv->contact_monitor;
-}
-
static void
contact_manager_get_pendings_foreach (TpConnection *connection,
EmpathyTpContactList *list,
const gchar *group)
{
EmpathyContactManagerPriv *priv = GET_PRIV (manager);
-
+
g_return_if_fail (EMPATHY_IS_CONTACT_MANAGER (manager));
g_hash_table_foreach (priv->lists,
iface->add = contact_manager_add;
iface->remove = contact_manager_remove;
iface->get_members = contact_manager_get_members;
- iface->get_monitor = contact_manager_get_monitor;
iface->get_pendings = contact_manager_get_pendings;
iface->get_all_groups = contact_manager_get_all_groups;
iface->get_groups = contact_manager_get_groups;
iface->remove_group = contact_manager_remove_group;
}
-gboolean
-empathy_contact_manager_can_add (EmpathyContactManager *manager,
- TpConnection *connection)
+EmpathyContactListFlags
+empathy_contact_manager_get_flags_for_connection (
+ EmpathyContactManager *manager,
+ TpConnection *connection)
{
EmpathyContactManagerPriv *priv = GET_PRIV (manager);
- EmpathyTpContactList *list;
-
+ EmpathyContactList *list;
+ EmpathyContactListFlags flags;
+
g_return_val_if_fail (EMPATHY_IS_CONTACT_MANAGER (manager), FALSE);
+ g_return_val_if_fail (connection != NULL, FALSE);
list = g_hash_table_lookup (priv->lists, connection);
- if (list == NULL)
+ if (list == NULL) {
return FALSE;
+ }
+ flags = empathy_contact_list_get_flags (list);
- return empathy_tp_contact_list_can_add (list);
+ return flags;
}