]> git.0d.be Git - empathy.git/blob - libempathy-gtk/empathy-contact-widget.c
Merge branch 'gnome-3-6'
[empathy.git] / libempathy-gtk / empathy-contact-widget.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3  * Copyright (C) 2007-2009 Collabora Ltd.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library 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  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
18  *
19  * Authors: Xavier Claessens <xclaesse@gmail.com>
20  */
21
22 #include <config.h>
23
24 #include <string.h>
25 #include <stdlib.h>
26
27 #include <gtk/gtk.h>
28 #include <glib/gi18n-lib.h>
29
30 #include <telepathy-glib/telepathy-glib.h>
31
32 #include <libempathy/empathy-time.h>
33 #include <libempathy/empathy-utils.h>
34 #include <libempathy/empathy-client-factory.h>
35
36 #include "empathy-calendar-button.h"
37 #include "empathy-contact-widget.h"
38 #include "empathy-contactinfo-utils.h"
39 #include "empathy-account-chooser.h"
40 #include "empathy-avatar-chooser.h"
41 #include "empathy-avatar-image.h"
42 #include "empathy-groups-widget.h"
43 #include "empathy-ui-utils.h"
44 #include "empathy-string-parser.h"
45
46 #define DEBUG_FLAG EMPATHY_DEBUG_CONTACT
47 #include <libempathy/empathy-debug.h>
48
49 /**
50  * SECTION:empathy-contact-widget
51  * @title:EmpathyContactWidget
52  * @short_description: A widget used to display and edit details about a contact
53  * @include: libempathy-empathy-contact-widget.h
54  *
55  * #EmpathyContactWidget is a widget which displays appropriate widgets
56  * with details about a contact, also allowing changing these details,
57  * if desired.
58  */
59
60 /**
61  * EmpathyContactWidget:
62  * @parent: parent object
63  *
64  * Widget which displays appropriate widgets with details about a contact,
65  * also allowing changing these details, if desired.
66  */
67
68 G_DEFINE_TYPE (EmpathyContactWidget, empathy_contact_widget, GTK_TYPE_BOX)
69
70 /* Delay before updating the widget when the id entry changed (seconds) */
71 #define ID_CHANGED_TIMEOUT 1
72
73 #define DATA_FIELD "contact-info-field"
74
75 struct _EmpathyContactWidgetPriv
76 {
77   EmpathyContact *contact;
78   guint widget_id_timeout;
79   gulong fav_sig_id;
80
81   /* Contact */
82   GtkWidget *widget_avatar;
83   GtkWidget *widget_account;
84   GtkWidget *image_account;
85   GtkWidget *label_account;
86   GtkWidget *widget_id;
87   GtkWidget *widget_alias;
88   GtkWidget *label_alias;
89   GtkWidget *hbox_presence;
90   GtkWidget *image_state;
91   GtkWidget *label_status;
92   GtkWidget *grid_contact;
93   GtkWidget *vbox_avatar;
94   GtkWidget *favourite_checkbox;
95   GtkWidget *label_details;
96   GtkWidget *label_left_account;
97
98   /* Groups */
99   GtkWidget *groups_widget;
100
101   /* Client */
102   GtkWidget *vbox_client;
103   GtkWidget *grid_client;
104   GtkWidget *hbox_client_requested;
105 };
106
107 typedef struct
108 {
109   EmpathyContactWidget *self;
110   const gchar *name;
111   gboolean found;
112   GtkTreeIter found_iter;
113 } FindName;
114
115 enum
116 {
117   COL_NAME,
118   COL_ENABLED,
119   COL_EDITABLE,
120   COL_COUNT
121 };
122
123
124 static void
125 contact_widget_client_update (EmpathyContactWidget *self)
126 {
127   /* FIXME: Needs new telepathy spec */
128 }
129
130 static void
131 contact_widget_client_setup (EmpathyContactWidget *self)
132 {
133   /* FIXME: Needs new telepathy spec */
134   gtk_widget_hide (self->priv->vbox_client);
135 }
136
137 static void
138 contact_widget_groups_update (EmpathyContactWidget *self)
139 {
140   if (self->priv->contact != NULL)
141     {
142       FolksPersona *persona =
143           empathy_contact_get_persona (self->priv->contact);
144
145       if (FOLKS_IS_GROUP_DETAILS (persona))
146         {
147           empathy_groups_widget_set_group_details (
148               EMPATHY_GROUPS_WIDGET (self->priv->groups_widget),
149               FOLKS_GROUP_DETAILS (persona));
150           gtk_widget_show (self->priv->groups_widget);
151
152           return;
153         }
154     }
155
156   /* In case of failure */
157   gtk_widget_hide (self->priv->groups_widget);
158 }
159
160 static void
161 save_avatar_menu_activate_cb (GtkWidget *widget,
162     EmpathyContactWidget *self)
163 {
164   GtkWidget *dialog;
165   EmpathyAvatar *avatar;
166   gchar *ext = NULL, *filename;
167
168   dialog = gtk_file_chooser_dialog_new (_("Save Avatar"),
169       NULL,
170       GTK_FILE_CHOOSER_ACTION_SAVE,
171       GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
172       GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
173       NULL);
174
175   gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog),
176       TRUE);
177
178   /* look for the avatar extension */
179   avatar = empathy_contact_get_avatar (self->priv->contact);
180   if (avatar->format != NULL)
181     {
182       gchar **splitted;
183
184       splitted = g_strsplit (avatar->format, "/", 2);
185       if (splitted[0] != NULL && splitted[1] != NULL)
186           ext = g_strdup (splitted[1]);
187
188       g_strfreev (splitted);
189     }
190   else
191     {
192       /* Avatar was loaded from the cache so was converted to PNG */
193       ext = g_strdup ("png");
194     }
195
196   if (ext != NULL)
197     {
198       gchar *id;
199
200       id = tp_escape_as_identifier (empathy_contact_get_id (
201             self->priv->contact));
202
203       filename = g_strdup_printf ("%s.%s", id, ext);
204       gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), filename);
205
206       g_free (id);
207       g_free (ext);
208       g_free (filename);
209     }
210
211   if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
212     {
213       GError *error = NULL;
214
215       filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
216
217       if (!empathy_avatar_save_to_file (avatar, filename, &error))
218         {
219           /* Save error */
220           GtkWidget *error_dialog;
221
222           error_dialog = gtk_message_dialog_new (NULL, 0,
223               GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
224               _("Unable to save avatar"));
225
226           gtk_message_dialog_format_secondary_text (
227               GTK_MESSAGE_DIALOG (error_dialog), "%s", error->message);
228
229           g_signal_connect (error_dialog, "response",
230               G_CALLBACK (gtk_widget_destroy), NULL);
231
232           gtk_window_present (GTK_WINDOW (error_dialog));
233
234           g_clear_error (&error);
235         }
236
237       g_free (filename);
238     }
239
240   gtk_widget_destroy (dialog);
241 }
242
243 static void
244 popup_avatar_menu (EmpathyContactWidget *self,
245                    GtkWidget *parent,
246                    GdkEventButton *event)
247 {
248   GtkWidget *menu, *item;
249   gint button, event_time;
250
251   if (self->priv->contact == NULL ||
252       empathy_contact_get_avatar (self->priv->contact) == NULL)
253       return;
254
255   menu = empathy_context_menu_new (parent);
256
257   /* Add "Save as..." entry */
258   item = gtk_image_menu_item_new_from_stock (GTK_STOCK_SAVE_AS, NULL);
259   gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
260   gtk_widget_show (item);
261
262   g_signal_connect (item, "activate",
263       G_CALLBACK (save_avatar_menu_activate_cb), self);
264
265   if (event)
266     {
267       button = event->button;
268       event_time = event->time;
269     }
270   else
271     {
272       button = 0;
273       event_time = gtk_get_current_event_time ();
274     }
275
276   gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL,
277       button, event_time);
278 }
279
280 static gboolean
281 widget_avatar_popup_menu_cb (GtkWidget *widget,
282                              EmpathyContactWidget *self)
283 {
284   popup_avatar_menu (self, widget, NULL);
285
286   return TRUE;
287 }
288
289 static gboolean
290 widget_avatar_button_press_event_cb (GtkWidget *widget,
291                                      GdkEventButton *event,
292                                      EmpathyContactWidget *self)
293 {
294   /* Ignore double-clicks and triple-clicks */
295   if (event->button == 3 && event->type == GDK_BUTTON_PRESS)
296     {
297       popup_avatar_menu (self, widget, event);
298       return TRUE;
299     }
300
301   return FALSE;
302 }
303
304 static void
305 set_nickname_cb (GObject *source,
306     GAsyncResult *res,
307     gpointer user_data)
308 {
309   GError *error = NULL;
310
311   if (!tp_account_set_nickname_finish (TP_ACCOUNT (source), res, &error))
312     {
313       DEBUG ("Failed to set Account.Nickname: %s", error->message);
314       g_error_free (error);
315     }
316 }
317
318 static gboolean
319 contact_widget_entry_alias_focus_event_cb (GtkEditable *editable,
320     GdkEventFocus *event,
321     EmpathyContactWidget *self)
322 {
323   if (self->priv->contact)
324     {
325       const gchar *alias;
326
327       alias = gtk_entry_get_text (GTK_ENTRY (editable));
328
329       if (empathy_contact_is_user (self->priv->contact))
330         {
331           TpAccount * account;
332           const gchar *current_nickname;
333
334           account = empathy_contact_get_account (self->priv->contact);
335           current_nickname = tp_account_get_nickname (account);
336
337           if (tp_strdiff (current_nickname, alias))
338             {
339               DEBUG ("Set Account.Nickname to %s", alias);
340
341               tp_account_set_nickname_async (account, alias, set_nickname_cb,
342                   NULL);
343             }
344         }
345       else
346         {
347           empathy_contact_set_alias (self->priv->contact, alias);
348         }
349     }
350
351   return FALSE;
352 }
353
354 static void
355 contact_widget_name_notify_cb (EmpathyContactWidget *self)
356 {
357   if (GTK_IS_ENTRY (self->priv->widget_alias))
358       gtk_entry_set_text (GTK_ENTRY (self->priv->widget_alias),
359           empathy_contact_get_alias (self->priv->contact));
360   else
361       gtk_label_set_label (GTK_LABEL (self->priv->widget_alias),
362           empathy_contact_get_alias (self->priv->contact));
363 }
364
365 static void
366 contact_widget_presence_notify_cb (EmpathyContactWidget *self)
367 {
368   const gchar *status;
369   gchar *markup_text = NULL;
370
371   status = empathy_contact_get_status (self->priv->contact);
372   if (status != NULL)
373     markup_text = empathy_add_link_markup (status);
374   gtk_label_set_markup (GTK_LABEL (self->priv->label_status), markup_text);
375   g_free (markup_text);
376
377   gtk_image_set_from_icon_name (GTK_IMAGE (self->priv->image_state),
378       empathy_icon_name_for_contact (self->priv->contact),
379       GTK_ICON_SIZE_BUTTON);
380   gtk_widget_show (self->priv->image_state);
381 }
382
383 static void
384 contact_widget_remove_contact (EmpathyContactWidget *self)
385 {
386   if (self->priv->contact)
387     {
388       g_signal_handlers_disconnect_by_func (self->priv->contact,
389           contact_widget_name_notify_cb, self);
390       g_signal_handlers_disconnect_by_func (self->priv->contact,
391           contact_widget_presence_notify_cb, self);
392
393       g_object_unref (self->priv->contact);
394       self->priv->contact = NULL;
395     }
396 }
397
398 static void contact_widget_change_contact (EmpathyContactWidget *self);
399
400 static void
401 contact_widget_contact_update (EmpathyContactWidget *self)
402 {
403   TpAccount *account = NULL;
404   const gchar *id = NULL;
405
406   /* Connect and get info from new contact */
407   if (self->priv->contact)
408     {
409       g_signal_connect_swapped (self->priv->contact, "notify::name",
410           G_CALLBACK (contact_widget_name_notify_cb), self);
411       g_signal_connect_swapped (self->priv->contact, "notify::presence",
412           G_CALLBACK (contact_widget_presence_notify_cb), self);
413       g_signal_connect_swapped (self->priv->contact,
414           "notify::presence-message",
415           G_CALLBACK (contact_widget_presence_notify_cb), self);
416
417       account = empathy_contact_get_account (self->priv->contact);
418       id = empathy_contact_get_id (self->priv->contact);
419     }
420
421   /* Update account widget */
422   if (account)
423     {
424       g_signal_handlers_block_by_func (self->priv->widget_account,
425                contact_widget_change_contact,
426                self);
427       empathy_account_chooser_set_account (
428           EMPATHY_ACCOUNT_CHOOSER (self->priv->widget_account), account);
429       g_signal_handlers_unblock_by_func (self->priv->widget_account,
430           contact_widget_change_contact, self);
431     }
432
433   /* Update id widget */
434   gtk_entry_set_text (GTK_ENTRY (self->priv->widget_id), id ? id : "");
435
436   /* Update other widgets */
437   if (self->priv->contact)
438     {
439       contact_widget_name_notify_cb (self);
440       contact_widget_presence_notify_cb (self);
441
442       gtk_widget_show (self->priv->label_alias);
443       gtk_widget_show (self->priv->widget_alias);
444       gtk_widget_show (self->priv->widget_avatar);
445
446       gtk_widget_set_visible (self->priv->hbox_presence, TRUE);
447     }
448   else
449     {
450       gtk_widget_hide (self->priv->label_alias);
451       gtk_widget_hide (self->priv->widget_alias);
452       gtk_widget_hide (self->priv->hbox_presence);
453       gtk_widget_hide (self->priv->widget_avatar);
454     }
455 }
456
457 static void
458 contact_widget_set_contact (EmpathyContactWidget *self,
459                             EmpathyContact *contact)
460 {
461   if (contact == self->priv->contact)
462     return;
463
464   contact_widget_remove_contact (self);
465   if (contact)
466     self->priv->contact = g_object_ref (contact);
467
468   /* set the selected account to be the account this contact came from */
469   if (contact && EMPATHY_IS_ACCOUNT_CHOOSER (self->priv->widget_account)) {
470       empathy_account_chooser_set_account (
471                       EMPATHY_ACCOUNT_CHOOSER (self->priv->widget_account),
472                       empathy_contact_get_account (contact));
473   }
474
475   /* Update self for widgets */
476   contact_widget_contact_update (self);
477   contact_widget_groups_update (self);
478   contact_widget_client_update (self);
479 }
480
481 static void
482 contact_widget_got_contact_cb (GObject *source,
483     GAsyncResult *result,
484     gpointer user_data)
485 {
486   EmpathyContactWidget *self = user_data;
487   GError *error = NULL;
488   EmpathyContact *contact;
489
490   contact = empathy_client_factory_dup_contact_by_id_finish (
491       EMPATHY_CLIENT_FACTORY (source), result, &error);
492
493   if (contact == NULL)
494     {
495       DEBUG ("Error: %s", error->message);
496       g_error_free (error);
497       goto out;
498     }
499
500   contact_widget_set_contact (self, contact);
501
502   g_object_unref (contact);
503 out:
504   g_object_unref (self);
505 }
506
507 static void
508 contact_widget_change_contact (EmpathyContactWidget *self)
509 {
510   TpConnection *connection;
511   const gchar *id;
512
513   connection = empathy_account_chooser_get_connection (
514       EMPATHY_ACCOUNT_CHOOSER (self->priv->widget_account));
515   if (!connection)
516       return;
517
518   id = gtk_entry_get_text (GTK_ENTRY (self->priv->widget_id));
519   if (!EMP_STR_EMPTY (id))
520     {
521       EmpathyClientFactory *factory;
522
523       factory = empathy_client_factory_dup ();
524
525       empathy_client_factory_dup_contact_by_id_async (factory, connection,
526           id, contact_widget_got_contact_cb, g_object_ref (self));
527
528       g_object_unref (factory);
529     }
530 }
531
532 static gboolean
533 contact_widget_id_activate_timeout (EmpathyContactWidget *self)
534 {
535   contact_widget_change_contact (self);
536   return FALSE;
537 }
538
539 static void
540 contact_widget_id_changed_cb (GtkEntry *entry,
541                               EmpathyContactWidget *self)
542 {
543   if (self->priv->widget_id_timeout != 0)
544     {
545       g_source_remove (self->priv->widget_id_timeout);
546     }
547
548   self->priv->widget_id_timeout =
549     g_timeout_add_seconds (ID_CHANGED_TIMEOUT,
550         (GSourceFunc) contact_widget_id_activate_timeout, self);
551 }
552
553 static gboolean
554 contact_widget_id_focus_out_cb (GtkWidget *widget,
555                                 GdkEventFocus *event,
556                                 EmpathyContactWidget *self)
557 {
558   contact_widget_change_contact (self);
559   return FALSE;
560 }
561
562 static void
563 contact_widget_contact_setup (EmpathyContactWidget *self)
564 {
565   self->priv->label_status = gtk_label_new ("");
566   gtk_label_set_line_wrap_mode (GTK_LABEL (self->priv->label_status),
567                                 PANGO_WRAP_WORD_CHAR);
568   gtk_label_set_line_wrap (GTK_LABEL (self->priv->label_status),
569                            TRUE);
570   gtk_misc_set_alignment (GTK_MISC (self->priv->label_status), 0, 0.5);
571
572   gtk_label_set_selectable (GTK_LABEL (self->priv->label_status), TRUE);
573
574   gtk_box_pack_start (GTK_BOX (self->priv->hbox_presence),
575         self->priv->label_status, TRUE, TRUE, 0);
576   gtk_widget_show (self->priv->label_status);
577
578   /* Setup account chooser */
579   self->priv->widget_account = empathy_account_chooser_new ();
580   g_signal_connect_swapped (self->priv->widget_account, "changed",
581         G_CALLBACK (contact_widget_change_contact),
582         self);
583   gtk_grid_attach (GTK_GRID (self->priv->grid_contact),
584       self->priv->widget_account,
585       2, 0, 1, 1);
586   gtk_widget_show (self->priv->widget_account);
587
588   /* Set up avatar display */
589   self->priv->widget_avatar = empathy_avatar_image_new ();
590
591   g_signal_connect (self->priv->widget_avatar, "popup-menu",
592       G_CALLBACK (widget_avatar_popup_menu_cb), self);
593   g_signal_connect (self->priv->widget_avatar, "button-press-event",
594       G_CALLBACK (widget_avatar_button_press_event_cb), self);
595   gtk_box_pack_start (GTK_BOX (self->priv->vbox_avatar),
596           self->priv->widget_avatar,
597           FALSE, FALSE,
598           6);
599   gtk_widget_show (self->priv->widget_avatar);
600
601   /* Setup id entry */
602   self->priv->widget_id = gtk_entry_new ();
603   g_signal_connect (self->priv->widget_id, "focus-out-event",
604         G_CALLBACK (contact_widget_id_focus_out_cb),
605         self);
606   g_signal_connect (self->priv->widget_id, "changed",
607         G_CALLBACK (contact_widget_id_changed_cb),
608         self);
609   gtk_grid_attach (GTK_GRID (self->priv->grid_contact), self->priv->widget_id,
610       2, 1, 1, 1);
611   gtk_widget_set_hexpand (self->priv->widget_id, TRUE);
612
613   gtk_widget_show (self->priv->widget_id);
614
615   /* Setup alias entry */
616   self->priv->widget_alias = gtk_entry_new ();
617
618   g_signal_connect (self->priv->widget_alias, "focus-out-event",
619         G_CALLBACK (contact_widget_entry_alias_focus_event_cb),
620         self);
621
622   /* Make return activate the window default (the Close button) */
623   gtk_entry_set_activates_default (GTK_ENTRY (self->priv->widget_alias),
624       TRUE);
625
626   gtk_grid_attach (GTK_GRID (self->priv->grid_contact),
627       self->priv->widget_alias, 2, 2, 1, 1);
628   gtk_widget_set_hexpand (self->priv->widget_alias, TRUE);
629
630   gtk_label_set_selectable (GTK_LABEL (self->priv->label_status), FALSE);
631   gtk_widget_show (self->priv->widget_alias);
632 }
633
634 static void
635 empathy_contact_widget_finalize (GObject *object)
636 {
637   EmpathyContactWidget *self = EMPATHY_CONTACT_WIDGET (object);
638   void (*chain_up) (GObject *) =
639       ((GObjectClass *) empathy_contact_widget_parent_class)->finalize;
640
641   contact_widget_remove_contact (self);
642
643   if (self->priv->widget_id_timeout != 0)
644     {
645       g_source_remove (self->priv->widget_id_timeout);
646     }
647
648
649   if (chain_up != NULL)
650     chain_up (object);
651 }
652
653 /**
654  * empathy_contact_widget_new:
655  * @contact: an #EmpathyContact
656  *
657  * Creates a new #EmpathyContactWidget.
658  *
659  * Return value: a new #EmpathyContactWidget
660  */
661 GtkWidget *
662 empathy_contact_widget_new (EmpathyContact *contact)
663 {
664   EmpathyContactWidget *self;
665   gchar *filename;
666   GtkWidget *main_vbox;
667   GtkBuilder *gui;
668
669   g_return_val_if_fail (contact == NULL || EMPATHY_IS_CONTACT (contact), NULL);
670
671   self = g_object_new (EMPATHY_TYPE_CONTACT_WIDGET, NULL);
672
673   filename = empathy_file_lookup ("empathy-contact-widget.ui",
674       "libempathy-gtk");
675   gui = empathy_builder_get_file (filename,
676        "vbox_contact_widget", &main_vbox,
677        "hbox_presence", &self->priv->hbox_presence,
678        "label_alias", &self->priv->label_alias,
679        "image_state", &self->priv->image_state,
680        "grid_contact", &self->priv->grid_contact,
681        "vbox_avatar", &self->priv->vbox_avatar,
682        "groups_widget", &self->priv->groups_widget,
683        "vbox_client", &self->priv->vbox_client,
684        "grid_client", &self->priv->grid_client,
685        "hbox_client_requested", &self->priv->hbox_client_requested,
686        "label_details", &self->priv->label_details,
687        "label_left_account", &self->priv->label_left_account,
688        NULL);
689   g_free (filename);
690
691   gtk_container_add (GTK_CONTAINER (self), main_vbox);
692   gtk_widget_show (GTK_WIDGET (main_vbox));
693
694   /* Create widgets */
695   contact_widget_contact_setup (self);
696   contact_widget_client_setup (self);
697
698   gtk_widget_hide (self->priv->label_details);
699
700   if (contact != NULL)
701     contact_widget_set_contact (self, contact);
702   else
703     contact_widget_change_contact (self);
704
705   g_object_unref (gui);
706
707   return GTK_WIDGET (self);
708 }
709
710 /**
711  * empathy_contact_widget_get_contact:
712  * @widget: an #EmpathyContactWidget
713  *
714  * Get the #EmpathyContact related with the #EmpathyContactWidget @widget.
715  *
716  * Returns: the #EmpathyContact associated with @widget
717  */
718 EmpathyContact *
719 empathy_contact_widget_get_contact (GtkWidget *widget)
720 {
721   EmpathyContactWidget *self = EMPATHY_CONTACT_WIDGET (widget);
722
723   return self->priv->contact;
724 }
725
726 const gchar *
727 empathy_contact_widget_get_alias (GtkWidget *widget)
728 {
729   EmpathyContactWidget *self = EMPATHY_CONTACT_WIDGET (widget);
730
731   return gtk_entry_get_text (GTK_ENTRY (self->priv->widget_alias));
732 }
733
734 /**
735  * empathy_contact_widget_set_contact:
736  * @widget: an #EmpathyContactWidget
737  * @contact: a different #EmpathyContact
738  *
739  * Change the #EmpathyContact related with the #EmpathyContactWidget @widget.
740  */
741 void
742 empathy_contact_widget_set_contact (GtkWidget *widget,
743                                     EmpathyContact *contact)
744 {
745   EmpathyContactWidget *self = EMPATHY_CONTACT_WIDGET (widget);
746
747   g_return_if_fail (EMPATHY_IS_CONTACT (contact));
748
749   contact_widget_set_contact (self, contact);
750 }
751
752 /**
753  * empathy_contact_widget_set_account_filter:
754  * @widget: an #EmpathyContactWidget
755  * @filter: a #EmpathyAccountChooserFilterFunc
756  * @user_data: user data to pass to @filter, or %NULL
757  *
758  * Set a filter on the #EmpathyAccountChooser included in the
759  * #EmpathyContactWidget.
760  */
761 void
762 empathy_contact_widget_set_account_filter (
763     GtkWidget *widget,
764     EmpathyAccountChooserFilterFunc filter,
765     gpointer user_data)
766 {
767   EmpathyContactWidget *self = EMPATHY_CONTACT_WIDGET (widget);
768   EmpathyAccountChooser *chooser;
769
770   chooser = EMPATHY_ACCOUNT_CHOOSER (self->priv->widget_account);
771   if (chooser)
772       empathy_account_chooser_set_filter (chooser, filter, user_data);
773 }
774
775 static void
776 empathy_contact_widget_class_init (
777     EmpathyContactWidgetClass *klass)
778 {
779   GObjectClass *oclass = G_OBJECT_CLASS (klass);
780
781   oclass->finalize = empathy_contact_widget_finalize;
782
783   g_type_class_add_private (klass, sizeof (EmpathyContactWidgetPriv));
784 }
785
786 static void
787 empathy_contact_widget_init (EmpathyContactWidget *self)
788 {
789   self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self,
790       EMPATHY_TYPE_CONTACT_WIDGET, EmpathyContactWidgetPriv);
791 }