1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 * Copyright (C) 2004-2007 Imendio AB
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of the
8 * License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public
16 * License along with this program; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
20 * Authors: Mikael Hallendal <micke@imendio.com>
21 * Martyn Russell <martyn@imendio.com>
28 #include <glib/gi18n.h>
30 #include "empathy-contact.h"
31 #include "empathy-utils.h"
32 #include "empathy-debug.h"
34 #define DEBUG_DOMAIN "Contact"
36 #define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EMPATHY_TYPE_CONTACT, EmpathyContactPriv))
38 typedef struct _EmpathyContactPriv EmpathyContactPriv;
40 struct _EmpathyContactPriv {
43 EmpathyAvatar *avatar;
45 EmpathyPresence *presence;
47 EmpathySubscription subscription;
52 static void contact_class_init (EmpathyContactClass *class);
53 static void contact_init (EmpathyContact *contact);
54 static void contact_finalize (GObject *object);
55 static void contact_get_property (GObject *object,
59 static void contact_set_property (GObject *object,
77 static gpointer parent_class = NULL;
80 empathy_contact_get_gtype (void)
82 static GType type = 0;
85 static const GTypeInfo info = {
86 sizeof (EmpathyContactClass),
88 NULL, /* base_finalize */
89 (GClassInitFunc) contact_class_init,
90 NULL, /* class_finalize */
91 NULL, /* class_data */
92 sizeof (EmpathyContact),
94 (GInstanceInitFunc) contact_init
97 type = g_type_register_static (G_TYPE_OBJECT,
106 contact_class_init (EmpathyContactClass *class)
108 GObjectClass *object_class;
110 object_class = G_OBJECT_CLASS (class);
111 parent_class = g_type_class_peek_parent (class);
113 object_class->finalize = contact_finalize;
114 object_class->get_property = contact_get_property;
115 object_class->set_property = contact_set_property;
117 g_object_class_install_property (object_class,
119 g_param_spec_string ("id",
121 "String identifying contact",
125 g_object_class_install_property (object_class,
127 g_param_spec_string ("name",
129 "The name of the contact",
133 g_object_class_install_property (object_class,
135 g_param_spec_boxed ("avatar",
141 g_object_class_install_property (object_class,
143 g_param_spec_object ("account",
145 "The account associated with the contact",
149 g_object_class_install_property (object_class,
151 g_param_spec_object ("presence",
153 "Presence of contact",
154 EMPATHY_TYPE_PRESENCE,
157 g_object_class_install_property (object_class,
159 g_param_spec_pointer ("groups",
164 g_object_class_install_property (object_class,
166 g_param_spec_int ("subscription",
167 "Contact Subscription",
168 "The subscription status of the contact",
169 EMPATHY_SUBSCRIPTION_NONE,
170 EMPATHY_SUBSCRIPTION_BOTH,
171 EMPATHY_SUBSCRIPTION_NONE,
175 g_object_class_install_property (object_class,
177 g_param_spec_uint ("handle",
179 "The handle of the contact",
184 g_object_class_install_property (object_class,
186 g_param_spec_boolean ("is-user",
188 "Is contact the user",
192 g_type_class_add_private (object_class, sizeof (EmpathyContactPriv));
196 contact_init (EmpathyContact *contact)
201 contact_finalize (GObject *object)
203 EmpathyContactPriv *priv;
205 priv = GET_PRIV (object);
207 empathy_debug (DEBUG_DOMAIN, "finalize: %p", object);
213 empathy_avatar_unref (priv->avatar);
216 if (priv->presence) {
217 g_object_unref (priv->presence);
221 g_list_foreach (priv->groups, (GFunc) g_free, NULL);
222 g_list_free (priv->groups);
226 g_object_unref (priv->account);
229 (G_OBJECT_CLASS (parent_class)->finalize) (object);
233 contact_get_property (GObject *object,
238 EmpathyContactPriv *priv;
240 priv = GET_PRIV (object);
244 g_value_set_string (value,
245 empathy_contact_get_id (EMPATHY_CONTACT (object)));
248 g_value_set_string (value,
249 empathy_contact_get_name (EMPATHY_CONTACT (object)));
252 g_value_set_boxed (value, priv->avatar);
255 g_value_set_object (value, priv->account);
258 g_value_set_object (value, priv->presence);
261 g_value_set_pointer (value, priv->groups);
263 case PROP_SUBSCRIPTION:
264 g_value_set_int (value, priv->subscription);
267 g_value_set_uint (value, priv->handle);
270 g_value_set_boolean (value, priv->is_user);
273 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
279 contact_set_property (GObject *object,
284 EmpathyContactPriv *priv;
286 priv = GET_PRIV (object);
290 empathy_contact_set_id (EMPATHY_CONTACT (object),
291 g_value_get_string (value));
294 empathy_contact_set_name (EMPATHY_CONTACT (object),
295 g_value_get_string (value));
298 empathy_contact_set_avatar (EMPATHY_CONTACT (object),
299 g_value_get_boxed (value));
302 empathy_contact_set_account (EMPATHY_CONTACT (object),
303 MC_ACCOUNT (g_value_get_object (value)));
306 empathy_contact_set_presence (EMPATHY_CONTACT (object),
307 EMPATHY_PRESENCE (g_value_get_object (value)));
310 empathy_contact_set_groups (EMPATHY_CONTACT (object),
311 g_value_get_pointer (value));
313 case PROP_SUBSCRIPTION:
314 empathy_contact_set_subscription (EMPATHY_CONTACT (object),
315 g_value_get_int (value));
318 empathy_contact_set_handle (EMPATHY_CONTACT (object),
319 g_value_get_uint (value));
322 empathy_contact_set_is_user (EMPATHY_CONTACT (object),
323 g_value_get_boolean (value));
326 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
332 empathy_contact_new (McAccount *account)
334 return g_object_new (EMPATHY_TYPE_CONTACT,
340 empathy_contact_new_full (McAccount *account,
344 return g_object_new (EMPATHY_TYPE_CONTACT,
352 empathy_contact_get_id (EmpathyContact *contact)
354 EmpathyContactPriv *priv;
356 g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), "");
358 priv = GET_PRIV (contact);
368 empathy_contact_get_name (EmpathyContact *contact)
370 EmpathyContactPriv *priv;
372 g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), "");
374 priv = GET_PRIV (contact);
376 if (G_STR_EMPTY (priv->name)) {
377 return empathy_contact_get_id (contact);
384 empathy_contact_get_avatar (EmpathyContact *contact)
386 EmpathyContactPriv *priv;
388 g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL);
390 priv = GET_PRIV (contact);
396 empathy_contact_get_account (EmpathyContact *contact)
398 EmpathyContactPriv *priv;
400 g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL);
402 priv = GET_PRIV (contact);
404 return priv->account;
408 empathy_contact_get_presence (EmpathyContact *contact)
410 EmpathyContactPriv *priv;
412 g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL);
414 priv = GET_PRIV (contact);
416 return priv->presence;
420 empathy_contact_get_groups (EmpathyContact *contact)
422 EmpathyContactPriv *priv;
424 g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL);
426 priv = GET_PRIV (contact);
432 empathy_contact_get_subscription (EmpathyContact *contact)
434 EmpathyContactPriv *priv;
436 g_return_val_if_fail (EMPATHY_IS_CONTACT (contact),
437 EMPATHY_SUBSCRIPTION_NONE);
439 priv = GET_PRIV (contact);
441 return priv->subscription;
445 empathy_contact_get_handle (EmpathyContact *contact)
447 EmpathyContactPriv *priv;
449 g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), 0);
451 priv = GET_PRIV (contact);
457 empathy_contact_is_user (EmpathyContact *contact)
459 EmpathyContactPriv *priv;
461 g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), FALSE);
463 priv = GET_PRIV (contact);
465 return priv->is_user;
469 empathy_contact_set_id (EmpathyContact *contact,
472 EmpathyContactPriv *priv;
474 g_return_if_fail (EMPATHY_IS_CONTACT (contact));
475 g_return_if_fail (id != NULL);
477 priv = GET_PRIV (contact);
479 if (priv->id && strcmp (id, priv->id) == 0) {
484 priv->id = g_strdup (id);
486 g_object_notify (G_OBJECT (contact), "id");
490 empathy_contact_set_name (EmpathyContact *contact,
493 EmpathyContactPriv *priv;
495 g_return_if_fail (EMPATHY_IS_CONTACT (contact));
496 g_return_if_fail (name != NULL);
498 priv = GET_PRIV (contact);
500 if (priv->name && strcmp (name, priv->name) == 0) {
505 priv->name = g_strdup (name);
507 g_object_notify (G_OBJECT (contact), "name");
511 empathy_contact_set_avatar (EmpathyContact *contact,
512 EmpathyAvatar *avatar)
514 EmpathyContactPriv *priv;
516 g_return_if_fail (EMPATHY_IS_CONTACT (contact));
518 priv = GET_PRIV (contact);
520 if (priv->avatar == avatar) {
525 empathy_avatar_unref (priv->avatar);
530 priv->avatar = empathy_avatar_ref (avatar);
533 g_object_notify (G_OBJECT (contact), "avatar");
537 empathy_contact_set_account (EmpathyContact *contact,
540 EmpathyContactPriv *priv;
542 g_return_if_fail (EMPATHY_IS_CONTACT (contact));
543 g_return_if_fail (MC_IS_ACCOUNT (account));
545 priv = GET_PRIV (contact);
547 if (account == priv->account) {
552 g_object_unref (priv->account);
554 priv->account = g_object_ref (account);
556 g_object_notify (G_OBJECT (contact), "account");
560 empathy_contact_set_presence (EmpathyContact *contact,
561 EmpathyPresence *presence)
563 EmpathyContactPriv *priv;
565 g_return_if_fail (EMPATHY_IS_CONTACT (contact));
567 priv = GET_PRIV (contact);
569 if (presence == priv->presence) {
573 if (priv->presence) {
574 g_object_unref (priv->presence);
575 priv->presence = NULL;
579 priv->presence = g_object_ref (presence);
582 g_object_notify (G_OBJECT (contact), "presence");
586 empathy_contact_set_groups (EmpathyContact *contact,
589 EmpathyContactPriv *priv;
590 GList *old_groups, *l;
592 g_return_if_fail (EMPATHY_IS_CONTACT (contact));
594 priv = GET_PRIV (contact);
596 old_groups = priv->groups;
599 for (l = groups; l; l = l->next) {
600 priv->groups = g_list_append (priv->groups,
604 g_list_foreach (old_groups, (GFunc) g_free, NULL);
605 g_list_free (old_groups);
607 g_object_notify (G_OBJECT (contact), "groups");
611 empathy_contact_set_subscription (EmpathyContact *contact,
612 EmpathySubscription subscription)
614 EmpathyContactPriv *priv;
616 g_return_if_fail (EMPATHY_IS_CONTACT (contact));
618 priv = GET_PRIV (contact);
620 if (priv->subscription == subscription) {
624 priv->subscription = subscription;
626 g_object_notify (G_OBJECT (contact), "subscription");
630 empathy_contact_set_handle (EmpathyContact *contact,
633 EmpathyContactPriv *priv;
635 g_return_if_fail (EMPATHY_IS_CONTACT (contact));
637 priv = GET_PRIV (contact);
639 if (priv->handle == handle) {
643 priv->handle = handle;
645 g_object_notify (G_OBJECT (contact), "handle");
649 empathy_contact_set_is_user (EmpathyContact *contact,
652 EmpathyContactPriv *priv;
654 g_return_if_fail (EMPATHY_IS_CONTACT (contact));
656 priv = GET_PRIV (contact);
658 if (priv->is_user == is_user) {
662 priv->is_user = is_user;
664 g_object_notify (G_OBJECT (contact), "is-user");
668 empathy_contact_add_group (EmpathyContact *contact,
671 EmpathyContactPriv *priv;
673 g_return_if_fail (EMPATHY_IS_CONTACT (contact));
674 g_return_if_fail (group != NULL);
676 priv = GET_PRIV (contact);
678 if (!g_list_find_custom (priv->groups, group, (GCompareFunc) strcmp)) {
679 priv->groups = g_list_prepend (priv->groups, g_strdup (group));
680 g_object_notify (G_OBJECT (contact), "groups");
685 empathy_contact_remove_group (EmpathyContact *contact,
688 EmpathyContactPriv *priv;
691 g_return_if_fail (EMPATHY_IS_CONTACT (contact));
692 g_return_if_fail (group != NULL);
694 priv = GET_PRIV (contact);
696 l = g_list_find_custom (priv->groups, group, (GCompareFunc) strcmp);
699 priv->groups = g_list_delete_link (priv->groups, l);
700 g_object_notify (G_OBJECT (contact), "groups");
705 empathy_contact_is_online (EmpathyContact *contact)
707 EmpathyContactPriv *priv;
709 g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), FALSE);
711 priv = GET_PRIV (contact);
713 if (!priv->presence) {
717 return (empathy_presence_get_state (priv->presence) > MC_PRESENCE_OFFLINE);
721 empathy_contact_is_in_group (EmpathyContact *contact,
724 EmpathyContactPriv *priv;
726 g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), FALSE);
727 g_return_val_if_fail (!G_STR_EMPTY (group), FALSE);
729 priv = GET_PRIV (contact);
731 if (g_list_find_custom (priv->groups, group, (GCompareFunc) strcmp)) {
739 empathy_contact_get_status (EmpathyContact *contact)
741 EmpathyContactPriv *priv;
743 g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), "");
745 priv = GET_PRIV (contact);
747 if (priv->presence) {
750 status = empathy_presence_get_status (priv->presence);
754 state = empathy_presence_get_state (priv->presence);
755 status = empathy_presence_state_get_default_status (state);
761 return empathy_presence_state_get_default_status (MC_PRESENCE_OFFLINE);
765 empathy_contact_equal (gconstpointer v1,
768 McAccount *account_a;
769 McAccount *account_b;
773 g_return_val_if_fail (EMPATHY_IS_CONTACT (v1), FALSE);
774 g_return_val_if_fail (EMPATHY_IS_CONTACT (v2), FALSE);
776 account_a = empathy_contact_get_account (EMPATHY_CONTACT (v1));
777 account_b = empathy_contact_get_account (EMPATHY_CONTACT (v2));
779 id_a = empathy_contact_get_id (EMPATHY_CONTACT (v1));
780 id_b = empathy_contact_get_id (EMPATHY_CONTACT (v2));
782 return empathy_account_equal (account_a, account_b) && g_str_equal (id_a, id_b);
786 empathy_contact_hash (gconstpointer key)
788 EmpathyContactPriv *priv;
791 g_return_val_if_fail (EMPATHY_IS_CONTACT (key), +1);
793 priv = GET_PRIV (EMPATHY_CONTACT (key));
795 hash = empathy_account_hash (empathy_contact_get_account (EMPATHY_CONTACT (key)));
796 hash += g_str_hash (empathy_contact_get_id (EMPATHY_CONTACT (key)));