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