]> git.0d.be Git - empathy.git/blob - libempathy/empathy-contact.c
Updated.
[empathy.git] / libempathy / empathy-contact.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3  * Copyright (C) 2004 Imendio AB
4  * Copyright (C) 2007 Collabora Ltd.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License as
8  * published by the Free Software Foundation; either version 2 of the
9  * License, or (at your option) any later version.
10  *
11  * This program 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  * General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public
17  * License along with this program; if not, write to the
18  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19  * Boston, MA 02111-1307, USA.
20  *
21  * Authors: Mikael Hallendal <micke@imendio.com>
22  *          Martyn Russell <martyn@imendio.com>
23  *          Xavier Claessens <xclaesse@gmail.com>
24  */
25
26 #include "config.h"
27
28 #include <string.h>
29
30 #include <glib/gi18n.h>
31
32 #include "empathy-contact.h"
33 #include "empathy-utils.h"
34 #include "empathy-debug.h"
35 #include "empathy-enum-types.h"
36
37 #define DEBUG_DOMAIN "Contact"
38
39 #define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EMPATHY_TYPE_CONTACT, EmpathyContactPriv))
40
41 typedef struct _EmpathyContactPriv EmpathyContactPriv;
42
43 struct _EmpathyContactPriv {
44         gchar              *id;
45         gchar              *name;
46         EmpathyAvatar      *avatar;
47         McAccount          *account;
48         EmpathyPresence    *presence;
49         guint               handle;
50         EmpathyCapabilities capabilities;
51         gboolean            is_user;
52 };
53
54 static void empathy_contact_class_init (EmpathyContactClass *class);
55 static void empathy_contact_init       (EmpathyContact      *contact);
56 static void contact_finalize           (GObject             *object);
57 static void contact_get_property       (GObject             *object,
58                                         guint                param_id,
59                                         GValue              *value,
60                                         GParamSpec          *pspec);
61 static void contact_set_property       (GObject             *object,
62                                         guint                param_id,
63                                         const GValue        *value,
64                                         GParamSpec          *pspec);
65
66 G_DEFINE_TYPE (EmpathyContact, empathy_contact, G_TYPE_OBJECT);
67
68 enum {
69         PROP_0,
70         PROP_ID,
71         PROP_NAME,
72         PROP_AVATAR,
73         PROP_ACCOUNT,
74         PROP_PRESENCE,
75         PROP_GROUPS,
76         PROP_SUBSCRIPTION,
77         PROP_HANDLE,
78         PROP_CAPABILITIES,
79         PROP_IS_USER
80 };
81
82 static void
83 empathy_contact_class_init (EmpathyContactClass *class)
84 {
85         GObjectClass *object_class;
86
87         object_class = G_OBJECT_CLASS (class);
88
89         object_class->finalize     = contact_finalize;
90         object_class->get_property = contact_get_property;
91         object_class->set_property = contact_set_property;
92
93         g_object_class_install_property (object_class,
94                                          PROP_ID,
95                                          g_param_spec_string ("id",
96                                                               "Contact id",
97                                                               "String identifying contact",
98                                                               NULL,
99                                                               G_PARAM_READWRITE));
100
101         g_object_class_install_property (object_class,
102                                          PROP_NAME,
103                                          g_param_spec_string ("name",
104                                                               "Contact Name",
105                                                               "The name of the contact",
106                                                               NULL,
107                                                               G_PARAM_READWRITE));
108
109         g_object_class_install_property (object_class,
110                                          PROP_AVATAR,
111                                          g_param_spec_boxed ("avatar",
112                                                              "Avatar image",
113                                                              "The avatar image",
114                                                              EMPATHY_TYPE_AVATAR,
115                                                              G_PARAM_READWRITE));
116
117         g_object_class_install_property (object_class,
118                                          PROP_ACCOUNT,
119                                          g_param_spec_object ("account",
120                                                               "Contact Account",
121                                                               "The account associated with the contact",
122                                                               MC_TYPE_ACCOUNT,
123                                                               G_PARAM_READWRITE));
124
125         g_object_class_install_property (object_class,
126                                          PROP_PRESENCE,
127                                          g_param_spec_object ("presence",
128                                                               "Contact presence",
129                                                               "Presence of contact",
130                                                               EMPATHY_TYPE_PRESENCE,
131                                                               G_PARAM_READWRITE));
132
133         g_object_class_install_property (object_class,
134                                          PROP_HANDLE,
135                                          g_param_spec_uint ("handle",
136                                                             "Contact Handle",
137                                                             "The handle of the contact",
138                                                             0,
139                                                             G_MAXUINT,
140                                                             0,
141                                                             G_PARAM_READWRITE));
142
143         g_object_class_install_property (object_class,
144                                          PROP_CAPABILITIES,
145                                          g_param_spec_flags ("capabilities",
146                                                              "Contact Capabilities",
147                                                              "Capabilities of the contact",
148                                                              EMPATHY_TYPE_CAPABILITIES,
149                                                              0,
150                                                              G_PARAM_READWRITE));
151
152         g_object_class_install_property (object_class,
153                                          PROP_IS_USER,
154                                          g_param_spec_boolean ("is-user",
155                                                                "Contact is-user",
156                                                                "Is contact the user",
157                                                                FALSE,
158                                                                G_PARAM_READWRITE));
159
160         g_type_class_add_private (object_class, sizeof (EmpathyContactPriv));
161 }
162
163 static void
164 empathy_contact_init (EmpathyContact *contact)
165 {
166 }
167
168 static void
169 contact_finalize (GObject *object)
170 {
171         EmpathyContactPriv *priv;
172
173         priv = GET_PRIV (object);
174
175         empathy_debug (DEBUG_DOMAIN, "finalize: %p", object);
176
177         g_free (priv->name);
178         g_free (priv->id);
179
180         if (priv->avatar) {
181                 empathy_avatar_unref (priv->avatar);
182         }
183
184         if (priv->presence) {
185                 g_object_unref (priv->presence);
186         }
187
188         if (priv->account) {
189                 g_object_unref (priv->account);
190         }
191
192         G_OBJECT_CLASS (empathy_contact_parent_class)->finalize (object);
193 }
194
195 static void
196 contact_get_property (GObject    *object,
197                       guint       param_id,
198                       GValue     *value,
199                       GParamSpec *pspec)
200 {
201         EmpathyContactPriv *priv;
202
203         priv = GET_PRIV (object);
204
205         switch (param_id) {
206         case PROP_ID:
207                 g_value_set_string (value,
208                                     empathy_contact_get_id (EMPATHY_CONTACT (object)));
209                 break;
210         case PROP_NAME:
211                 g_value_set_string (value,
212                                     empathy_contact_get_name (EMPATHY_CONTACT (object)));
213                 break;
214         case PROP_AVATAR:
215                 g_value_set_boxed (value, priv->avatar);
216                 break;
217         case PROP_ACCOUNT:
218                 g_value_set_object (value, priv->account);
219                 break;
220         case PROP_PRESENCE:
221                 g_value_set_object (value, priv->presence);
222                 break;
223         case PROP_HANDLE:
224                 g_value_set_uint (value, priv->handle);
225                 break;
226         case PROP_CAPABILITIES:
227                 g_value_set_flags (value, priv->capabilities);
228                 break;
229         case PROP_IS_USER:
230                 g_value_set_boolean (value, priv->is_user);
231                 break;
232         default:
233                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
234                 break;
235         };
236 }
237
238 static void
239 contact_set_property (GObject      *object,
240                       guint         param_id,
241                       const GValue *value,
242                       GParamSpec   *pspec)
243 {
244         EmpathyContactPriv *priv;
245
246         priv = GET_PRIV (object);
247
248         switch (param_id) {
249         case PROP_ID:
250                 empathy_contact_set_id (EMPATHY_CONTACT (object),
251                                        g_value_get_string (value));
252                 break;
253         case PROP_NAME:
254                 empathy_contact_set_name (EMPATHY_CONTACT (object),
255                                          g_value_get_string (value));
256                 break;
257         case PROP_AVATAR:
258                 empathy_contact_set_avatar (EMPATHY_CONTACT (object),
259                                            g_value_get_boxed (value));
260                 break;
261         case PROP_ACCOUNT:
262                 empathy_contact_set_account (EMPATHY_CONTACT (object),
263                                             MC_ACCOUNT (g_value_get_object (value)));
264                 break;
265         case PROP_PRESENCE:
266                 empathy_contact_set_presence (EMPATHY_CONTACT (object),
267                                              EMPATHY_PRESENCE (g_value_get_object (value)));
268                 break;
269         case PROP_HANDLE:
270                 empathy_contact_set_handle (EMPATHY_CONTACT (object),
271                                            g_value_get_uint (value));
272                 break;
273         case PROP_CAPABILITIES:
274                 empathy_contact_set_capabilities (EMPATHY_CONTACT (object),
275                                                   g_value_get_flags (value));
276                 break;
277         case PROP_IS_USER:
278                 empathy_contact_set_is_user (EMPATHY_CONTACT (object),
279                                             g_value_get_boolean (value));
280                 break;
281         default:
282                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
283                 break;
284         };
285 }
286
287 EmpathyContact *
288 empathy_contact_new (McAccount *account)
289 {
290         return g_object_new (EMPATHY_TYPE_CONTACT,
291                              "account", account,
292                              NULL);
293 }
294
295 EmpathyContact *
296 empathy_contact_new_full (McAccount   *account,
297                           const gchar *id,
298                           const gchar *name)
299 {
300         return g_object_new (EMPATHY_TYPE_CONTACT,
301                              "account", account,
302                              "name", name,
303                              "id", id,
304                              NULL);
305 }
306
307 const gchar *
308 empathy_contact_get_id (EmpathyContact *contact)
309 {
310         EmpathyContactPriv *priv;
311
312         g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), "");
313
314         priv = GET_PRIV (contact);
315
316         if (priv->id) {
317                 return priv->id;
318         }
319
320         return "";
321 }
322
323 void
324 empathy_contact_set_id (EmpathyContact *contact,
325                        const gchar   *id)
326 {
327         EmpathyContactPriv *priv;
328
329         g_return_if_fail (EMPATHY_IS_CONTACT (contact));
330         g_return_if_fail (id != NULL);
331
332         priv = GET_PRIV (contact);
333
334         if (priv->id && strcmp (id, priv->id) == 0) {
335                 return;
336         }
337
338         g_free (priv->id);
339         priv->id = g_strdup (id);
340
341         g_object_notify (G_OBJECT (contact), "id");
342 }
343
344 const gchar *
345 empathy_contact_get_name (EmpathyContact *contact)
346 {
347         EmpathyContactPriv *priv;
348
349         g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), "");
350
351         priv = GET_PRIV (contact);
352
353         if (G_STR_EMPTY (priv->name)) {
354                 return empathy_contact_get_id (contact);
355         }
356
357         return priv->name;
358 }
359
360 void
361 empathy_contact_set_name (EmpathyContact *contact,
362                          const gchar   *name)
363 {
364         EmpathyContactPriv *priv;
365
366         g_return_if_fail (EMPATHY_IS_CONTACT (contact));
367         g_return_if_fail (name != NULL);
368
369         priv = GET_PRIV (contact);
370
371         if (priv->name && strcmp (name, priv->name) == 0) {
372                 return;
373         }
374
375         g_free (priv->name);
376         priv->name = g_strdup (name);
377
378         g_object_notify (G_OBJECT (contact), "name");
379 }
380
381 EmpathyAvatar *
382 empathy_contact_get_avatar (EmpathyContact *contact)
383 {
384         EmpathyContactPriv *priv;
385
386         g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL);
387
388         priv = GET_PRIV (contact);
389
390         return priv->avatar;
391 }
392
393 void
394 empathy_contact_set_avatar (EmpathyContact *contact,
395                            EmpathyAvatar  *avatar)
396 {
397         EmpathyContactPriv *priv;
398
399         g_return_if_fail (EMPATHY_IS_CONTACT (contact));
400
401         priv = GET_PRIV (contact);
402
403         if (priv->avatar == avatar) {
404                 return;
405         }
406
407         if (priv->avatar) {
408                 empathy_avatar_unref (priv->avatar);
409                 priv->avatar = NULL;
410         }
411
412         if (avatar) {
413                 priv->avatar = empathy_avatar_ref (avatar);
414         }
415
416         g_object_notify (G_OBJECT (contact), "avatar");
417 }
418
419 McAccount *
420 empathy_contact_get_account (EmpathyContact *contact)
421 {
422         EmpathyContactPriv *priv;
423
424         g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL);
425
426         priv = GET_PRIV (contact);
427
428         return priv->account;
429 }
430
431 void
432 empathy_contact_set_account (EmpathyContact *contact,
433                              McAccount      *account)
434 {
435         EmpathyContactPriv *priv;
436
437         g_return_if_fail (EMPATHY_IS_CONTACT (contact));
438         g_return_if_fail (MC_IS_ACCOUNT (account));
439
440         priv = GET_PRIV (contact);
441
442         if (account == priv->account) {
443                 return;
444         }
445
446         if (priv->account) {
447                 g_object_unref (priv->account);
448         }
449         priv->account = g_object_ref (account);
450
451         g_object_notify (G_OBJECT (contact), "account");
452 }
453
454 EmpathyPresence *
455 empathy_contact_get_presence (EmpathyContact *contact)
456 {
457         EmpathyContactPriv *priv;
458
459         g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL);
460
461         priv = GET_PRIV (contact);
462
463         return priv->presence;
464 }
465
466 void
467 empathy_contact_set_presence (EmpathyContact  *contact,
468                               EmpathyPresence *presence)
469 {
470         EmpathyContactPriv *priv;
471
472         g_return_if_fail (EMPATHY_IS_CONTACT (contact));
473
474         priv = GET_PRIV (contact);
475
476         if (presence == priv->presence) {
477                 return;
478         }
479
480         if (priv->presence) {
481                 g_object_unref (priv->presence);
482                 priv->presence = NULL;
483         }
484
485         if (presence) {
486                 priv->presence = g_object_ref (presence);
487         }
488
489         g_object_notify (G_OBJECT (contact), "presence");
490 }
491
492 guint
493 empathy_contact_get_handle (EmpathyContact *contact)
494 {
495         EmpathyContactPriv *priv;
496
497         g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), 0);
498
499         priv = GET_PRIV (contact);
500
501         return priv->handle;
502 }
503
504 void
505 empathy_contact_set_handle (EmpathyContact *contact,
506                            guint          handle)
507 {
508         EmpathyContactPriv *priv;
509
510         g_return_if_fail (EMPATHY_IS_CONTACT (contact));
511
512         priv = GET_PRIV (contact);
513
514         if (priv->handle == handle) {
515                 return;
516         }
517
518         priv->handle = handle;
519
520         g_object_notify (G_OBJECT (contact), "handle");
521 }
522
523 EmpathyCapabilities
524 empathy_contact_get_capabilities (EmpathyContact *contact)
525 {
526         EmpathyContactPriv *priv;
527
528         g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), 0);
529
530         priv = GET_PRIV (contact);
531
532         return priv->capabilities;
533 }
534
535 void
536 empathy_contact_set_capabilities (EmpathyContact      *contact,
537                                   EmpathyCapabilities  capabilities)
538 {
539         EmpathyContactPriv *priv;
540
541         g_return_if_fail (EMPATHY_IS_CONTACT (contact));
542
543         priv = GET_PRIV (contact);
544
545         if (priv->capabilities == capabilities) {
546                 return;
547         }
548
549         priv->capabilities = capabilities;
550
551         g_object_notify (G_OBJECT (contact), "capabilities");
552 }
553
554 gboolean
555 empathy_contact_is_user (EmpathyContact *contact)
556 {
557         EmpathyContactPriv *priv;
558
559         g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), FALSE);
560
561         priv = GET_PRIV (contact);
562
563         return priv->is_user;
564 }
565
566 void
567 empathy_contact_set_is_user (EmpathyContact *contact,
568                             gboolean       is_user)
569 {
570         EmpathyContactPriv *priv;
571
572         g_return_if_fail (EMPATHY_IS_CONTACT (contact));
573
574         priv = GET_PRIV (contact);
575
576         if (priv->is_user == is_user) {
577                 return;
578         }
579
580         priv->is_user = is_user;
581
582         g_object_notify (G_OBJECT (contact), "is-user");
583 }
584
585 gboolean
586 empathy_contact_is_online (EmpathyContact *contact)
587 {
588         EmpathyContactPriv *priv;
589
590         g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), FALSE);
591
592         priv = GET_PRIV (contact);
593
594         if (!priv->presence) {
595                 return FALSE;
596         }
597
598         return (empathy_presence_get_state (priv->presence) > MC_PRESENCE_OFFLINE);
599 }
600
601 const gchar *
602 empathy_contact_get_status (EmpathyContact *contact)
603 {
604         EmpathyContactPriv *priv;
605
606         g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), "");
607
608         priv = GET_PRIV (contact);
609
610         if (priv->presence) {
611                 const gchar *status;
612
613                 status = empathy_presence_get_status (priv->presence);
614                 if (!status) {
615                         McPresence state;
616
617                         state = empathy_presence_get_state (priv->presence);
618                         status = empathy_presence_state_get_default_status (state);
619                 }
620
621                 return status;
622         }
623
624         return empathy_presence_state_get_default_status (MC_PRESENCE_OFFLINE);
625 }
626
627 gboolean
628 empathy_contact_can_voip (EmpathyContact *contact)
629 {
630         EmpathyContactPriv *priv;
631
632         g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), FALSE);
633
634         priv = GET_PRIV (contact);
635
636         return priv->capabilities & (EMPATHY_CAPABILITIES_AUDIO |
637                                      EMPATHY_CAPABILITIES_VIDEO);
638 }
639
640 gboolean
641 empathy_contact_equal (gconstpointer v1,
642                       gconstpointer v2)
643 {
644         McAccount   *account_a;
645         McAccount   *account_b;
646         const gchar *id_a;
647         const gchar *id_b;
648
649         g_return_val_if_fail (EMPATHY_IS_CONTACT (v1), FALSE);
650         g_return_val_if_fail (EMPATHY_IS_CONTACT (v2), FALSE);
651
652         account_a = empathy_contact_get_account (EMPATHY_CONTACT (v1));
653         account_b = empathy_contact_get_account (EMPATHY_CONTACT (v2));
654
655         id_a = empathy_contact_get_id (EMPATHY_CONTACT (v1));
656         id_b = empathy_contact_get_id (EMPATHY_CONTACT (v2));
657
658         return empathy_account_equal (account_a, account_b) && g_str_equal (id_a, id_b);
659 }
660
661 guint
662 empathy_contact_hash (gconstpointer key)
663 {
664         EmpathyContactPriv *priv;
665         guint              hash;
666
667         g_return_val_if_fail (EMPATHY_IS_CONTACT (key), +1);
668
669         priv = GET_PRIV (EMPATHY_CONTACT (key));
670
671         hash = empathy_account_hash (empathy_contact_get_account (EMPATHY_CONTACT (key)));
672         hash += g_str_hash (empathy_contact_get_id (EMPATHY_CONTACT (key)));
673
674         return hash;
675 }
676