1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 * Copyright (C) 2008-2010 Collabora Ltd.
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.
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.
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
19 * Authors: Xavier Claessens <xclaesse@gmail.com>
20 * Travis Reitter <travis.reitter@collabora.co.uk>
27 #include <glib/gi18n-lib.h>
29 #include <telepathy-glib/util.h>
30 #include <telepathy-logger/log-manager.h>
31 #include <folks/folks.h>
32 #include <folks/folks-telepathy.h>
34 #include <libempathy/empathy-call-factory.h>
35 #include <libempathy/empathy-dispatcher.h>
36 #include <libempathy/empathy-contact-manager.h>
37 #include <libempathy/empathy-individual-manager.h>
38 #include <libempathy/empathy-chatroom-manager.h>
39 #include <libempathy/empathy-utils.h>
41 #include "empathy-individual-menu.h"
42 #include "empathy-images.h"
43 #include "empathy-log-window.h"
44 #include "empathy-contact-dialogs.h"
45 #include "empathy-individual-dialogs.h"
46 #include "empathy-individual-edit-dialog.h"
47 #include "empathy-individual-information-dialog.h"
48 #include "empathy-ui-utils.h"
49 #include "empathy-share-my-desktop.h"
50 #include "empathy-linking-dialog.h"
53 individual_menu_add_personas (GtkMenuShell
*menu
,
54 FolksIndividual
*individual
,
55 EmpathyIndividualFeatureFlags features
)
59 guint persona_count
= 0;
61 g_return_if_fail (GTK_IS_MENU (menu
));
62 g_return_if_fail (FOLKS_IS_INDIVIDUAL (individual
));
63 g_return_if_fail (empathy_folks_individual_contains_contact (individual
));
65 personas
= folks_individual_get_personas (individual
);
67 /* Make sure we've got enough valid entries for these menu items to add
69 for (l
= personas
; l
!= NULL
; l
= l
->next
)
71 if (!TPF_IS_PERSONA (l
->data
))
77 /* return early if these entries would add nothing beyond the "quick" items */
78 if (persona_count
<= 1)
81 /* add a separator before the list of personas */
82 item
= gtk_separator_menu_item_new ();
83 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), item
);
84 gtk_widget_show (item
);
86 personas
= folks_individual_get_personas (individual
);
87 for (l
= personas
; l
!= NULL
; l
= l
->next
)
90 GtkWidget
*contact_item
;
91 GtkWidget
*contact_submenu
;
92 TpContact
*tp_contact
;
93 EmpathyContact
*contact
;
94 TpfPersona
*persona
= l
->data
;
96 FolksPersonaStore
*store
;
100 if (!TPF_IS_PERSONA (persona
))
103 tp_contact
= tpf_persona_get_contact (persona
);
104 contact
= empathy_contact_dup_from_tp_contact (tp_contact
);
106 store
= folks_persona_get_store (FOLKS_PERSONA (persona
));
107 account
= folks_persona_store_get_display_name (store
);
108 label
= g_strdup_printf (_("%s (%s)"),
109 folks_persona_get_display_id (FOLKS_PERSONA (persona
)), account
);
111 contact_item
= gtk_image_menu_item_new_with_label (label
);
112 contact_submenu
= gtk_menu_new ();
113 gtk_menu_item_set_submenu (GTK_MENU_ITEM (contact_item
), contact_submenu
);
114 image
= gtk_image_new_from_icon_name (
115 empathy_icon_name_for_contact (contact
), GTK_ICON_SIZE_MENU
);
116 gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (contact_item
), image
);
117 gtk_widget_show (image
);
120 if (features
& EMPATHY_INDIVIDUAL_FEATURE_CHAT
)
122 action
= empathy_individual_chat_menu_item_new (NULL
, contact
);
123 gtk_menu_shell_append (GTK_MENU_SHELL (contact_submenu
), action
);
124 gtk_widget_show (action
);
127 if (features
& EMPATHY_INDIVIDUAL_FEATURE_CALL
)
130 action
= empathy_individual_audio_call_menu_item_new (NULL
, contact
);
131 gtk_menu_shell_append (GTK_MENU_SHELL (contact_submenu
), action
);
132 gtk_widget_show (action
);
135 action
= empathy_individual_video_call_menu_item_new (NULL
, contact
);
136 gtk_menu_shell_append (GTK_MENU_SHELL (contact_submenu
), action
);
137 gtk_widget_show (action
);
141 if (features
& EMPATHY_INDIVIDUAL_FEATURE_LOG
)
143 action
= empathy_individual_log_menu_item_new (NULL
, contact
);
144 gtk_menu_shell_append (GTK_MENU_SHELL (contact_submenu
), action
);
145 gtk_widget_show (action
);
149 action
= empathy_individual_invite_menu_item_new (NULL
, contact
);
150 gtk_menu_shell_append (GTK_MENU_SHELL (contact_submenu
), action
);
151 gtk_widget_show (action
);
154 action
= empathy_individual_file_transfer_menu_item_new (NULL
, contact
);
155 gtk_menu_shell_append (GTK_MENU_SHELL (contact_submenu
), action
);
156 gtk_widget_show (action
);
158 /* Share my desktop */
159 action
= empathy_individual_share_my_desktop_menu_item_new (NULL
,
161 gtk_menu_shell_append (GTK_MENU_SHELL (contact_submenu
), action
);
162 gtk_widget_show (action
);
164 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), contact_item
);
165 gtk_widget_show (contact_item
);
168 g_object_unref (contact
);
173 empathy_individual_menu_new (FolksIndividual
*individual
,
174 EmpathyIndividualFeatureFlags features
)
180 g_return_val_if_fail (FOLKS_IS_INDIVIDUAL (individual
), NULL
);
182 if (features
== EMPATHY_INDIVIDUAL_FEATURE_NONE
)
185 menu
= gtk_menu_new ();
186 shell
= GTK_MENU_SHELL (menu
);
189 item
= empathy_individual_add_menu_item_new (individual
);
192 gtk_menu_shell_append (shell
, item
);
193 gtk_widget_show (item
);
197 if (features
& EMPATHY_INDIVIDUAL_FEATURE_CHAT
)
199 item
= empathy_individual_chat_menu_item_new (individual
, NULL
);
202 gtk_menu_shell_append (shell
, item
);
203 gtk_widget_show (item
);
207 if (features
& EMPATHY_INDIVIDUAL_FEATURE_CALL
)
210 item
= empathy_individual_audio_call_menu_item_new (individual
, NULL
);
211 gtk_menu_shell_append (shell
, item
);
212 gtk_widget_show (item
);
215 item
= empathy_individual_video_call_menu_item_new (individual
, NULL
);
216 gtk_menu_shell_append (shell
, item
);
217 gtk_widget_show (item
);
221 if (features
& EMPATHY_INDIVIDUAL_FEATURE_LOG
)
223 item
= empathy_individual_log_menu_item_new (individual
, NULL
);
224 gtk_menu_shell_append (shell
, item
);
225 gtk_widget_show (item
);
229 item
= empathy_individual_invite_menu_item_new (individual
, NULL
);
230 gtk_menu_shell_append (shell
, item
);
231 gtk_widget_show (item
);
234 item
= empathy_individual_file_transfer_menu_item_new (individual
, NULL
);
235 gtk_menu_shell_append (shell
, item
);
236 gtk_widget_show (item
);
238 /* Share my desktop */
239 /* FIXME we should add the "Share my desktop" menu item if Vino is
240 a registered handler in MC5 */
241 item
= empathy_individual_share_my_desktop_menu_item_new (individual
, NULL
);
242 gtk_menu_shell_append (shell
, item
);
243 gtk_widget_show (item
);
245 /* Menu items to target specific contacts */
246 individual_menu_add_personas (GTK_MENU_SHELL (menu
), individual
, features
);
249 if (features
& (EMPATHY_INDIVIDUAL_FEATURE_EDIT
|
250 EMPATHY_INDIVIDUAL_FEATURE_INFO
|
251 EMPATHY_INDIVIDUAL_FEATURE_FAVOURITE
|
252 EMPATHY_INDIVIDUAL_FEATURE_LINK
))
254 item
= gtk_separator_menu_item_new ();
255 gtk_menu_shell_append (shell
, item
);
256 gtk_widget_show (item
);
260 if (features
& EMPATHY_INDIVIDUAL_FEATURE_EDIT
)
262 item
= empathy_individual_edit_menu_item_new (individual
);
263 gtk_menu_shell_append (shell
, item
);
264 gtk_widget_show (item
);
268 if (features
& EMPATHY_INDIVIDUAL_FEATURE_LINK
)
270 item
= empathy_individual_link_menu_item_new (individual
);
271 gtk_menu_shell_append (shell
, item
);
272 gtk_widget_show (item
);
276 if (features
& EMPATHY_INDIVIDUAL_FEATURE_INFO
)
278 item
= empathy_individual_info_menu_item_new (individual
);
279 gtk_menu_shell_append (shell
, item
);
280 gtk_widget_show (item
);
283 /* Favorite checkbox */
284 if (features
& EMPATHY_INDIVIDUAL_FEATURE_FAVOURITE
)
286 item
= empathy_individual_favourite_menu_item_new (individual
);
287 gtk_menu_shell_append (shell
, item
);
288 gtk_widget_show (item
);
295 empathy_individual_add_menu_item_activated (GtkMenuItem
*item
,
296 FolksIndividual
*individual
)
300 toplevel
= gtk_widget_get_toplevel (GTK_WIDGET (item
));
301 if (!gtk_widget_is_toplevel (toplevel
) || !GTK_IS_WINDOW (toplevel
))
304 empathy_new_individual_dialog_show_with_individual (GTK_WINDOW (toplevel
),
309 empathy_individual_add_menu_item_new (FolksIndividual
*individual
)
313 EmpathyIndividualManager
*manager
= NULL
;
314 EmpathyContact
*contact
= NULL
;
315 TpConnection
*connection
;
317 gboolean found
= FALSE
;
318 EmpathyIndividualManagerFlags flags
;
320 g_return_val_if_fail (FOLKS_IS_INDIVIDUAL (individual
), NULL
);
322 if (!empathy_individual_manager_initialized ())
328 manager
= empathy_individual_manager_dup_singleton ();
329 contact
= empathy_contact_dup_from_folks_individual (individual
);
330 connection
= empathy_contact_get_connection (contact
);
332 flags
= empathy_individual_manager_get_flags_for_connection (manager
,
335 if (!(flags
& EMPATHY_INDIVIDUAL_MANAGER_CAN_ADD
))
341 members
= empathy_individual_manager_get_members (
342 EMPATHY_INDIVIDUAL_MANAGER (manager
));
344 for (l
= members
; l
&& !found
; l
= l
->next
)
346 if (!tp_strdiff (folks_individual_get_id (l
->data
),
347 folks_individual_get_id (individual
)))
352 g_list_free (members
);
360 item
= gtk_image_menu_item_new_with_mnemonic (_("_Add Contact…"));
361 image
= gtk_image_new_from_icon_name (GTK_STOCK_ADD
, GTK_ICON_SIZE_MENU
);
362 gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item
), image
);
364 g_signal_connect (item
, "activate",
365 G_CALLBACK (empathy_individual_add_menu_item_activated
),
369 tp_clear_object (&contact
);
370 tp_clear_object (&manager
);
375 typedef gboolean (*SensitivityPredicate
) (EmpathyContact
*contact
);
377 /* Like menu_item_set_first_contact(), but always operates upon the given
380 menu_item_set_contact (GtkWidget
*item
,
381 EmpathyContact
*contact
,
382 GCallback activate_callback
,
383 SensitivityPredicate sensitivity_predicate
)
385 gboolean contact_valid
= TRUE
;
387 if (sensitivity_predicate
!= NULL
)
389 contact_valid
= sensitivity_predicate (contact
);
390 gtk_widget_set_sensitive (item
, sensitivity_predicate (contact
));
393 g_signal_connect (item
, "activate", G_CALLBACK (activate_callback
),
396 return contact_valid
;
400 * Set the given menu @item to call @activate_callback upon the first valid
401 * TpContact associated with @individual whenever @item is activated.
403 * @sensitivity_predicate is an optional function to determine whether the menu
404 * item should be insensitive (if the function returns @FALSE). Otherwise, the
405 * menu item's sensitivity will not change.
408 menu_item_set_first_contact (GtkWidget
*item
,
409 FolksIndividual
*individual
,
410 GCallback activate_callback
,
411 SensitivityPredicate sensitivity_predicate
)
415 personas
= folks_individual_get_personas (individual
);
416 for (l
= personas
; l
!= NULL
; l
= l
->next
)
418 TpContact
*tp_contact
;
419 EmpathyContact
*contact
;
420 TpfPersona
*persona
= l
->data
;
421 gboolean contact_valid
= TRUE
;
423 if (!TPF_IS_PERSONA (persona
))
426 tp_contact
= tpf_persona_get_contact (persona
);
427 contact
= empathy_contact_dup_from_tp_contact (tp_contact
);
429 contact_valid
= menu_item_set_contact (item
, contact
,
430 G_CALLBACK (activate_callback
), sensitivity_predicate
);
432 g_object_unref (contact
);
434 /* stop after the first valid match */
443 empathy_individual_chat_menu_item_activated (GtkMenuItem
*item
,
444 EmpathyContact
*contact
)
446 g_return_if_fail (EMPATHY_IS_CONTACT (contact
));
448 empathy_dispatcher_chat_with_contact (contact
, gtk_get_current_event_time ());
452 empathy_individual_chat_menu_item_new (FolksIndividual
*individual
,
453 EmpathyContact
*contact
)
458 g_return_val_if_fail ((FOLKS_IS_INDIVIDUAL (individual
) &&
459 empathy_folks_individual_contains_contact (individual
)) ||
460 EMPATHY_IS_CONTACT (contact
),
463 item
= gtk_image_menu_item_new_with_mnemonic (_("_Chat"));
464 image
= gtk_image_new_from_icon_name (EMPATHY_IMAGE_MESSAGE
,
466 gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item
), image
);
467 gtk_widget_show (image
);
471 menu_item_set_contact (item
, contact
,
472 G_CALLBACK (empathy_individual_chat_menu_item_activated
), NULL
);
476 menu_item_set_first_contact (item
, individual
,
477 G_CALLBACK (empathy_individual_chat_menu_item_activated
), NULL
);
484 empathy_individual_audio_call_menu_item_activated (GtkMenuItem
*item
,
485 EmpathyContact
*contact
)
487 g_return_if_fail (EMPATHY_IS_CONTACT (contact
));
489 empathy_call_factory_new_call_with_streams (contact
, TRUE
, FALSE
,
490 gtk_get_current_event_time (), NULL
);
494 empathy_individual_audio_call_menu_item_new (FolksIndividual
*individual
,
495 EmpathyContact
*contact
)
500 g_return_val_if_fail (FOLKS_IS_INDIVIDUAL (individual
) ||
501 EMPATHY_IS_CONTACT (contact
),
504 item
= gtk_image_menu_item_new_with_mnemonic (C_("menu item", "_Audio Call"));
505 image
= gtk_image_new_from_icon_name (EMPATHY_IMAGE_VOIP
, GTK_ICON_SIZE_MENU
);
506 gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item
), image
);
507 gtk_widget_show (image
);
511 menu_item_set_contact (item
, contact
,
512 G_CALLBACK (empathy_individual_audio_call_menu_item_activated
),
513 empathy_contact_can_voip_audio
);
517 menu_item_set_first_contact (item
, individual
,
518 G_CALLBACK (empathy_individual_audio_call_menu_item_activated
),
519 empathy_contact_can_voip_audio
);
526 empathy_individual_video_call_menu_item_activated (GtkMenuItem
*item
,
527 EmpathyContact
*contact
)
529 g_return_if_fail (EMPATHY_IS_CONTACT (contact
));
531 empathy_call_factory_new_call_with_streams (contact
, TRUE
, TRUE
,
532 gtk_get_current_event_time (), NULL
);
536 empathy_individual_video_call_menu_item_new (FolksIndividual
*individual
,
537 EmpathyContact
*contact
)
542 g_return_val_if_fail (FOLKS_IS_INDIVIDUAL (individual
) ||
543 EMPATHY_IS_CONTACT (contact
),
546 item
= gtk_image_menu_item_new_with_mnemonic (C_("menu item", "_Video Call"));
547 image
= gtk_image_new_from_icon_name (EMPATHY_IMAGE_VIDEO_CALL
,
549 gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item
), image
);
550 gtk_widget_show (image
);
554 menu_item_set_contact (item
, contact
,
555 G_CALLBACK (empathy_individual_video_call_menu_item_activated
),
556 empathy_contact_can_voip_video
);
560 menu_item_set_first_contact (item
, individual
,
561 G_CALLBACK (empathy_individual_video_call_menu_item_activated
),
562 empathy_contact_can_voip_video
);
569 empathy_individual_log_menu_item_activated (GtkMenuItem
*item
,
570 EmpathyContact
*contact
)
572 g_return_if_fail (EMPATHY_IS_CONTACT (contact
));
574 empathy_log_window_show (empathy_contact_get_account (contact
),
575 empathy_contact_get_id (contact
), FALSE
, NULL
);
579 contact_has_log (EmpathyContact
*contact
)
581 TplLogManager
*manager
;
584 manager
= tpl_log_manager_dup_singleton ();
585 have_log
= tpl_log_manager_exists (manager
,
586 empathy_contact_get_account (contact
), empathy_contact_get_id (contact
),
588 g_object_unref (manager
);
594 empathy_individual_log_menu_item_new (FolksIndividual
*individual
,
595 EmpathyContact
*contact
)
600 g_return_val_if_fail (FOLKS_IS_INDIVIDUAL (individual
) ||
601 EMPATHY_IS_CONTACT (contact
),
604 item
= gtk_image_menu_item_new_with_mnemonic (_("_Previous Conversations"));
605 image
= gtk_image_new_from_icon_name (EMPATHY_IMAGE_LOG
, GTK_ICON_SIZE_MENU
);
606 gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item
), image
);
607 gtk_widget_show (image
);
611 menu_item_set_contact (item
, contact
,
612 G_CALLBACK (empathy_individual_log_menu_item_activated
),
617 menu_item_set_first_contact (item
, individual
,
618 G_CALLBACK (empathy_individual_log_menu_item_activated
),
626 empathy_individual_file_transfer_menu_item_activated (GtkMenuItem
*item
,
627 EmpathyContact
*contact
)
629 g_return_if_fail (EMPATHY_IS_CONTACT (contact
));
631 empathy_send_file_with_file_chooser (contact
);
635 empathy_individual_file_transfer_menu_item_new (FolksIndividual
*individual
,
636 EmpathyContact
*contact
)
641 g_return_val_if_fail (FOLKS_IS_INDIVIDUAL (individual
) ||
642 EMPATHY_IS_CONTACT (contact
),
645 item
= gtk_image_menu_item_new_with_mnemonic (_("Send File"));
646 image
= gtk_image_new_from_icon_name (EMPATHY_IMAGE_DOCUMENT_SEND
,
648 gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item
), image
);
649 gtk_widget_show (image
);
653 menu_item_set_contact (item
, contact
,
654 G_CALLBACK (empathy_individual_file_transfer_menu_item_activated
),
655 empathy_contact_can_send_files
);
659 menu_item_set_first_contact (item
, individual
,
660 G_CALLBACK (empathy_individual_file_transfer_menu_item_activated
),
661 empathy_contact_can_send_files
);
668 empathy_individual_share_my_desktop_menu_item_activated (GtkMenuItem
*item
,
669 EmpathyContact
*contact
)
671 g_return_if_fail (EMPATHY_IS_CONTACT (contact
));
673 empathy_share_my_desktop_share_with_contact (contact
);
677 empathy_individual_share_my_desktop_menu_item_new (FolksIndividual
*individual
,
678 EmpathyContact
*contact
)
683 g_return_val_if_fail (FOLKS_IS_INDIVIDUAL (individual
) ||
684 EMPATHY_IS_CONTACT (contact
),
687 item
= gtk_image_menu_item_new_with_mnemonic (_("Share My Desktop"));
688 image
= gtk_image_new_from_icon_name (GTK_STOCK_NETWORK
, GTK_ICON_SIZE_MENU
);
689 gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item
), image
);
690 gtk_widget_show (image
);
694 menu_item_set_contact (item
, contact
,
695 G_CALLBACK (empathy_individual_share_my_desktop_menu_item_activated
),
696 empathy_contact_can_use_rfb_stream_tube
);
700 menu_item_set_first_contact (item
, individual
,
701 G_CALLBACK (empathy_individual_share_my_desktop_menu_item_activated
),
702 empathy_contact_can_use_rfb_stream_tube
);
709 favourite_menu_item_toggled_cb (GtkCheckMenuItem
*item
,
710 FolksIndividual
*individual
)
712 folks_favourite_set_is_favourite (FOLKS_FAVOURITE (individual
),
713 gtk_check_menu_item_get_active (item
));
717 empathy_individual_favourite_menu_item_new (FolksIndividual
*individual
)
721 item
= gtk_check_menu_item_new_with_label (_("Favorite"));
723 gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item
),
724 folks_favourite_get_is_favourite (FOLKS_FAVOURITE (individual
)));
726 g_signal_connect (item
, "toggled",
727 G_CALLBACK (favourite_menu_item_toggled_cb
), individual
);
733 individual_info_menu_item_activate_cb (FolksIndividual
*individual
)
735 empathy_individual_information_dialog_show (individual
, NULL
);
739 empathy_individual_info_menu_item_new (FolksIndividual
*individual
)
744 g_return_val_if_fail (FOLKS_IS_INDIVIDUAL (individual
), NULL
);
745 g_return_val_if_fail (empathy_folks_individual_contains_contact (individual
),
748 item
= gtk_image_menu_item_new_with_mnemonic (_("Infor_mation"));
749 image
= gtk_image_new_from_icon_name (EMPATHY_IMAGE_CONTACT_INFORMATION
,
751 gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item
), image
);
752 gtk_widget_show (image
);
754 g_signal_connect_swapped (item
, "activate",
755 G_CALLBACK (individual_info_menu_item_activate_cb
),
762 individual_edit_menu_item_activate_cb (FolksIndividual
*individual
)
764 empathy_individual_edit_dialog_show (individual
, NULL
);
768 empathy_individual_edit_menu_item_new (FolksIndividual
*individual
)
770 EmpathyIndividualManager
*manager
;
773 gboolean enable
= FALSE
;
774 EmpathyContact
*contact
;
776 g_return_val_if_fail (FOLKS_IS_INDIVIDUAL (individual
), NULL
);
778 contact
= empathy_contact_dup_from_folks_individual (individual
);
780 g_return_val_if_fail (EMPATHY_IS_CONTACT (contact
), NULL
);
782 if (empathy_individual_manager_initialized ())
784 TpConnection
*connection
;
785 EmpathyIndividualManagerFlags flags
;
787 manager
= empathy_individual_manager_dup_singleton ();
788 connection
= empathy_contact_get_connection (contact
);
789 flags
= empathy_individual_manager_get_flags_for_connection (
790 manager
, connection
);
792 enable
= (flags
& EMPATHY_INDIVIDUAL_MANAGER_CAN_ALIAS
||
793 flags
& EMPATHY_INDIVIDUAL_MANAGER_CAN_GROUP
);
795 g_object_unref (manager
);
798 item
= gtk_image_menu_item_new_with_mnemonic (
799 C_("Edit individual (contextual menu)", "_Edit"));
800 image
= gtk_image_new_from_icon_name (GTK_STOCK_EDIT
, GTK_ICON_SIZE_MENU
);
801 gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item
), image
);
802 gtk_widget_show (image
);
804 gtk_widget_set_sensitive (item
, enable
);
806 g_signal_connect_swapped (item
, "activate",
807 G_CALLBACK (individual_edit_menu_item_activate_cb
), individual
);
809 g_object_unref (contact
);
815 individual_link_menu_item_activate_cb (FolksIndividual
*individual
)
817 empathy_linking_dialog_show (individual
, NULL
);
821 empathy_individual_link_menu_item_new (FolksIndividual
*individual
)
824 /*GtkWidget *image;*/
826 g_return_val_if_fail (FOLKS_IS_INDIVIDUAL (individual
), NULL
);
828 item
= gtk_image_menu_item_new_with_mnemonic (
829 C_("Link individual (contextual menu)", "_Link…"));
831 /*image = gtk_image_new_from_icon_name (GTK_STOCK_EDIT, GTK_ICON_SIZE_MENU);
832 gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
833 gtk_widget_show (image);*/
835 g_signal_connect_swapped (item
, "activate",
836 G_CALLBACK (individual_link_menu_item_activate_cb
), individual
);
843 FolksIndividual
*individual
;
844 EmpathyContact
*contact
;
845 EmpathyChatroom
*chatroom
;
848 static RoomSubMenuData
*
849 room_sub_menu_data_new (FolksIndividual
*individual
,
850 EmpathyContact
*contact
,
851 EmpathyChatroom
*chatroom
)
853 RoomSubMenuData
*data
;
855 data
= g_slice_new0 (RoomSubMenuData
);
856 if (individual
!= NULL
)
857 data
->individual
= g_object_ref (individual
);
859 data
->contact
= g_object_ref (contact
);
860 data
->chatroom
= g_object_ref (chatroom
);
866 room_sub_menu_data_free (RoomSubMenuData
*data
)
868 tp_clear_object (&data
->individual
);
869 tp_clear_object (&data
->contact
);
870 g_object_unref (data
->chatroom
);
871 g_slice_free (RoomSubMenuData
, data
);
875 room_sub_menu_activate_cb (GtkWidget
*item
,
876 RoomSubMenuData
*data
)
879 EmpathyChatroomManager
*mgr
;
880 EmpathyContact
*contact
= NULL
;
883 chat
= empathy_chatroom_get_tp_chat (data
->chatroom
);
886 /* channel was invalidated. Ignoring */
890 mgr
= empathy_chatroom_manager_dup_singleton (NULL
);
892 if (data
->contact
!= NULL
)
893 contact
= g_object_ref (data
->contact
);
896 /* find the first of this Individual's contacts who can join this room */
897 personas
= folks_individual_get_personas (data
->individual
);
898 for (l
= personas
; l
!= NULL
&& contact
== NULL
; l
= g_list_next (l
))
900 TpfPersona
*persona
= l
->data
;
901 TpContact
*tp_contact
;
904 if (!TPF_IS_PERSONA (persona
))
907 tp_contact
= tpf_persona_get_contact (persona
);
908 contact
= empathy_contact_dup_from_tp_contact (tp_contact
);
910 rooms
= empathy_chatroom_manager_get_chatrooms (mgr
,
911 empathy_contact_get_account (contact
));
913 if (g_list_find (rooms
, data
->chatroom
) == NULL
)
914 tp_clear_object (&contact
);
916 /* if contact != NULL here, we've found our match */
922 g_object_unref (mgr
);
926 /* contact disappeared. Ignoring */
930 g_return_if_fail (EMPATHY_IS_CONTACT (contact
));
932 /* send invitation */
933 empathy_contact_list_add (EMPATHY_CONTACT_LIST (chat
),
934 contact
, _("Inviting you to this room"));
937 g_object_unref (contact
);
941 create_room_sub_menu (FolksIndividual
*individual
,
942 EmpathyContact
*contact
,
943 EmpathyChatroom
*chatroom
)
946 RoomSubMenuData
*data
;
948 item
= gtk_menu_item_new_with_label (empathy_chatroom_get_name (chatroom
));
949 data
= room_sub_menu_data_new (individual
, contact
, chatroom
);
950 g_signal_connect_data (item
, "activate",
951 G_CALLBACK (room_sub_menu_activate_cb
), data
,
952 (GClosureNotify
) room_sub_menu_data_free
, 0);
958 empathy_individual_invite_menu_item_new (FolksIndividual
*individual
,
959 EmpathyContact
*contact
)
963 GtkWidget
*room_item
;
964 EmpathyChatroomManager
*mgr
;
969 GtkWidget
*submenu
= NULL
;
970 /* map of chat room names to their objects; just a utility to remove
971 * duplicates and to make construction of the alphabetized list easier */
972 GHashTable
*name_room_map
;
974 g_return_val_if_fail (FOLKS_IS_INDIVIDUAL (individual
) ||
975 EMPATHY_IS_CONTACT (contact
),
978 name_room_map
= g_hash_table_new_full (g_str_hash
, g_str_equal
, NULL
,
981 item
= gtk_image_menu_item_new_with_mnemonic (_("_Invite to Chat Room"));
982 image
= gtk_image_new_from_icon_name (EMPATHY_IMAGE_GROUP_MESSAGE
,
984 gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item
), image
);
986 mgr
= empathy_chatroom_manager_dup_singleton (NULL
);
990 rooms
= empathy_chatroom_manager_get_chatrooms (mgr
,
991 empathy_contact_get_account (contact
));
995 /* collect the rooms from amongst all accounts for this Individual */
996 personas
= folks_individual_get_personas (individual
);
997 for (l
= personas
; l
!= NULL
; l
= g_list_next (l
))
999 TpfPersona
*persona
= l
->data
;
1001 TpContact
*tp_contact
;
1002 EmpathyContact
*contact_cur
;
1004 if (!TPF_IS_PERSONA (persona
))
1007 tp_contact
= tpf_persona_get_contact (persona
);
1008 contact_cur
= empathy_contact_dup_from_tp_contact (tp_contact
);
1010 rooms_cur
= empathy_chatroom_manager_get_chatrooms (mgr
,
1011 empathy_contact_get_account (contact_cur
));
1012 rooms
= g_list_concat (rooms
, rooms_cur
);
1014 g_object_unref (contact_cur
);
1018 /* alphabetize the rooms */
1019 for (l
= rooms
; l
!= NULL
; l
= g_list_next (l
))
1021 EmpathyChatroom
*chatroom
= l
->data
;
1024 if (empathy_chatroom_get_tp_chat (chatroom
) != NULL
)
1028 name
= empathy_chatroom_get_name (chatroom
);
1029 existed
= (g_hash_table_lookup (name_room_map
, name
) != NULL
);
1030 g_hash_table_insert (name_room_map
, (gpointer
) name
,
1031 g_object_ref (chatroom
));
1033 /* this will take care of duplicates in rooms */
1036 names
= g_list_insert_sorted (names
, (gpointer
) name
,
1037 (GCompareFunc
) g_strcmp0
);
1042 for (l
= names
; l
!= NULL
; l
= g_list_next (l
))
1044 const gchar
*name
= l
->data
;
1045 EmpathyChatroom
*chatroom
;
1047 if (G_UNLIKELY (submenu
== NULL
))
1048 submenu
= gtk_menu_new ();
1050 chatroom
= g_hash_table_lookup (name_room_map
, name
);
1051 room_item
= create_room_sub_menu (individual
, contact
, chatroom
);
1052 gtk_menu_shell_append ((GtkMenuShell
*) submenu
, room_item
);
1053 gtk_widget_show (room_item
);
1057 gtk_menu_item_set_submenu (GTK_MENU_ITEM (item
), submenu
);
1059 gtk_widget_set_sensitive (item
, FALSE
);
1061 gtk_widget_show (image
);
1063 g_hash_table_destroy (name_room_map
);
1064 g_object_unref (mgr
);
1065 g_list_free (names
);
1066 g_list_free (rooms
);