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