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 "gossip-contact.h"
31 #include "gossip-utils.h"
32 #include "gossip-debug.h"
34 #define DEBUG_DOMAIN "Contact"
36 #define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GOSSIP_TYPE_CONTACT, GossipContactPriv))
38 typedef struct _GossipContactPriv GossipContactPriv;
40 struct _GossipContactPriv {
45 GossipPresence *presence;
47 GossipSubscription subscription;
51 static void contact_class_init (GossipContactClass *class);
52 static void contact_init (GossipContact *contact);
53 static void contact_finalize (GObject *object);
54 static void contact_get_property (GObject *object,
58 static void contact_set_property (GObject *object,
75 static gpointer parent_class = NULL;
78 gossip_contact_get_gtype (void)
80 static GType type = 0;
83 static const GTypeInfo info = {
84 sizeof (GossipContactClass),
86 NULL, /* base_finalize */
87 (GClassInitFunc) contact_class_init,
88 NULL, /* class_finalize */
89 NULL, /* class_data */
90 sizeof (GossipContact),
92 (GInstanceInitFunc) contact_init
95 type = g_type_register_static (G_TYPE_OBJECT,
104 contact_class_init (GossipContactClass *class)
106 GObjectClass *object_class;
108 object_class = G_OBJECT_CLASS (class);
109 parent_class = g_type_class_peek_parent (class);
111 object_class->finalize = contact_finalize;
112 object_class->get_property = contact_get_property;
113 object_class->set_property = contact_set_property;
115 g_object_class_install_property (object_class,
117 g_param_spec_string ("id",
119 "String identifying contact",
123 g_object_class_install_property (object_class,
125 g_param_spec_string ("name",
127 "The name of the contact",
131 g_object_class_install_property (object_class,
133 g_param_spec_boxed ("avatar",
139 g_object_class_install_property (object_class,
141 g_param_spec_object ("account",
143 "The account associated with the contact",
147 g_object_class_install_property (object_class,
149 g_param_spec_object ("presence",
151 "Presence of contact",
152 GOSSIP_TYPE_PRESENCE,
155 g_object_class_install_property (object_class,
157 g_param_spec_pointer ("groups",
162 g_object_class_install_property (object_class,
164 g_param_spec_int ("subscription",
165 "Contact Subscription",
166 "The subscription status of the contact",
167 GOSSIP_SUBSCRIPTION_NONE,
168 GOSSIP_SUBSCRIPTION_BOTH,
169 GOSSIP_SUBSCRIPTION_NONE,
173 g_object_class_install_property (object_class,
175 g_param_spec_uint ("handle",
177 "The handle of the contact",
183 g_type_class_add_private (object_class, sizeof (GossipContactPriv));
187 contact_init (GossipContact *contact)
189 GossipContactPriv *priv;
191 priv = GET_PRIV (contact);
196 priv->account = NULL;
197 priv->presence = NULL;
203 contact_finalize (GObject *object)
205 GossipContactPriv *priv;
207 priv = GET_PRIV (object);
209 gossip_debug (DEBUG_DOMAIN, "finalize: %p", object);
215 gossip_avatar_unref (priv->avatar);
218 if (priv->presence) {
219 g_object_unref (priv->presence);
223 g_list_foreach (priv->groups, (GFunc) g_free, NULL);
224 g_list_free (priv->groups);
228 g_object_unref (priv->account);
231 (G_OBJECT_CLASS (parent_class)->finalize) (object);
235 contact_get_property (GObject *object,
240 GossipContactPriv *priv;
242 priv = GET_PRIV (object);
246 g_value_set_string (value,
247 gossip_contact_get_id (GOSSIP_CONTACT (object)));
250 g_value_set_string (value,
251 gossip_contact_get_name (GOSSIP_CONTACT (object)));
254 g_value_set_boxed (value, priv->avatar);
257 g_value_set_object (value, priv->account);
260 g_value_set_object (value, priv->presence);
263 g_value_set_pointer (value, priv->groups);
265 case PROP_SUBSCRIPTION:
266 g_value_set_int (value, priv->subscription);
269 g_value_set_uint (value, priv->handle);
272 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
278 contact_set_property (GObject *object,
283 GossipContactPriv *priv;
285 priv = GET_PRIV (object);
289 gossip_contact_set_id (GOSSIP_CONTACT (object),
290 g_value_get_string (value));
293 gossip_contact_set_name (GOSSIP_CONTACT (object),
294 g_value_get_string (value));
297 gossip_contact_set_avatar (GOSSIP_CONTACT (object),
298 g_value_get_boxed (value));
301 gossip_contact_set_account (GOSSIP_CONTACT (object),
302 MC_ACCOUNT (g_value_get_object (value)));
305 gossip_contact_set_presence (GOSSIP_CONTACT (object),
306 GOSSIP_PRESENCE (g_value_get_object (value)));
309 gossip_contact_set_groups (GOSSIP_CONTACT (object),
310 g_value_get_pointer (value));
312 case PROP_SUBSCRIPTION:
313 gossip_contact_set_subscription (GOSSIP_CONTACT (object),
314 g_value_get_int (value));
317 gossip_contact_set_handle (GOSSIP_CONTACT (object),
318 g_value_get_uint (value));
321 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
327 gossip_contact_new (McAccount *account)
329 return g_object_new (GOSSIP_TYPE_CONTACT,
335 gossip_contact_new_full (McAccount *account,
339 return g_object_new (GOSSIP_TYPE_CONTACT,
347 gossip_contact_get_id (GossipContact *contact)
349 GossipContactPriv *priv;
351 g_return_val_if_fail (GOSSIP_IS_CONTACT (contact), "");
353 priv = GET_PRIV (contact);
363 gossip_contact_get_name (GossipContact *contact)
365 GossipContactPriv *priv;
367 g_return_val_if_fail (GOSSIP_IS_CONTACT (contact), "");
369 priv = GET_PRIV (contact);
371 if (priv->name == NULL) {
372 return gossip_contact_get_id (contact);
379 gossip_contact_get_avatar (GossipContact *contact)
381 GossipContactPriv *priv;
383 g_return_val_if_fail (GOSSIP_IS_CONTACT (contact), NULL);
385 priv = GET_PRIV (contact);
391 gossip_contact_get_account (GossipContact *contact)
393 GossipContactPriv *priv;
395 g_return_val_if_fail (GOSSIP_IS_CONTACT (contact), NULL);
397 priv = GET_PRIV (contact);
399 return priv->account;
403 gossip_contact_get_presence (GossipContact *contact)
405 GossipContactPriv *priv;
407 g_return_val_if_fail (GOSSIP_IS_CONTACT (contact), NULL);
409 priv = GET_PRIV (contact);
411 return priv->presence;
415 gossip_contact_get_groups (GossipContact *contact)
417 GossipContactPriv *priv;
419 g_return_val_if_fail (GOSSIP_IS_CONTACT (contact), NULL);
421 priv = GET_PRIV (contact);
427 gossip_contact_get_subscription (GossipContact *contact)
429 GossipContactPriv *priv;
431 g_return_val_if_fail (GOSSIP_IS_CONTACT (contact),
432 GOSSIP_SUBSCRIPTION_NONE);
434 priv = GET_PRIV (contact);
436 return priv->subscription;
440 gossip_contact_get_handle (GossipContact *contact)
442 GossipContactPriv *priv;
444 g_return_val_if_fail (GOSSIP_IS_CONTACT (contact), 0);
446 priv = GET_PRIV (contact);
452 gossip_contact_set_id (GossipContact *contact,
455 GossipContactPriv *priv;
457 g_return_if_fail (GOSSIP_IS_CONTACT (contact));
458 g_return_if_fail (id != NULL);
460 priv = GET_PRIV (contact);
463 priv->id = g_strdup (id);
465 g_object_notify (G_OBJECT (contact), "id");
469 gossip_contact_set_name (GossipContact *contact,
472 GossipContactPriv *priv;
474 g_return_if_fail (GOSSIP_IS_CONTACT (contact));
475 g_return_if_fail (name != NULL);
477 priv = GET_PRIV (contact);
480 priv->name = g_strdup (name);
482 g_object_notify (G_OBJECT (contact), "name");
486 gossip_contact_set_avatar (GossipContact *contact,
487 GossipAvatar *avatar)
489 GossipContactPriv *priv;
491 g_return_if_fail (GOSSIP_IS_CONTACT (contact));
493 priv = GET_PRIV (contact);
496 gossip_avatar_unref (priv->avatar);
501 priv->avatar = gossip_avatar_ref (avatar);
504 g_object_notify (G_OBJECT (contact), "avatar");
508 gossip_contact_set_account (GossipContact *contact,
511 GossipContactPriv *priv;
513 g_return_if_fail (GOSSIP_IS_CONTACT (contact));
514 g_return_if_fail (MC_IS_ACCOUNT (account));
516 priv = GET_PRIV (contact);
519 g_object_unref (priv->account);
521 priv->account = g_object_ref (account);
523 g_object_notify (G_OBJECT (contact), "account");
527 gossip_contact_set_presence (GossipContact *contact,
528 GossipPresence *presence)
530 GossipContactPriv *priv;
532 g_return_if_fail (GOSSIP_IS_CONTACT (contact));
534 priv = GET_PRIV (contact);
536 if (priv->presence) {
537 g_object_unref (priv->presence);
538 priv->presence = NULL;
542 priv->presence = g_object_ref (presence);
545 g_object_notify (G_OBJECT (contact), "presence");
549 gossip_contact_set_groups (GossipContact *contact,
552 GossipContactPriv *priv;
553 GList *old_groups, *l;
555 g_return_if_fail (GOSSIP_IS_CONTACT (contact));
557 priv = GET_PRIV (contact);
559 old_groups = priv->groups;
562 for (l = groups; l; l = l->next) {
563 priv->groups = g_list_append (priv->groups,
567 g_list_foreach (old_groups, (GFunc) g_free, NULL);
568 g_list_free (old_groups);
570 g_object_notify (G_OBJECT (contact), "groups");
574 gossip_contact_set_subscription (GossipContact *contact,
575 GossipSubscription subscription)
577 GossipContactPriv *priv;
579 g_return_if_fail (GOSSIP_IS_CONTACT (contact));
581 priv = GET_PRIV (contact);
583 priv->subscription = subscription;
585 g_object_notify (G_OBJECT (contact), "subscription");
589 gossip_contact_set_handle (GossipContact *contact,
592 GossipContactPriv *priv;
594 priv = GET_PRIV (contact);
596 priv->handle = handle;
598 g_object_notify (G_OBJECT (contact), "handle");
602 gossip_contact_is_online (GossipContact *contact)
604 GossipContactPriv *priv;
606 g_return_val_if_fail (GOSSIP_IS_CONTACT (contact), FALSE);
608 priv = GET_PRIV (contact);
610 return (priv->presence != NULL);
614 gossip_contact_get_status (GossipContact *contact)
616 GossipContactPriv *priv;
618 g_return_val_if_fail (GOSSIP_IS_CONTACT (contact), "");
620 priv = GET_PRIV (contact);
622 if (priv->presence) {
625 status = gossip_presence_get_status (priv->presence);
627 GossipPresenceState state;
629 state = gossip_presence_get_state (priv->presence);
630 status = gossip_presence_state_get_default_status (state);
640 gossip_contact_equal (gconstpointer v1,
643 McAccount *account_a;
644 McAccount *account_b;
648 g_return_val_if_fail (GOSSIP_IS_CONTACT (v1), FALSE);
649 g_return_val_if_fail (GOSSIP_IS_CONTACT (v2), FALSE);
651 account_a = gossip_contact_get_account (GOSSIP_CONTACT (v1));
652 account_b = gossip_contact_get_account (GOSSIP_CONTACT (v2));
654 id_a = gossip_contact_get_id (GOSSIP_CONTACT (v1));
655 id_b = gossip_contact_get_id (GOSSIP_CONTACT (v2));
657 return gossip_account_equal (account_a, account_b) && g_str_equal (id_a, id_b);
661 gossip_contact_hash (gconstpointer key)
663 GossipContactPriv *priv;
666 g_return_val_if_fail (GOSSIP_IS_CONTACT (key), +1);
668 priv = GET_PRIV (GOSSIP_CONTACT (key));
670 hash = gossip_account_hash (gossip_contact_get_account (GOSSIP_CONTACT (key)));
671 hash += g_str_hash (gossip_contact_get_id (GOSSIP_CONTACT (key)));