]> git.0d.be Git - empathy.git/blob - libempathy/empathy-contact.c
If we set contact's id and name is still empty, emit notify::name.
[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-2008 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         if (G_STR_EMPTY (priv->name)) {
358                 g_object_notify (G_OBJECT (contact), "name");
359         }
360 }
361
362 const gchar *
363 empathy_contact_get_name (EmpathyContact *contact)
364 {
365         EmpathyContactPriv *priv;
366
367         g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), "");
368
369         priv = GET_PRIV (contact);
370
371         if (G_STR_EMPTY (priv->name)) {
372                 return empathy_contact_get_id (contact);
373         }
374
375         return priv->name;
376 }
377
378 void
379 empathy_contact_set_name (EmpathyContact *contact,
380                          const gchar   *name)
381 {
382         EmpathyContactPriv *priv;
383
384         g_return_if_fail (EMPATHY_IS_CONTACT (contact));
385         g_return_if_fail (name != NULL);
386
387         priv = GET_PRIV (contact);
388
389         if (priv->name && strcmp (name, priv->name) == 0) {
390                 return;
391         }
392
393         g_free (priv->name);
394         priv->name = g_strdup (name);
395
396         g_object_notify (G_OBJECT (contact), "name");
397 }
398
399 EmpathyAvatar *
400 empathy_contact_get_avatar (EmpathyContact *contact)
401 {
402         EmpathyContactPriv *priv;
403
404         g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL);
405
406         priv = GET_PRIV (contact);
407
408         return priv->avatar;
409 }
410
411 void
412 empathy_contact_set_avatar (EmpathyContact *contact,
413                            EmpathyAvatar  *avatar)
414 {
415         EmpathyContactPriv *priv;
416
417         g_return_if_fail (EMPATHY_IS_CONTACT (contact));
418
419         priv = GET_PRIV (contact);
420
421         if (priv->avatar == avatar) {
422                 return;
423         }
424
425         if (priv->avatar) {
426                 empathy_avatar_unref (priv->avatar);
427                 priv->avatar = NULL;
428         }
429
430         if (avatar) {
431                 priv->avatar = empathy_avatar_ref (avatar);
432         }
433
434         g_object_notify (G_OBJECT (contact), "avatar");
435 }
436
437 McAccount *
438 empathy_contact_get_account (EmpathyContact *contact)
439 {
440         EmpathyContactPriv *priv;
441
442         g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL);
443
444         priv = GET_PRIV (contact);
445
446         return priv->account;
447 }
448
449 void
450 empathy_contact_set_account (EmpathyContact *contact,
451                              McAccount      *account)
452 {
453         EmpathyContactPriv *priv;
454
455         g_return_if_fail (EMPATHY_IS_CONTACT (contact));
456         g_return_if_fail (MC_IS_ACCOUNT (account));
457
458         priv = GET_PRIV (contact);
459
460         if (account == priv->account) {
461                 return;
462         }
463
464         if (priv->account) {
465                 g_object_unref (priv->account);
466         }
467         priv->account = g_object_ref (account);
468
469         g_object_notify (G_OBJECT (contact), "account");
470 }
471
472 McPresence
473 empathy_contact_get_presence (EmpathyContact *contact)
474 {
475         EmpathyContactPriv *priv;
476
477         g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), MC_PRESENCE_UNSET);
478
479         priv = GET_PRIV (contact);
480
481         return priv->presence;
482 }
483
484 void
485 empathy_contact_set_presence (EmpathyContact *contact,
486                               McPresence      presence)
487 {
488         EmpathyContactPriv *priv;
489
490         g_return_if_fail (EMPATHY_IS_CONTACT (contact));
491
492         priv = GET_PRIV (contact);
493
494         if (presence == priv->presence) {
495                 return;
496         }
497
498         priv->presence = presence;
499
500         g_object_notify (G_OBJECT (contact), "presence");
501 }
502
503 const gchar *
504 empathy_contact_get_presence_message (EmpathyContact *contact)
505 {
506         EmpathyContactPriv *priv;
507
508         g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL);
509
510         priv = GET_PRIV (contact);
511
512         return priv->presence_message;
513 }
514
515 void
516 empathy_contact_set_presence_message (EmpathyContact *contact,
517                                       const gchar    *message)
518 {
519         EmpathyContactPriv *priv = GET_PRIV (contact);
520
521         g_return_if_fail (EMPATHY_IS_CONTACT (contact));
522
523         if (!tp_strdiff (message, priv->presence_message)) {
524                 return;
525         }
526
527         g_free (priv->presence_message);
528         priv->presence_message = g_strdup (message);
529
530         g_object_notify (G_OBJECT (contact), "presence-message");
531 }
532
533 guint
534 empathy_contact_get_handle (EmpathyContact *contact)
535 {
536         EmpathyContactPriv *priv;
537
538         g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), 0);
539
540         priv = GET_PRIV (contact);
541
542         return priv->handle;
543 }
544
545 void
546 empathy_contact_set_handle (EmpathyContact *contact,
547                            guint          handle)
548 {
549         EmpathyContactPriv *priv;
550
551         g_return_if_fail (EMPATHY_IS_CONTACT (contact));
552
553         priv = GET_PRIV (contact);
554
555         if (priv->handle == handle) {
556                 return;
557         }
558
559         priv->handle = handle;
560
561         g_object_notify (G_OBJECT (contact), "handle");
562 }
563
564 EmpathyCapabilities
565 empathy_contact_get_capabilities (EmpathyContact *contact)
566 {
567         EmpathyContactPriv *priv;
568
569         g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), 0);
570
571         priv = GET_PRIV (contact);
572
573         return priv->capabilities;
574 }
575
576 void
577 empathy_contact_set_capabilities (EmpathyContact      *contact,
578                                   EmpathyCapabilities  capabilities)
579 {
580         EmpathyContactPriv *priv;
581
582         g_return_if_fail (EMPATHY_IS_CONTACT (contact));
583
584         priv = GET_PRIV (contact);
585
586         if (priv->capabilities == capabilities) {
587                 return;
588         }
589
590         priv->capabilities = capabilities;
591
592         g_object_notify (G_OBJECT (contact), "capabilities");
593 }
594
595 gboolean
596 empathy_contact_is_user (EmpathyContact *contact)
597 {
598         EmpathyContactPriv *priv;
599
600         g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), FALSE);
601
602         priv = GET_PRIV (contact);
603
604         return priv->is_user;
605 }
606
607 void
608 empathy_contact_set_is_user (EmpathyContact *contact,
609                             gboolean       is_user)
610 {
611         EmpathyContactPriv *priv;
612
613         g_return_if_fail (EMPATHY_IS_CONTACT (contact));
614
615         priv = GET_PRIV (contact);
616
617         if (priv->is_user == is_user) {
618                 return;
619         }
620
621         priv->is_user = is_user;
622
623         g_object_notify (G_OBJECT (contact), "is-user");
624 }
625
626 gboolean
627 empathy_contact_is_online (EmpathyContact *contact)
628 {
629         EmpathyContactPriv *priv;
630
631         g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), FALSE);
632
633         priv = GET_PRIV (contact);
634
635         return (priv->presence > MC_PRESENCE_OFFLINE);
636 }
637
638 const gchar *
639 empathy_contact_get_status (EmpathyContact *contact)
640 {
641         EmpathyContactPriv *priv;
642
643         g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), "");
644
645         priv = GET_PRIV (contact);
646
647         if (priv->presence_message) {
648                 return priv->presence_message;
649         }
650
651         return empathy_presence_get_default_message (priv->presence);
652 }
653
654 gboolean
655 empathy_contact_can_voip (EmpathyContact *contact)
656 {
657         EmpathyContactPriv *priv;
658
659         g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), FALSE);
660
661         priv = GET_PRIV (contact);
662
663         return priv->capabilities & (EMPATHY_CAPABILITIES_AUDIO |
664                                      EMPATHY_CAPABILITIES_VIDEO);
665 }
666
667 gboolean
668 empathy_contact_equal (gconstpointer v1,
669                       gconstpointer v2)
670 {
671         McAccount   *account_a;
672         McAccount   *account_b;
673         const gchar *id_a;
674         const gchar *id_b;
675
676         g_return_val_if_fail (EMPATHY_IS_CONTACT (v1), FALSE);
677         g_return_val_if_fail (EMPATHY_IS_CONTACT (v2), FALSE);
678
679         account_a = empathy_contact_get_account (EMPATHY_CONTACT (v1));
680         account_b = empathy_contact_get_account (EMPATHY_CONTACT (v2));
681
682         id_a = empathy_contact_get_id (EMPATHY_CONTACT (v1));
683         id_b = empathy_contact_get_id (EMPATHY_CONTACT (v2));
684
685         return empathy_account_equal (account_a, account_b) && g_str_equal (id_a, id_b);
686 }
687
688 guint
689 empathy_contact_hash (gconstpointer key)
690 {
691         EmpathyContactPriv *priv;
692         guint              hash;
693
694         g_return_val_if_fail (EMPATHY_IS_CONTACT (key), +1);
695
696         priv = GET_PRIV (EMPATHY_CONTACT (key));
697
698         hash = empathy_account_hash (empathy_contact_get_account (EMPATHY_CONTACT (key)));
699         hash += g_str_hash (empathy_contact_get_id (EMPATHY_CONTACT (key)));
700
701         return hash;
702 }
703