Update German translation
[empathy-mirror.git] / libempathy / empathy-connection-aggregator.c
blob763715f9e30c618beff4a56624de645c6762c0e0
1 /*
2 * empathy-connection-aggregator.c - Source for EmpathyConnectionAggregator
3 * Copyright (C) 2010 Collabora Ltd.
4 * @author Cosimo Cecchi <cosimo.cecchi@collabora.co.uk>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 #include "config.h"
22 #include "empathy-connection-aggregator.h"
24 #define DEBUG_FLAG EMPATHY_DEBUG_OTHER
25 #include "empathy-debug.h"
27 G_DEFINE_TYPE (EmpathyConnectionAggregator, empathy_connection_aggregator,
28 G_TYPE_OBJECT);
30 enum {
31 EVENT_CONTACT_LIST_CHANGED,
32 LAST_SIGNAL
35 static guint signals[LAST_SIGNAL];
37 struct _EmpathyConnectionAggregatorPriv {
38 TpAccountManager *mgr;
40 /* List of owned TpConnection */
41 GList *conns;
44 static void
45 empathy_connection_aggregator_dispose (GObject *object)
47 EmpathyConnectionAggregator *self = (EmpathyConnectionAggregator *) object;
49 g_clear_object (&self->priv->mgr);
51 g_list_free_full (self->priv->conns, g_object_unref);
52 self->priv->conns = NULL;
54 G_OBJECT_CLASS (empathy_connection_aggregator_parent_class)->dispose (object);
57 static void
58 empathy_connection_aggregator_class_init (
59 EmpathyConnectionAggregatorClass *klass)
61 GObjectClass *oclass = G_OBJECT_CLASS (klass);
63 oclass->dispose = empathy_connection_aggregator_dispose;
65 signals[EVENT_CONTACT_LIST_CHANGED] =
66 g_signal_new ("contact-list-changed",
67 G_TYPE_FROM_CLASS (klass),
68 G_SIGNAL_RUN_LAST,
70 NULL, NULL,
71 g_cclosure_marshal_generic,
72 G_TYPE_NONE,
73 2, G_TYPE_PTR_ARRAY, G_TYPE_PTR_ARRAY);
75 g_type_class_add_private (klass, sizeof (EmpathyConnectionAggregatorPriv));
78 static void
79 contact_list_changed_cb (TpConnection *conn,
80 GPtrArray *added,
81 GPtrArray *removed,
82 EmpathyConnectionAggregator *self)
84 g_signal_emit (self, signals[EVENT_CONTACT_LIST_CHANGED], 0, added, removed);
87 static void
88 conn_invalidated_cb (TpConnection *conn,
89 guint domain,
90 gint code,
91 gchar *message,
92 EmpathyConnectionAggregator *self)
94 self->priv->conns = g_list_remove (self->priv->conns, conn);
96 g_object_unref (conn);
99 static void
100 check_connection (EmpathyConnectionAggregator *self,
101 TpConnection *conn)
103 GPtrArray *contacts;
105 if (g_list_find (self->priv->conns, conn) != NULL)
106 return;
108 self->priv->conns = g_list_prepend (self->priv->conns,
109 g_object_ref (conn));
111 tp_g_signal_connect_object (conn, "contact-list-changed",
112 G_CALLBACK (contact_list_changed_cb), self, 0);
114 contacts = tp_connection_dup_contact_list (conn);
115 if (contacts != NULL)
117 GPtrArray *empty;
119 empty = g_ptr_array_new ();
121 contact_list_changed_cb (conn, contacts, empty, self);
122 g_ptr_array_unref (empty);
124 g_ptr_array_unref (contacts);
126 tp_g_signal_connect_object (conn, "invalidated",
127 G_CALLBACK (conn_invalidated_cb), self, 0);
130 static void
131 check_account (EmpathyConnectionAggregator *self,
132 TpAccount *account)
134 TpConnection *conn;
136 conn = tp_account_get_connection (account);
137 if (conn != NULL)
138 check_connection (self, conn);
141 static void
142 account_conn_changed_cb (TpAccount *account,
143 GParamSpec *spec,
144 EmpathyConnectionAggregator *self)
146 check_account (self, account);
149 static void
150 add_account (EmpathyConnectionAggregator *self,
151 TpAccount *account)
153 check_account (self, account);
155 tp_g_signal_connect_object (account, "notify::connection",
156 G_CALLBACK (account_conn_changed_cb), self, 0);
159 static void
160 account_validity_changed_cb (TpAccountManager *manager,
161 TpAccount *account,
162 gboolean valid,
163 EmpathyConnectionAggregator *self)
165 if (valid)
166 add_account (self, account);
169 static void
170 am_prepare_cb (GObject *source,
171 GAsyncResult *result,
172 gpointer user_data)
174 EmpathyConnectionAggregator *self = EMPATHY_CONNECTION_AGGREGATOR (user_data);
175 GError *error = NULL;
176 GList *accounts, *l;
178 if (!tp_proxy_prepare_finish (source, result, &error))
180 DEBUG ("Failed to prepare account manager: %s", error->message);
181 g_error_free (error);
182 goto out;
185 accounts = tp_account_manager_dup_valid_accounts (self->priv->mgr);
186 for (l = accounts; l != NULL; l = g_list_next (l))
188 TpAccount *account = l->data;
190 add_account (self, account);
193 tp_g_signal_connect_object (self->priv->mgr, "account-validity-changed",
194 G_CALLBACK (account_validity_changed_cb), self, 0);
196 g_list_free_full (accounts, g_object_unref);
198 out:
199 g_object_unref (self);
202 static void
203 empathy_connection_aggregator_init (EmpathyConnectionAggregator *self)
205 self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
206 EMPATHY_TYPE_CONNECTION_AGGREGATOR, EmpathyConnectionAggregatorPriv);
208 self->priv->mgr = tp_account_manager_dup ();
210 tp_proxy_prepare_async (self->priv->mgr, NULL, am_prepare_cb,
211 g_object_ref (self));
214 EmpathyConnectionAggregator *
215 empathy_connection_aggregator_dup_singleton (void)
217 static EmpathyConnectionAggregator *aggregator = NULL;
219 if (G_LIKELY (aggregator != NULL))
220 return g_object_ref (aggregator);
222 aggregator = g_object_new (EMPATHY_TYPE_CONNECTION_AGGREGATOR, NULL);
224 g_object_add_weak_pointer (G_OBJECT (aggregator), (gpointer *) &aggregator);
225 return aggregator;
228 /* (transfer container) */
229 GList *
230 empathy_connection_aggregator_get_all_groups (EmpathyConnectionAggregator *self)
232 GList *keys, *l;
233 GHashTable *set;
235 set = g_hash_table_new (g_str_hash, g_str_equal);
237 for (l = self->priv->conns; l != NULL; l = g_list_next (l))
239 TpConnection *conn = l->data;
240 const gchar * const *groups;
241 guint i;
243 groups = tp_connection_get_contact_groups (conn);
244 if (groups == NULL)
245 continue;
247 for (i = 0; groups[i] != NULL; i++)
248 g_hash_table_insert (set, (gchar *) groups[i], GUINT_TO_POINTER (TRUE));
251 keys = g_hash_table_get_keys (set);
252 g_hash_table_unref (set);
254 return keys;
257 GPtrArray *
258 empathy_connection_aggregator_dup_all_contacts (
259 EmpathyConnectionAggregator *self)
261 GPtrArray *result;
262 GList *l;
264 result = g_ptr_array_new_with_free_func (g_object_unref);
266 for (l = self->priv->conns; l != NULL; l = g_list_next (l))
268 TpConnection *conn = l->data;
269 GPtrArray *contacts;
271 contacts = tp_connection_dup_contact_list (conn);
272 if (contacts == NULL)
273 continue;
275 tp_g_ptr_array_extend (result, contacts);
277 /* tp_g_ptr_array_extend() doesn't give us an extra ref */
278 g_ptr_array_foreach (contacts, (GFunc) g_object_ref, NULL);
280 g_ptr_array_unref (contacts);
283 return result;
286 static void
287 rename_group_cb (GObject *source,
288 GAsyncResult *result,
289 gpointer user_data)
291 GError *error = NULL;
293 if (!tp_connection_rename_group_finish (TP_CONNECTION (source), result,
294 &error))
296 DEBUG ("Failed to rename group on %s: %s",
297 tp_proxy_get_object_path (source), error->message);
298 g_error_free (error);
302 void
303 empathy_connection_aggregator_rename_group (EmpathyConnectionAggregator *self,
304 const gchar *old_name,
305 const gchar *new_name)
307 GList *l;
309 for (l = self->priv->conns; l != NULL; l = g_list_next (l))
311 TpConnection *conn = l->data;
312 const gchar * const *groups;
314 groups = tp_connection_get_contact_groups (conn);
316 if (!tp_strv_contains (groups, old_name))
317 continue;
319 DEBUG ("Rename group '%s' to '%s' on %s", old_name, new_name,
320 tp_proxy_get_object_path (conn));
322 tp_connection_rename_group_async (conn, old_name, new_name,
323 rename_group_cb, NULL);