2 * Copyright (C) 2008 Collabora Ltd.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 * Authors: Cosimo Cecchi <cosimo.cecchi@collabora.co.uk>
23 #include <glib-object.h>
25 #include "empathy-contact-monitor.h"
26 #include "empathy-contact-list.h"
28 #include "empathy-contact.h"
29 #include "empathy-utils.h"
30 #include "empathy-marshal.h"
32 #define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyContactMonitor)
35 EmpathyContactList
*iface
;
39 } EmpathyContactMonitorPriv
;
43 CONTACT_AVATAR_CHANGED
,
44 CONTACT_CAPABILITIES_CHANGED
,
46 CONTACT_PRESENCE_CHANGED
,
47 CONTACT_PRESENCE_MESSAGE_CHANGED
,
57 static guint signals
[LAST_SIGNAL
];
59 G_DEFINE_TYPE (EmpathyContactMonitor
, empathy_contact_monitor
, G_TYPE_OBJECT
);
62 contact_monitor_presence_changed_cb (EmpathyContact
*contact
,
63 TpConnectionPresenceType current_presence
,
64 TpConnectionPresenceType previous_presence
,
65 EmpathyContactMonitor
*self
)
67 g_signal_emit (self
, signals
[CONTACT_PRESENCE_CHANGED
], 0, contact
,
68 current_presence
, previous_presence
);
72 contact_monitor_presence_message_changed_cb (EmpathyContact
*contact
,
74 EmpathyContactMonitor
*self
)
78 /* use the status so that we always have a presence message */
79 status
= empathy_contact_get_status (contact
);
81 g_signal_emit (self
, signals
[CONTACT_PRESENCE_MESSAGE_CHANGED
], 0,
86 contact_monitor_name_changed_cb (EmpathyContact
*contact
,
88 EmpathyContactMonitor
*self
)
92 name
= empathy_contact_get_name (contact
);
94 g_signal_emit (self
, signals
[CONTACT_NAME_CHANGED
], 0, contact
, name
);
98 contact_monitor_avatar_changed_cb (EmpathyContact
*contact
,
100 EmpathyContactMonitor
*self
)
102 /* don't emit a pixbuf in the signal, as we don't depend on GTK+ here
105 g_signal_emit (self
, signals
[CONTACT_AVATAR_CHANGED
], 0, contact
);
109 contact_monitor_capabilities_changed_cb (EmpathyContact
*contact
,
111 EmpathyContactMonitor
*self
)
113 g_signal_emit (self
, signals
[CONTACT_CAPABILITIES_CHANGED
], 0, contact
);
117 contact_add (EmpathyContactMonitor
*monitor
,
118 EmpathyContact
*contact
)
120 EmpathyContactMonitorPriv
*priv
= GET_PRIV (monitor
);
122 g_signal_connect (contact
, "presence-changed",
123 G_CALLBACK (contact_monitor_presence_changed_cb
),
125 g_signal_connect (contact
, "notify::presence-message",
126 G_CALLBACK (contact_monitor_presence_message_changed_cb
),
128 g_signal_connect (contact
, "notify::name",
129 G_CALLBACK (contact_monitor_name_changed_cb
),
131 g_signal_connect (contact
, "notify::avatar",
132 G_CALLBACK (contact_monitor_avatar_changed_cb
),
134 g_signal_connect (contact
, "notify::capabilities",
135 G_CALLBACK (contact_monitor_capabilities_changed_cb
),
138 priv
->contacts
= g_list_prepend (priv
->contacts
, g_object_ref (contact
));
140 g_signal_emit (monitor
, signals
[CONTACT_ADDED
], 0, contact
);
144 contact_remove (EmpathyContactMonitor
*monitor
,
145 EmpathyContact
*contact
)
147 EmpathyContactMonitorPriv
*priv
= GET_PRIV (monitor
);
149 g_signal_handlers_disconnect_by_func (contact
,
150 G_CALLBACK (contact_monitor_presence_changed_cb
),
152 g_signal_handlers_disconnect_by_func (contact
,
153 G_CALLBACK (contact_monitor_presence_message_changed_cb
),
155 g_signal_handlers_disconnect_by_func (contact
,
156 G_CALLBACK (contact_monitor_name_changed_cb
),
158 g_signal_handlers_disconnect_by_func (contact
,
159 G_CALLBACK (contact_monitor_avatar_changed_cb
),
161 g_signal_handlers_disconnect_by_func (contact
,
162 G_CALLBACK (contact_monitor_capabilities_changed_cb
),
165 priv
->contacts
= g_list_remove (priv
->contacts
, contact
);
167 g_signal_emit (monitor
, signals
[CONTACT_REMOVED
], 0, contact
);
169 g_object_unref (contact
);
173 contact_remove_foreach (EmpathyContact
*contact
,
174 EmpathyContactMonitor
*monitor
)
176 contact_remove (monitor
, contact
);
180 cl_members_changed_cb (EmpathyContactList
*cl
,
181 EmpathyContact
*contact
,
182 EmpathyContact
*actor
,
186 EmpathyContactMonitor
*monitor
)
189 contact_add (monitor
, contact
);
191 contact_remove (monitor
, contact
);
195 do_set_property (GObject
*object
,
203 empathy_contact_monitor_set_iface (EMPATHY_CONTACT_MONITOR (object
),
204 g_value_get_object (value
));
207 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, param_id
, pspec
);
213 do_get_property (GObject
*object
,
218 EmpathyContactMonitorPriv
*priv
= GET_PRIV (object
);
223 g_value_set_object (value
, priv
->iface
);
226 G_OBJECT_WARN_INVALID_PROPERTY_ID (object
, param_id
, pspec
);
232 do_finalize (GObject
*obj
)
234 EmpathyContactMonitorPriv
*priv
;
236 priv
= GET_PRIV (obj
);
240 g_list_free (priv
->contacts
);
241 priv
->contacts
= NULL
;
245 g_signal_handlers_disconnect_by_func (priv
->iface
,
246 cl_members_changed_cb
, obj
);
248 G_OBJECT_CLASS (empathy_contact_monitor_parent_class
)->finalize (obj
);
252 do_dispose (GObject
*obj
)
254 EmpathyContactMonitorPriv
*priv
;
256 priv
= GET_PRIV (obj
);
258 if (priv
->dispose_run
)
261 priv
->dispose_run
= TRUE
;
264 g_list_foreach (priv
->contacts
,
265 (GFunc
) contact_remove_foreach
, obj
);
268 g_signal_handlers_disconnect_by_func (priv
->iface
,
269 cl_members_changed_cb
, obj
);
271 G_OBJECT_CLASS (empathy_contact_monitor_parent_class
)->dispose (obj
);
275 empathy_contact_monitor_class_init (EmpathyContactMonitorClass
*klass
)
277 GObjectClass
*oclass
= G_OBJECT_CLASS (klass
);
279 oclass
->finalize
= do_finalize
;
280 oclass
->dispose
= do_dispose
;
281 oclass
->get_property
= do_get_property
;
282 oclass
->set_property
= do_set_property
;
284 g_object_class_install_property (oclass
,
286 g_param_spec_object ("iface",
288 "The contact list we're monitoring",
289 EMPATHY_TYPE_CONTACT_LIST
,
291 G_PARAM_CONSTRUCT_ONLY
|
292 G_PARAM_STATIC_STRINGS
));
294 signals
[CONTACT_ADDED
] =
295 g_signal_new ("contact-added",
296 G_TYPE_FROM_CLASS (klass
),
300 g_cclosure_marshal_VOID__OBJECT
,
302 1, EMPATHY_TYPE_CONTACT
);
303 signals
[CONTACT_AVATAR_CHANGED
] =
304 g_signal_new ("contact-avatar-changed",
305 G_TYPE_FROM_CLASS (klass
),
309 g_cclosure_marshal_VOID__OBJECT
,
311 1, EMPATHY_TYPE_CONTACT
);
312 signals
[CONTACT_CAPABILITIES_CHANGED
] =
313 g_signal_new ("contact-capabilities-changed",
314 G_TYPE_FROM_CLASS (klass
),
318 g_cclosure_marshal_VOID__OBJECT
,
320 1, EMPATHY_TYPE_CONTACT
);
321 signals
[CONTACT_NAME_CHANGED
] =
322 g_signal_new ("contact-name-changed",
323 G_TYPE_FROM_CLASS (klass
),
327 _empathy_marshal_VOID__OBJECT_STRING
,
329 2, EMPATHY_TYPE_CONTACT
,
331 signals
[CONTACT_PRESENCE_CHANGED
] =
332 g_signal_new ("contact-presence-changed",
333 G_TYPE_FROM_CLASS (klass
),
337 _empathy_marshal_VOID__OBJECT_UINT_UINT
,
339 3, EMPATHY_TYPE_CONTACT
,
342 signals
[CONTACT_PRESENCE_MESSAGE_CHANGED
] =
343 g_signal_new ("contact-presence-message-changed",
344 G_TYPE_FROM_CLASS (klass
),
348 _empathy_marshal_VOID__OBJECT_STRING
,
350 2, EMPATHY_TYPE_CONTACT
,
352 signals
[CONTACT_REMOVED
] =
353 g_signal_new ("contact-removed",
354 G_TYPE_FROM_CLASS (klass
),
358 g_cclosure_marshal_VOID__OBJECT
,
360 1, EMPATHY_TYPE_CONTACT
);
362 g_type_class_add_private (klass
, sizeof (EmpathyContactMonitorPriv
));
366 empathy_contact_monitor_init (EmpathyContactMonitor
*self
)
368 EmpathyContactMonitorPriv
*priv
=
369 G_TYPE_INSTANCE_GET_PRIVATE (self
, EMPATHY_TYPE_CONTACT_MONITOR
,
370 EmpathyContactMonitorPriv
);
373 priv
->contacts
= NULL
;
375 priv
->dispose_run
= FALSE
;
381 empathy_contact_monitor_set_iface (EmpathyContactMonitor
*self
,
382 EmpathyContactList
*iface
)
384 EmpathyContactMonitorPriv
*priv
;
386 g_return_if_fail (EMPATHY_IS_CONTACT_MONITOR (self
));
387 g_return_if_fail (EMPATHY_IS_CONTACT_LIST (iface
));
389 priv
= GET_PRIV (self
);
391 if (priv
->contacts
!= NULL
)
393 g_list_foreach (priv
->contacts
,
394 (GFunc
) contact_remove_foreach
, self
);
395 g_list_free (priv
->contacts
);
396 priv
->contacts
= NULL
;
401 g_signal_connect (iface
, "members-changed",
402 G_CALLBACK (cl_members_changed_cb
), self
);
405 EmpathyContactMonitor
*
406 empathy_contact_monitor_new_for_iface (EmpathyContactList
*iface
)
408 EmpathyContactMonitor
*retval
;
410 g_return_val_if_fail (EMPATHY_IS_CONTACT_LIST (iface
), NULL
);
412 retval
= g_object_new (EMPATHY_TYPE_CONTACT_MONITOR
,
413 "iface", iface
, NULL
);