X-Git-Url: https://git.0d.be/?p=empathy.git;a=blobdiff_plain;f=libempathy-gtk%2Fempathy-contact-menu.c;h=0de7c1ca6afdd78c4ab7847db97c4aa6d7db8c23;hp=81c94a6dbabebb40f8ecc665b04ab725d42026e0;hb=aedb2729fa86eafc2891bc522cad68285d41b8a5;hpb=ec55d4f9308a0eb65c6ea5de7e9757e9d8b0b70f diff --git a/libempathy-gtk/empathy-contact-menu.c b/libempathy-gtk/empathy-contact-menu.c index 81c94a6d..0de7c1ca 100644 --- a/libempathy-gtk/empathy-contact-menu.c +++ b/libempathy-gtk/empathy-contact-menu.c @@ -15,7 +15,7 @@ * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - * + * * Authors: Xavier Claessens */ @@ -23,17 +23,22 @@ #include -#include +#include #include +#include #include +#include #include #include +#include +#include #include "empathy-contact-menu.h" #include "empathy-images.h" #include "empathy-log-window.h" #include "empathy-contact-dialogs.h" +#include "empathy-ui-utils.h" GtkWidget * empathy_contact_menu_new (EmpathyContact *contact, @@ -52,6 +57,13 @@ empathy_contact_menu_new (EmpathyContact *contact, menu = gtk_menu_new (); shell = GTK_MENU_SHELL (menu); + /* Add Contact */ + item = empathy_contact_add_menu_item_new (contact); + if (item) { + gtk_menu_shell_append (shell, item); + gtk_widget_show (item); + } + /* Chat */ if (features & EMPATHY_CONTACT_FEATURE_CHAT) { item = empathy_contact_chat_menu_item_new (contact); @@ -59,9 +71,14 @@ empathy_contact_menu_new (EmpathyContact *contact, gtk_widget_show (item); } - /* Call */ if (features & EMPATHY_CONTACT_FEATURE_CALL) { - item = empathy_contact_call_menu_item_new (contact); + /* Audio Call */ + item = empathy_contact_audio_call_menu_item_new (contact); + gtk_menu_shell_append (shell, item); + gtk_widget_show (item); + + /* Video Call */ + item = empathy_contact_video_call_menu_item_new (contact); gtk_menu_shell_append (shell, item); gtk_widget_show (item); } @@ -73,6 +90,16 @@ empathy_contact_menu_new (EmpathyContact *contact, gtk_widget_show (item); } + /* Invite */ + item = empathy_contact_invite_menu_item_new (contact); + gtk_menu_shell_append (shell, item); + gtk_widget_show (item); + + /* File transfer */ + item = empathy_contact_file_transfer_menu_item_new (contact); + gtk_menu_shell_append (shell, item); + gtk_widget_show (item); + /* Separator */ if (features & (EMPATHY_CONTACT_FEATURE_EDIT | EMPATHY_CONTACT_FEATURE_INFO)) { @@ -98,6 +125,84 @@ empathy_contact_menu_new (EmpathyContact *contact, return menu; } +static void +empathy_contact_add_menu_item_activated (GtkMenuItem *item, + EmpathyContact *contact) +{ + GtkWidget *toplevel; + + toplevel = gtk_widget_get_toplevel (GTK_WIDGET (item)); + if (!GTK_WIDGET_TOPLEVEL (toplevel) || !GTK_IS_WINDOW (toplevel)) { + toplevel = NULL; + } + + empathy_new_contact_dialog_show_with_contact (GTK_WINDOW (toplevel), + contact); +} + +GtkWidget * +empathy_contact_add_menu_item_new (EmpathyContact *contact) +{ + GtkWidget *item; + GtkWidget *image; + EmpathyContactManager *manager; + TpConnection *connection; + GList *l, *members; + gboolean found = FALSE; + EmpathyContactListFlags flags; + + g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL); + + if (!empathy_contact_manager_initialized ()) { + return NULL; + } + + manager = empathy_contact_manager_dup_singleton (); + connection = empathy_contact_get_connection (contact); + + flags = empathy_contact_manager_get_flags_for_connection (manager, + connection); + + if (!(flags & EMPATHY_CONTACT_LIST_CAN_ADD)) { + return NULL; + } + + members = empathy_contact_list_get_members (EMPATHY_CONTACT_LIST (manager)); + for (l = members; l; l = l->next) { + if (!found && empathy_contact_equal (l->data, contact)) { + found = TRUE; + /* we keep iterating so that we don't leak contact + * refs */ + } + + g_object_unref (l->data); + } + g_list_free (members); + g_object_unref (manager); + + if (found) { + return NULL; + } + + item = gtk_image_menu_item_new_with_mnemonic (_("_Add Contact...")); + image = gtk_image_new_from_icon_name (GTK_STOCK_ADD, + GTK_ICON_SIZE_MENU); + gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image); + + g_signal_connect (item, "activate", + G_CALLBACK (empathy_contact_add_menu_item_activated), + contact); + + return item; +} + +static void +empathy_contact_chat_menu_item_activated (GtkMenuItem *item, + EmpathyContact *contact) +{ + empathy_dispatcher_chat_with_contact (contact, NULL, NULL); +} + GtkWidget * empathy_contact_chat_menu_item_new (EmpathyContact *contact) { @@ -112,32 +217,74 @@ empathy_contact_chat_menu_item_new (EmpathyContact *contact) gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image); gtk_widget_show (image); - g_signal_connect_swapped (item, "activate", - G_CALLBACK (empathy_dispatcher_chat_with_contact), + g_signal_connect (item, "activate", + G_CALLBACK (empathy_contact_chat_menu_item_activated), contact); - + return item; } +static void +empathy_contact_audio_call_menu_item_activated (GtkMenuItem *item, + EmpathyContact *contact) +{ + EmpathyCallFactory *factory; + + factory = empathy_call_factory_get (); + empathy_call_factory_new_call_with_streams (factory, contact, TRUE, FALSE); +} + GtkWidget * -empathy_contact_call_menu_item_new (EmpathyContact *contact) +empathy_contact_audio_call_menu_item_new (EmpathyContact *contact) { GtkWidget *item; GtkWidget *image; g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL); - item = gtk_image_menu_item_new_with_mnemonic (_("_Call")); + item = gtk_image_menu_item_new_with_mnemonic (C_("menu item", "_Audio Call")); image = gtk_image_new_from_icon_name (EMPATHY_IMAGE_VOIP, GTK_ICON_SIZE_MENU); gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image); - gtk_widget_set_sensitive (item, empathy_contact_can_voip (contact)); + gtk_widget_set_sensitive (item, empathy_contact_can_voip_audio (contact)); gtk_widget_show (image); - g_signal_connect_swapped (item, "activate", - G_CALLBACK (empathy_dispatcher_call_with_contact), + g_signal_connect (item, "activate", + G_CALLBACK (empathy_contact_audio_call_menu_item_activated), contact); - + + return item; +} + +static void +empathy_contact_video_call_menu_item_activated (GtkMenuItem *item, + EmpathyContact *contact) +{ + EmpathyCallFactory *factory; + + factory = empathy_call_factory_get (); + empathy_call_factory_new_call_with_streams (factory, contact, TRUE, TRUE); +} + +GtkWidget * +empathy_contact_video_call_menu_item_new (EmpathyContact *contact) +{ + GtkWidget *item; + GtkWidget *image; + + g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL); + + item = gtk_image_menu_item_new_with_mnemonic (C_("menu item", "_Video Call")); + image = gtk_image_new_from_icon_name (EMPATHY_IMAGE_VIDEO_CALL, + GTK_ICON_SIZE_MENU); + gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image); + gtk_widget_set_sensitive (item, empathy_contact_can_voip_video (contact)); + gtk_widget_show (image); + + g_signal_connect (item, "activate", + G_CALLBACK (empathy_contact_video_call_menu_item_activated), + contact); + return item; } @@ -159,7 +306,7 @@ empathy_contact_log_menu_item_new (EmpathyContact *contact) g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL); - manager = empathy_log_manager_new (); + manager = empathy_log_manager_dup_singleton (); have_log = empathy_log_manager_exists (manager, empathy_contact_get_account (contact), empathy_contact_get_id (contact), @@ -176,14 +323,36 @@ empathy_contact_log_menu_item_new (EmpathyContact *contact) g_signal_connect_swapped (item, "activate", G_CALLBACK (contact_log_menu_item_activate_cb), contact); - + + return item; +} + +GtkWidget * +empathy_contact_file_transfer_menu_item_new (EmpathyContact *contact) +{ + GtkWidget *item; + GtkWidget *image; + + g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL); + + item = gtk_image_menu_item_new_with_mnemonic (_("Send file")); + image = gtk_image_new_from_icon_name (EMPATHY_IMAGE_DOCUMENT_SEND, + GTK_ICON_SIZE_MENU); + gtk_widget_set_sensitive (item, empathy_contact_can_send_files (contact)); + gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image); + gtk_widget_show (image); + + g_signal_connect_swapped (item, "activate", + G_CALLBACK (empathy_send_file_with_file_chooser), + contact); + return item; } static void contact_info_menu_item_activate_cb (EmpathyContact *contact) { - empathy_contact_information_dialog_show (contact, NULL, FALSE, FALSE); + empathy_contact_information_dialog_show (contact, NULL); } GtkWidget * @@ -203,34 +372,165 @@ empathy_contact_info_menu_item_new (EmpathyContact *contact) g_signal_connect_swapped (item, "activate", G_CALLBACK (contact_info_menu_item_activate_cb), contact); - + return item; } static void contact_edit_menu_item_activate_cb (EmpathyContact *contact) { - empathy_contact_information_dialog_show (contact, NULL, TRUE, FALSE); + empathy_contact_edit_dialog_show (contact, NULL); } GtkWidget * empathy_contact_edit_menu_item_new (EmpathyContact *contact) { + EmpathyContactManager *manager; GtkWidget *item; GtkWidget *image; + gboolean enable = FALSE; g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL); + if (empathy_contact_manager_initialized ()) { + TpConnection *connection; + EmpathyContactListFlags flags; + + manager = empathy_contact_manager_dup_singleton (); + connection = empathy_contact_get_connection (contact); + flags = empathy_contact_manager_get_flags_for_connection ( + manager, connection); + + enable = (flags & EMPATHY_CONTACT_LIST_CAN_ALIAS || + flags & EMPATHY_CONTACT_LIST_CAN_GROUP); + + g_object_unref (manager); + } + item = gtk_image_menu_item_new_with_mnemonic (_("_Edit")); image = gtk_image_new_from_icon_name (GTK_STOCK_EDIT, GTK_ICON_SIZE_MENU); gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image); gtk_widget_show (image); + gtk_widget_set_sensitive (item, enable); + g_signal_connect_swapped (item, "activate", G_CALLBACK (contact_edit_menu_item_activate_cb), contact); - + + return item; +} + +typedef struct { + EmpathyContact *contact; + EmpathyChatroom *chatroom; +} RoomSubMenuData; + +static RoomSubMenuData * +room_sub_menu_data_new (EmpathyContact *contact, + EmpathyChatroom *chatroom) +{ + RoomSubMenuData *data; + + data = g_slice_new (RoomSubMenuData); + data->contact = g_object_ref (contact); + data->chatroom = g_object_ref (chatroom); + return data; +} + +static void +room_sub_menu_data_free (RoomSubMenuData *data) +{ + /* FIXME: seems this is never called... */ + g_object_unref (data->contact); + g_object_unref (data->chatroom); + g_slice_free (RoomSubMenuData, data); +} + +static void +room_sub_menu_activate_cb (GtkWidget *item, + RoomSubMenuData *data) +{ + TpHandle handle; + GArray handles = {(gchar *) &handle, 1}; + EmpathyTpChat *chat; + TpChannel *channel; + + chat = empathy_chatroom_get_tp_chat (data->chatroom); + if (chat == NULL) { + /* channel was invalidated. Ignoring */ + return; + } + + /* send invitation */ + handle = empathy_contact_get_handle (data->contact); + channel = empathy_tp_chat_get_channel (chat); + tp_cli_channel_interface_group_call_add_members (channel, -1, &handles, + _("Inviting to this room"), NULL, NULL, NULL, NULL); +} + +static GtkWidget * +create_room_sub_menu (EmpathyContact *contact, + EmpathyChatroom *chatroom) +{ + GtkWidget *item; + RoomSubMenuData *data; + + item = gtk_menu_item_new_with_label (empathy_chatroom_get_name (chatroom)); + data = room_sub_menu_data_new (contact, chatroom); + g_signal_connect_data (item, "activate", + G_CALLBACK (room_sub_menu_activate_cb), data, + (GClosureNotify) room_sub_menu_data_free, 0); + + return item; +} + +GtkWidget * +empathy_contact_invite_menu_item_new (EmpathyContact *contact) +{ + GtkWidget *item; + GtkWidget *image; + GtkWidget *room_item; + EmpathyChatroomManager *mgr; + GList *rooms, *l; + GtkWidget *submenu = NULL; + + g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL); + + item = gtk_image_menu_item_new_with_mnemonic (_("_Invite to chatroom")); + image = gtk_image_new_from_icon_name (EMPATHY_IMAGE_GROUP_MESSAGE, + GTK_ICON_SIZE_MENU); + gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image); + + mgr = empathy_chatroom_manager_dup_singleton (NULL); + rooms = empathy_chatroom_manager_get_chatrooms (mgr, + empathy_contact_get_account (contact)); + + for (l = rooms; l != NULL; l = g_list_next (l)) { + EmpathyChatroom *chatroom = l->data; + + if (empathy_chatroom_get_tp_chat (chatroom) != NULL) { + if (G_UNLIKELY (submenu == NULL)) + submenu = gtk_menu_new (); + + room_item = create_room_sub_menu (contact, chatroom); + gtk_menu_shell_append ((GtkMenuShell *) submenu, room_item); + gtk_widget_show (room_item); + } + } + + if (submenu) { + gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), submenu); + } else { + gtk_widget_set_sensitive (item, FALSE); + } + + gtk_widget_show (image); + + g_object_unref (mgr); + g_list_free (rooms); + return item; }