]> git.0d.be Git - empathy.git/blob - libempathy-gtk/empathy-contact-menu.c
Add 'Block Contact' to empathy-contact-menu
[empathy.git] / libempathy-gtk / empathy-contact-menu.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3  * Copyright (C) 2008 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
26 #include <glib/gi18n-lib.h>
27 #include <gtk/gtk.h>
28 #include <telepathy-logger/log-manager.h>
29
30 #include <libempathy/empathy-contact-manager.h>
31 #include <libempathy/empathy-dispatcher.h>
32 #include <libempathy/empathy-utils.h>
33 #include <libempathy/empathy-chatroom-manager.h>
34 #include <libempathy/empathy-contact-manager.h>
35
36 #include "empathy-contact-menu.h"
37 #include "empathy-images.h"
38 #include "empathy-log-window.h"
39 #include "empathy-contact-dialogs.h"
40 #include "empathy-ui-utils.h"
41 #include "empathy-share-my-desktop.h"
42
43 static GtkWidget *empathy_contact_block_menu_item_new (EmpathyContact *);
44
45 GtkWidget *
46 empathy_contact_menu_new (EmpathyContact             *contact,
47                           EmpathyContactFeatureFlags  features)
48 {
49         GtkWidget    *menu;
50         GtkMenuShell *shell;
51         GtkWidget    *item;
52
53         g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL);
54
55         if (features == EMPATHY_CONTACT_FEATURE_NONE) {
56                 return NULL;
57         }
58
59         menu = gtk_menu_new ();
60         shell = GTK_MENU_SHELL (menu);
61
62         /* Add Contact */
63         item = empathy_contact_add_menu_item_new (contact);
64         if (item) {
65                 gtk_menu_shell_append (shell, item);
66                 gtk_widget_show (item);
67         }
68
69         /* Chat */
70         if (features & EMPATHY_CONTACT_FEATURE_CHAT) {
71                 item = empathy_contact_chat_menu_item_new (contact);
72                 gtk_menu_shell_append (shell, item);
73                 gtk_widget_show (item);
74         }
75
76         if (features & EMPATHY_CONTACT_FEATURE_CALL) {
77                 /* Audio Call */
78                 item = empathy_contact_audio_call_menu_item_new (contact);
79                 gtk_menu_shell_append (shell, item);
80                 gtk_widget_show (item);
81
82                 /* Video Call */
83                 item = empathy_contact_video_call_menu_item_new (contact);
84                 gtk_menu_shell_append (shell, item);
85                 gtk_widget_show (item);
86         }
87
88         /* Log */
89         if (features & EMPATHY_CONTACT_FEATURE_LOG) {
90                 item = empathy_contact_log_menu_item_new (contact);
91                 gtk_menu_shell_append (shell, item);
92                 gtk_widget_show (item);
93         }
94
95         /* Invite */
96         item = empathy_contact_invite_menu_item_new (contact);
97         gtk_menu_shell_append (shell, item);
98         gtk_widget_show (item);
99
100         /* File transfer */
101         if (features & EMPATHY_CONTACT_FEATURE_FT) {
102                 item = empathy_contact_file_transfer_menu_item_new (contact);
103                 gtk_menu_shell_append (shell, item);
104                 gtk_widget_show (item);
105         }
106
107         /* Share my desktop */
108         /* FIXME we should add the "Share my desktop" menu item if Vino is
109         a registered handler in MC5 */
110         item = empathy_contact_share_my_desktop_menu_item_new (contact);
111         gtk_menu_shell_append (shell, item);
112         gtk_widget_show (item);
113
114         /* Separator */
115         if (features & (EMPATHY_CONTACT_FEATURE_EDIT |
116                         EMPATHY_CONTACT_FEATURE_INFO |
117                         EMPATHY_CONTACT_FEATURE_FAVOURITE)) {
118                 item = gtk_separator_menu_item_new ();
119                 gtk_menu_shell_append (shell, item);
120                 gtk_widget_show (item);
121         }
122
123         /* Edit */
124         if (features & EMPATHY_CONTACT_FEATURE_EDIT) {
125                 item = empathy_contact_edit_menu_item_new (contact);
126                 gtk_menu_shell_append (shell, item);
127                 gtk_widget_show (item);
128         }
129
130         /* Info */
131         if (features & EMPATHY_CONTACT_FEATURE_INFO) {
132                 item = empathy_contact_info_menu_item_new (contact);
133                 gtk_menu_shell_append (shell, item);
134                 gtk_widget_show (item);
135         }
136
137         /* Favorite checkbox */
138         if (features & EMPATHY_CONTACT_FEATURE_FAVOURITE) {
139                 item = empathy_contact_favourite_menu_item_new (contact);
140                 gtk_menu_shell_append (shell, item);
141                 gtk_widget_show (item);
142         }
143
144         /* Separator & Block */
145         if (features & EMPATHY_CONTACT_FEATURE_BLOCK &&
146             (item = empathy_contact_block_menu_item_new (contact)) != NULL) {
147                 GtkWidget *sep;
148
149                 sep = gtk_separator_menu_item_new ();
150                 gtk_menu_shell_append (shell, sep);
151                 gtk_widget_show (sep);
152
153                 gtk_menu_shell_append (shell, item);
154                 gtk_widget_show (item);
155         }
156
157         return menu;
158 }
159
160 static void
161 empathy_contact_add_menu_item_activated (GtkMenuItem *item,
162         EmpathyContact *contact)
163 {
164         GtkWidget *toplevel;
165
166         toplevel = gtk_widget_get_toplevel (GTK_WIDGET (item));
167         if (!gtk_widget_is_toplevel (toplevel) || !GTK_IS_WINDOW (toplevel)) {
168                 toplevel = NULL;
169         }
170
171         empathy_new_contact_dialog_show_with_contact (GTK_WINDOW (toplevel),
172                                                       contact);
173 }
174
175 GtkWidget *
176 empathy_contact_add_menu_item_new (EmpathyContact *contact)
177 {
178         GtkWidget *item;
179         GtkWidget *image;
180         EmpathyContactManager *manager;
181         TpConnection *connection;
182         GList *l, *members;
183         gboolean found = FALSE;
184         EmpathyContactListFlags flags;
185
186         g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL);
187
188         if (!empathy_contact_manager_initialized ()) {
189                 return NULL;
190         }
191
192         manager = empathy_contact_manager_dup_singleton ();
193         connection = empathy_contact_get_connection (contact);
194
195         flags = empathy_contact_manager_get_flags_for_connection (manager,
196                         connection);
197
198         if (!(flags & EMPATHY_CONTACT_LIST_CAN_ADD)) {
199                 return NULL;
200         }
201
202         members = empathy_contact_list_get_members (EMPATHY_CONTACT_LIST (manager));
203         for (l = members; l; l = l->next) {
204                 if (!found && empathy_contact_equal (l->data, contact)) {
205                         found = TRUE;
206                         /* we keep iterating so that we don't leak contact
207                          * refs */
208                 }
209
210                 g_object_unref (l->data);
211         }
212         g_list_free (members);
213         g_object_unref (manager);
214
215         if (found) {
216                 return NULL;
217         }
218
219         item = gtk_image_menu_item_new_with_mnemonic (_("_Add Contact…"));
220         image = gtk_image_new_from_icon_name (GTK_STOCK_ADD,
221                                               GTK_ICON_SIZE_MENU);
222         gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
223
224         g_signal_connect (item, "activate",
225                         G_CALLBACK (empathy_contact_add_menu_item_activated),
226                         contact);
227
228         return item;
229 }
230
231 static void
232 empathy_contact_block_menu_item_toggled (GtkCheckMenuItem *item,
233                                          EmpathyContact   *contact)
234 {
235         EmpathyContactManager *manager;
236         gboolean blocked;
237
238         manager = empathy_contact_manager_dup_singleton ();
239         blocked = gtk_check_menu_item_get_active (item);
240
241         empathy_contact_list_set_blocked (EMPATHY_CONTACT_LIST (manager),
242                                           contact, blocked);
243
244         g_object_unref (manager);
245 }
246
247 static GtkWidget *
248 empathy_contact_block_menu_item_new (EmpathyContact *contact)
249 {
250         GtkWidget *item;
251         EmpathyContactManager *manager;
252         TpConnection *connection;
253         EmpathyContactListFlags flags;
254         gboolean blocked;
255
256         g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL);
257
258         if (!empathy_contact_manager_initialized ()) {
259                 return NULL;
260         }
261
262         manager = empathy_contact_manager_dup_singleton ();
263         connection = empathy_contact_get_connection (contact);
264
265         flags = empathy_contact_manager_get_flags_for_connection (manager,
266                         connection);
267
268         if (!(flags & EMPATHY_CONTACT_LIST_CAN_BLOCK)) {
269                 return NULL;
270         }
271
272         item = gtk_check_menu_item_new_with_mnemonic (_("_Block Contact"));
273         /* FIXME: this doesn't always get updated immediately */
274         blocked = empathy_contact_list_get_blocked (
275                         EMPATHY_CONTACT_LIST (manager),
276                         contact);
277
278         gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), blocked);
279
280         g_signal_connect (item, "toggled",
281                         G_CALLBACK (empathy_contact_block_menu_item_toggled),
282                         contact);
283
284         return item;
285 }
286
287 static void
288 empathy_contact_chat_menu_item_activated (GtkMenuItem *item,
289         EmpathyContact *contact)
290 {
291   empathy_dispatcher_chat_with_contact (contact, gtk_get_current_event_time ());
292 }
293
294 GtkWidget *
295 empathy_contact_chat_menu_item_new (EmpathyContact *contact)
296 {
297         GtkWidget *item;
298         GtkWidget *image;
299
300         g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL);
301
302         item = gtk_image_menu_item_new_with_mnemonic (_("_Chat"));
303         image = gtk_image_new_from_icon_name (EMPATHY_IMAGE_MESSAGE,
304                                               GTK_ICON_SIZE_MENU);
305         gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
306         gtk_widget_set_sensitive (item, !empathy_contact_is_user (contact));
307         gtk_widget_show (image);
308
309         g_signal_connect (item, "activate",
310                                   G_CALLBACK (empathy_contact_chat_menu_item_activated),
311                                   contact);
312
313         return item;
314 }
315
316 static void
317 empathy_contact_audio_call_menu_item_activated (GtkMenuItem *item,
318         EmpathyContact *contact)
319 {
320
321         empathy_call_new_with_streams (contact, TRUE, FALSE,
322                 gtk_get_current_event_time ());
323 }
324
325 GtkWidget *
326 empathy_contact_audio_call_menu_item_new (EmpathyContact *contact)
327 {
328         GtkWidget *item;
329         GtkWidget *image;
330
331         g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL);
332
333         item = gtk_image_menu_item_new_with_mnemonic (C_("menu item", "_Audio Call"));
334         image = gtk_image_new_from_icon_name (EMPATHY_IMAGE_VOIP,
335                                               GTK_ICON_SIZE_MENU);
336         gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
337         gtk_widget_set_sensitive (item, empathy_contact_can_voip_audio (contact) &&
338                                         !empathy_contact_is_user (contact));
339         gtk_widget_show (image);
340
341         g_signal_connect (item, "activate",
342                                   G_CALLBACK (empathy_contact_audio_call_menu_item_activated),
343                                   contact);
344
345         return item;
346 }
347
348 static void
349 empathy_contact_video_call_menu_item_activated (GtkMenuItem *item,
350         EmpathyContact *contact)
351 {
352         empathy_call_new_with_streams (contact, TRUE, TRUE,
353                 gtk_get_current_event_time ());
354 }
355
356 GtkWidget *
357 empathy_contact_video_call_menu_item_new (EmpathyContact *contact)
358 {
359         GtkWidget *item;
360         GtkWidget *image;
361
362         g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL);
363
364         item = gtk_image_menu_item_new_with_mnemonic (C_("menu item", "_Video Call"));
365         image = gtk_image_new_from_icon_name (EMPATHY_IMAGE_VIDEO_CALL,
366                                               GTK_ICON_SIZE_MENU);
367         gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
368         gtk_widget_set_sensitive (item, empathy_contact_can_voip_video (contact) &&
369                                         !empathy_contact_is_user (contact));
370         gtk_widget_show (image);
371
372         g_signal_connect (item, "activate",
373                                   G_CALLBACK (empathy_contact_video_call_menu_item_activated),
374                                   contact);
375
376         return item;
377 }
378
379 static void
380 contact_log_menu_item_activate_cb (EmpathyContact *contact)
381 {
382         empathy_log_window_show (empathy_contact_get_account (contact),
383                                  empathy_contact_get_id (contact),
384                                  FALSE, NULL);
385 }
386
387 GtkWidget *
388 empathy_contact_log_menu_item_new (EmpathyContact *contact)
389 {
390         TplLogManager     *manager;
391         TplEntity         *entity;
392         gboolean           have_log;
393         GtkWidget         *item;
394         GtkWidget         *image;
395
396         g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL);
397
398         manager = tpl_log_manager_dup_singleton ();
399         entity = tpl_entity_new_from_tp_contact (empathy_contact_get_tp_contact (contact),
400                                                  TPL_ENTITY_CONTACT);
401
402         have_log = tpl_log_manager_exists (manager,
403                                            empathy_contact_get_account (contact),
404                                            entity,
405                                            TPL_EVENT_MASK_TEXT);
406
407         g_object_unref (entity);
408         g_object_unref (manager);
409
410         item = gtk_image_menu_item_new_with_mnemonic (_("_Previous Conversations"));
411         image = gtk_image_new_from_icon_name (EMPATHY_IMAGE_LOG,
412                                               GTK_ICON_SIZE_MENU);
413         gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
414         gtk_widget_set_sensitive (item, have_log);
415         gtk_widget_show (image);
416
417         g_signal_connect_swapped (item, "activate",
418                                   G_CALLBACK (contact_log_menu_item_activate_cb),
419                                   contact);
420
421         return item;
422 }
423
424 GtkWidget *
425 empathy_contact_file_transfer_menu_item_new (EmpathyContact *contact)
426 {
427         GtkWidget         *item;
428         GtkWidget         *image;
429
430         g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL);
431
432         item = gtk_image_menu_item_new_with_mnemonic (_("Send File"));
433         image = gtk_image_new_from_icon_name (EMPATHY_IMAGE_DOCUMENT_SEND,
434                                               GTK_ICON_SIZE_MENU);
435         gtk_widget_set_sensitive (item, empathy_contact_can_send_files (contact) &&
436                                         !empathy_contact_is_user (contact));
437         gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
438         gtk_widget_show (image);
439
440         g_signal_connect_swapped (item, "activate",
441                                   G_CALLBACK (empathy_send_file_with_file_chooser),
442                                   contact);
443
444         return item;
445 }
446
447 GtkWidget *
448 empathy_contact_share_my_desktop_menu_item_new (EmpathyContact *contact)
449 {
450         GtkWidget         *item;
451         GtkWidget         *image;
452
453         g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL);
454
455         item = gtk_image_menu_item_new_with_mnemonic (_("Share My Desktop"));
456         image = gtk_image_new_from_icon_name (GTK_STOCK_NETWORK,
457                                               GTK_ICON_SIZE_MENU);
458         gtk_widget_set_sensitive (item, empathy_contact_can_use_rfb_stream_tube (
459                 contact));
460         gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
461         gtk_widget_show (image);
462
463         g_signal_connect_swapped (item, "activate",
464                                   G_CALLBACK (empathy_share_my_desktop_share_with_contact),
465                                   contact);
466
467         return item;
468 }
469
470 static void
471 favourite_menu_item_toggled_cb (GtkCheckMenuItem *item,
472         EmpathyContact *contact)
473 {
474         EmpathyContactManager *manager;
475         EmpathyContactList *list;
476
477         manager = empathy_contact_manager_dup_singleton ();
478         list = EMPATHY_CONTACT_LIST (manager);
479
480         if (gtk_check_menu_item_get_active (item)) {
481                 empathy_contact_list_add_to_favourites (list, contact);
482         } else {
483                 empathy_contact_list_remove_from_favourites (list, contact);
484         }
485
486         g_object_unref (manager);
487 }
488
489 GtkWidget *
490 empathy_contact_favourite_menu_item_new (EmpathyContact *contact)
491 {
492         GtkWidget *item;
493         EmpathyContactManager *manager;
494
495         item = gtk_check_menu_item_new_with_label (_("Favorite"));
496
497         manager = empathy_contact_manager_dup_singleton ();
498         gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item),
499                 empathy_contact_list_is_favourite (EMPATHY_CONTACT_LIST (manager),
500                                                    contact));
501
502         g_signal_connect (item, "toggled",
503                           G_CALLBACK (favourite_menu_item_toggled_cb),
504                           contact);
505
506         g_object_unref (manager);
507         return item;
508 }
509
510 static void
511 contact_info_menu_item_activate_cb (EmpathyContact *contact)
512 {
513         empathy_contact_information_dialog_show (contact, NULL);
514 }
515
516 GtkWidget *
517 empathy_contact_info_menu_item_new (EmpathyContact *contact)
518 {
519         GtkWidget *item;
520         GtkWidget *image;
521
522         g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL);
523
524         item = gtk_image_menu_item_new_with_mnemonic (_("Infor_mation"));
525         image = gtk_image_new_from_icon_name (EMPATHY_IMAGE_CONTACT_INFORMATION,
526                                               GTK_ICON_SIZE_MENU);
527         gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
528         gtk_widget_show (image);
529
530         g_signal_connect_swapped (item, "activate",
531                                   G_CALLBACK (contact_info_menu_item_activate_cb),
532                                   contact);
533
534         return item;
535 }
536
537 static void
538 contact_edit_menu_item_activate_cb (EmpathyContact *contact)
539 {
540         empathy_contact_edit_dialog_show (contact, NULL);
541 }
542
543 GtkWidget *
544 empathy_contact_edit_menu_item_new (EmpathyContact *contact)
545 {
546         EmpathyContactManager *manager;
547         GtkWidget *item;
548         GtkWidget *image;
549         gboolean enable = FALSE;
550
551         g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL);
552
553         if (empathy_contact_manager_initialized ()) {
554                 TpConnection *connection;
555                 EmpathyContactListFlags flags;
556
557                 manager = empathy_contact_manager_dup_singleton ();
558                 connection = empathy_contact_get_connection (contact);
559                 flags = empathy_contact_manager_get_flags_for_connection (
560                                 manager, connection);
561
562                 enable = (flags & EMPATHY_CONTACT_LIST_CAN_ALIAS ||
563                           flags & EMPATHY_CONTACT_LIST_CAN_GROUP);
564
565                 g_object_unref (manager);
566         }
567
568         item = gtk_image_menu_item_new_with_mnemonic (
569                                                      C_("Edit contact (contextual menu)",
570                                                         "_Edit"));
571         image = gtk_image_new_from_icon_name (GTK_STOCK_EDIT,
572                                               GTK_ICON_SIZE_MENU);
573         gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
574         gtk_widget_show (image);
575
576         gtk_widget_set_sensitive (item, enable);
577
578         g_signal_connect_swapped (item, "activate",
579                                   G_CALLBACK (contact_edit_menu_item_activate_cb),
580                                   contact);
581
582         return item;
583 }
584
585 typedef struct  {
586         EmpathyContact *contact;
587         EmpathyChatroom *chatroom;
588 } RoomSubMenuData;
589
590 static RoomSubMenuData *
591 room_sub_menu_data_new (EmpathyContact *contact,
592                         EmpathyChatroom *chatroom)
593 {
594         RoomSubMenuData *data;
595
596         data = g_slice_new (RoomSubMenuData);
597         data->contact = g_object_ref (contact);
598         data->chatroom = g_object_ref (chatroom);
599         return data;
600 }
601
602 static void
603 room_sub_menu_data_free (RoomSubMenuData *data)
604 {
605         g_object_unref (data->contact);
606         g_object_unref (data->chatroom);
607         g_slice_free (RoomSubMenuData, data);
608 }
609
610 static void
611 room_sub_menu_activate_cb (GtkWidget *item,
612                            RoomSubMenuData *data)
613 {
614         EmpathyTpChat *chat;
615
616         chat = empathy_chatroom_get_tp_chat (data->chatroom);
617         if (chat == NULL) {
618                 /* channel was invalidated. Ignoring */
619                 return;
620         }
621
622         /* send invitation */
623         empathy_contact_list_add (EMPATHY_CONTACT_LIST (chat), data->contact,
624                 _("Inviting you to this room"));
625 }
626
627 static GtkWidget *
628 create_room_sub_menu (EmpathyContact *contact,
629                       EmpathyChatroom *chatroom)
630 {
631         GtkWidget *item;
632         RoomSubMenuData *data;
633
634         item = gtk_menu_item_new_with_label (empathy_chatroom_get_name (chatroom));
635         data = room_sub_menu_data_new (contact, chatroom);
636         g_signal_connect_data (item, "activate",
637                                G_CALLBACK (room_sub_menu_activate_cb), data,
638                                (GClosureNotify) room_sub_menu_data_free, 0);
639
640         return item;
641 }
642
643 GtkWidget *
644 empathy_contact_invite_menu_item_new (EmpathyContact *contact)
645 {
646         GtkWidget *item;
647         GtkWidget *image;
648         GtkWidget *room_item;
649         EmpathyChatroomManager *mgr;
650         GList *rooms, *l;
651         GtkWidget *submenu = NULL;
652
653         g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL);
654
655         item = gtk_image_menu_item_new_with_mnemonic (_("_Invite to Chat Room"));
656         image = gtk_image_new_from_icon_name (EMPATHY_IMAGE_GROUP_MESSAGE,
657                                               GTK_ICON_SIZE_MENU);
658         gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
659
660         if (empathy_contact_is_user (contact)) {
661                 gtk_widget_set_sensitive (item, FALSE);
662                 gtk_widget_show (image);
663                 return item;
664         }
665
666         mgr = empathy_chatroom_manager_dup_singleton (NULL);
667         rooms = empathy_chatroom_manager_get_chatrooms (mgr,
668                 empathy_contact_get_account (contact));
669
670         for (l = rooms; l != NULL; l = g_list_next (l)) {
671                 EmpathyChatroom *chatroom = l->data;
672
673                 if (empathy_chatroom_get_tp_chat (chatroom) != NULL) {
674                         if (G_UNLIKELY (submenu == NULL))
675                                 submenu = gtk_menu_new ();
676
677                         room_item = create_room_sub_menu (contact, chatroom);
678                         gtk_menu_shell_append ((GtkMenuShell *) submenu, room_item);
679                         gtk_widget_show (room_item);
680                 }
681         }
682
683         if (submenu) {
684                 gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), submenu);
685         } else {
686                 gtk_widget_set_sensitive (item, FALSE);
687         }
688
689         gtk_widget_show (image);
690
691         g_object_unref (mgr);
692         g_list_free (rooms);
693
694         return item;
695 }
696