diff options
-rw-r--r-- | libempathy-gtk/Makefile.am | 1 | ||||
-rw-r--r-- | libempathy-gtk/empathy-individual-menu.c | 769 | ||||
-rw-r--r-- | libempathy-gtk/empathy-individual-menu.h | 20 | ||||
-rw-r--r-- | libempathy-gtk/empathy-individual-store.c | 41 | ||||
-rw-r--r-- | libempathy-gtk/empathy-individual-view.c | 22 | ||||
-rw-r--r-- | libempathy/empathy-individual-manager.c | 30 | ||||
-rw-r--r-- | libempathy/empathy-individual-manager.h | 6 | ||||
-rw-r--r-- | libempathy/empathy-utils.c | 24 | ||||
-rw-r--r-- | libempathy/empathy-utils.h | 1 | ||||
-rw-r--r-- | src/empathy-main-window.c | 3 |
10 files changed, 881 insertions, 36 deletions
diff --git a/libempathy-gtk/Makefile.am b/libempathy-gtk/Makefile.am index 6959578ae..eb32ccd35 100644 --- a/libempathy-gtk/Makefile.am +++ b/libempathy-gtk/Makefile.am @@ -52,6 +52,7 @@ libempathy_gtk_handwritten_source = \ empathy-contact-selector-dialog.c \ empathy-contact-widget.c \ empathy-geometry.c \ + empathy-individual-menu.c \ empathy-individual-store.c \ empathy-individual-view.c \ empathy-irc-network-dialog.c \ diff --git a/libempathy-gtk/empathy-individual-menu.c b/libempathy-gtk/empathy-individual-menu.c new file mode 100644 index 000000000..a849e7eb8 --- /dev/null +++ b/libempathy-gtk/empathy-individual-menu.c @@ -0,0 +1,769 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Copyright (C) 2008-2010 Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * 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 <xclaesse@gmail.com> + * Travis Reitter <travis.reitter@collabora.co.uk> + */ + +#include "config.h" + +#include <string.h> + +#include <glib/gi18n-lib.h> +#include <gtk/gtk.h> +#include <telepathy-glib/util.h> +#ifdef ENABLE_TPL +#include <telepathy-logger/log-manager.h> +#else + +#include <libempathy/empathy-log-manager.h> +#endif /* ENABLE_TPL */ +#include <libempathy/empathy-call-factory.h> +#include <libempathy/empathy-dispatcher.h> +#include <libempathy/empathy-contact-manager.h> +#include <libempathy/empathy-individual-manager.h> +#include <libempathy/empathy-chatroom-manager.h> +#include <libempathy/empathy-utils.h> + +#include "empathy-individual-menu.h" +#include "empathy-images.h" +#include "empathy-log-window.h" +#include "empathy-contact-dialogs.h" +#include "empathy-ui-utils.h" +#include "empathy-share-my-desktop.h" + +GtkWidget * +empathy_individual_menu_new (FolksIndividual *individual, + EmpathyIndividualFeatureFlags features) +{ + GtkWidget *menu; + GtkMenuShell *shell; + GtkWidget *item; + + g_return_val_if_fail (FOLKS_IS_INDIVIDUAL (individual), NULL); + + if (features == EMPATHY_INDIVIDUAL_FEATURE_NONE) + return NULL; + + menu = gtk_menu_new (); + shell = GTK_MENU_SHELL (menu); + + /* Add Contact */ + item = empathy_individual_add_menu_item_new (individual); + if (item) + { + gtk_menu_shell_append (shell, item); + gtk_widget_show (item); + } + + /* Chat */ + if (features & EMPATHY_INDIVIDUAL_FEATURE_CHAT) + { + item = empathy_individual_chat_menu_item_new (individual); + if (item != NULL) + { + gtk_menu_shell_append (shell, item); + gtk_widget_show (item); + } + } + + if (features & EMPATHY_INDIVIDUAL_FEATURE_CALL) + { + /* Audio Call */ + item = empathy_individual_audio_call_menu_item_new (individual); + gtk_menu_shell_append (shell, item); + gtk_widget_show (item); + + /* Video Call */ + item = empathy_individual_video_call_menu_item_new (individual); + gtk_menu_shell_append (shell, item); + gtk_widget_show (item); + } + + /* Log */ + if (features & EMPATHY_INDIVIDUAL_FEATURE_LOG) + { + item = empathy_individual_log_menu_item_new (individual); + gtk_menu_shell_append (shell, item); + gtk_widget_show (item); + } + + /* Invite */ + item = empathy_individual_invite_menu_item_new (individual); + gtk_menu_shell_append (shell, item); + gtk_widget_show (item); + + /* File transfer */ + item = empathy_individual_file_transfer_menu_item_new (individual); + gtk_menu_shell_append (shell, item); + gtk_widget_show (item); + + /* Share my desktop */ + /* FIXME we should add the "Share my desktop" menu item if Vino is + a registered handler in MC5 */ + item = empathy_individual_share_my_desktop_menu_item_new (individual); + gtk_menu_shell_append (shell, item); + gtk_widget_show (item); + + /* Separator */ + if (features & (EMPATHY_INDIVIDUAL_FEATURE_EDIT | + EMPATHY_INDIVIDUAL_FEATURE_INFO | + EMPATHY_INDIVIDUAL_FEATURE_FAVOURITE)) + { + item = gtk_separator_menu_item_new (); + gtk_menu_shell_append (shell, item); + gtk_widget_show (item); + } + + /* Edit */ + if (features & EMPATHY_INDIVIDUAL_FEATURE_EDIT) + { + item = empathy_individual_edit_menu_item_new (individual); + gtk_menu_shell_append (shell, item); + gtk_widget_show (item); + } + + /* Info */ + if (features & EMPATHY_INDIVIDUAL_FEATURE_INFO) + { + item = empathy_individual_info_menu_item_new (individual); + gtk_menu_shell_append (shell, item); + gtk_widget_show (item); + } + +#if HAVE_FAVOURITE_CONTACTS + /* Favorite checkbox */ + if (features & EMPATHY_INDIVIDUAL_FEATURE_FAVOURITE) + { + item = empathy_individual_favourite_menu_item_new (individual); + gtk_menu_shell_append (shell, item); + gtk_widget_show (item); + } +#endif + + return menu; +} + +static void +empathy_individual_add_menu_item_activated (GtkMenuItem *item, + FolksIndividual *individual) +{ + GtkWidget *toplevel; + EmpathyContact *contact; + + toplevel = gtk_widget_get_toplevel (GTK_WIDGET (item)); + if (!gtk_widget_is_toplevel (toplevel) || !GTK_IS_WINDOW (toplevel)) + toplevel = NULL; + + contact = empathy_contact_from_folks_individual (individual); + empathy_new_contact_dialog_show_with_contact (GTK_WINDOW (toplevel), + contact); + + if (contact != NULL) + g_object_unref (contact); +} + +GtkWidget * +empathy_individual_add_menu_item_new (FolksIndividual *individual) +{ + GtkWidget *item; + GtkWidget *image; + EmpathyIndividualManager *manager; + EmpathyContact *contact = NULL; + TpConnection *connection; + GList *l, *members; + gboolean found = FALSE; + EmpathyIndividualManagerFlags flags; + + g_return_val_if_fail (FOLKS_IS_INDIVIDUAL (individual), NULL); + + if (!empathy_individual_manager_initialized ()) + { + item = NULL; + goto out; + } + + manager = empathy_individual_manager_dup_singleton (); + contact = empathy_contact_from_folks_individual (individual); + connection = empathy_contact_get_connection (contact); + + flags = empathy_individual_manager_get_flags_for_connection (manager, + connection); + + if (!(flags & EMPATHY_INDIVIDUAL_MANAGER_CAN_ADD)) + { + item = NULL; + goto out; + } + + members = empathy_individual_manager_get_members ( + EMPATHY_INDIVIDUAL_MANAGER (manager)); + + for (l = members; l && !found; l = l->next) + { + if (!tp_strdiff (folks_individual_get_id (l->data), + folks_individual_get_id (individual))) + { + found = TRUE; + } + } + g_list_free (members); + g_object_unref (manager); + + if (found) + { + item = NULL; + goto out; + } + + 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_individual_add_menu_item_activated), + individual); + +out: + if (contact != NULL) + g_object_unref (contact); + + return item; +} + +static void +empathy_individual_chat_menu_item_activated (GtkMenuItem *item, + FolksIndividual *individual) +{ + EmpathyContact *contact; + + contact = empathy_contact_from_folks_individual (individual); + + g_return_if_fail (EMPATHY_IS_CONTACT (contact)); + + empathy_dispatcher_chat_with_contact (contact, gtk_get_current_event_time (), + NULL, NULL); + + g_object_unref (contact); +} + +GtkWidget * +empathy_individual_chat_menu_item_new (FolksIndividual *individual) +{ + GtkWidget *item; + GtkWidget *image; + + g_return_val_if_fail (FOLKS_IS_INDIVIDUAL (individual), NULL); + g_return_val_if_fail (empathy_folks_individual_contains_contact (individual), + NULL); + + item = gtk_image_menu_item_new_with_mnemonic (_("_Chat")); + image = gtk_image_new_from_icon_name (EMPATHY_IMAGE_MESSAGE, + GTK_ICON_SIZE_MENU); + gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image); + gtk_widget_show (image); + + g_signal_connect (item, "activate", + G_CALLBACK (empathy_individual_chat_menu_item_activated), individual); + + return item; +} + +static void +empathy_individual_audio_call_menu_item_activated (GtkMenuItem *item, + FolksIndividual *individual) +{ + EmpathyContact *contact; + EmpathyCallFactory *factory; + + contact = empathy_contact_from_folks_individual (individual); + + g_return_if_fail (EMPATHY_IS_CONTACT (contact)); + + factory = empathy_call_factory_get (); + empathy_call_factory_new_call_with_streams (factory, contact, TRUE, FALSE); + g_object_unref (contact); +} + +GtkWidget * +empathy_individual_audio_call_menu_item_new (FolksIndividual *individual) +{ + GtkWidget *item; + GtkWidget *image; + EmpathyContact *contact; + + g_return_val_if_fail (FOLKS_IS_INDIVIDUAL (individual), NULL); + + contact = empathy_contact_from_folks_individual (individual); + + g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL); + + 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_audio (contact)); + gtk_widget_show (image); + + g_signal_connect (item, "activate", + G_CALLBACK (empathy_individual_audio_call_menu_item_activated), + individual); + + g_object_unref (contact); + + return item; +} + +static void +empathy_individual_video_call_menu_item_activated (GtkMenuItem *item, + FolksIndividual *individual) +{ + EmpathyContact *contact; + EmpathyCallFactory *factory; + + contact = empathy_contact_from_folks_individual (individual); + + g_return_if_fail (EMPATHY_IS_CONTACT (contact)); + + factory = empathy_call_factory_get (); + empathy_call_factory_new_call_with_streams (factory, contact, TRUE, TRUE); + g_object_unref (contact); +} + +GtkWidget * +empathy_individual_video_call_menu_item_new (FolksIndividual *individual) +{ + GtkWidget *item; + GtkWidget *image; + EmpathyContact *contact; + + g_return_val_if_fail (FOLKS_IS_INDIVIDUAL (individual), NULL); + + contact = empathy_contact_from_folks_individual (individual); + + 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_individual_video_call_menu_item_activated), + individual); + + g_object_unref (contact); + + return item; +} + +static void +individual_log_menu_item_activate_cb (FolksIndividual *individual) +{ + EmpathyContact *contact; + + contact = empathy_contact_from_folks_individual (individual); + + g_return_if_fail (EMPATHY_IS_CONTACT (contact)); + + empathy_log_window_show (empathy_contact_get_account (contact), + empathy_contact_get_id (contact), FALSE, NULL); +} + +GtkWidget * +empathy_individual_log_menu_item_new (FolksIndividual *individual) +{ +#ifndef ENABLE_TPL + EmpathyLogManager *manager; +#else + TplLogManager *manager; +#endif /* ENABLE_TPL */ + gboolean have_log; + GtkWidget *item; + GtkWidget *image; + EmpathyContact *contact; + + g_return_val_if_fail (FOLKS_IS_INDIVIDUAL (individual), NULL); + + contact = empathy_contact_from_folks_individual (individual); + + g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL); + +#ifndef ENABLE_TPL + manager = empathy_log_manager_dup_singleton (); + have_log = empathy_log_manager_exists (manager, + empathy_contact_get_account (contact), empathy_contact_get_id (contact), + FALSE); +#else + manager = tpl_log_manager_dup_singleton (); + have_log = tpl_log_manager_exists (manager, + empathy_contact_get_account (contact), empathy_contact_get_id (contact), + FALSE); +#endif /* ENABLE_TPL */ + g_object_unref (manager); + + item = gtk_image_menu_item_new_with_mnemonic (_("_Previous Conversations")); + image = gtk_image_new_from_icon_name (EMPATHY_IMAGE_LOG, GTK_ICON_SIZE_MENU); + gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image); + gtk_widget_set_sensitive (item, have_log); + gtk_widget_show (image); + + g_signal_connect_swapped (item, "activate", + G_CALLBACK (individual_log_menu_item_activate_cb), individual); + + g_object_unref (contact); + + return item; +} + +static void +individual_file_transfer_menu_item_activate_cb (FolksIndividual *individual) +{ + EmpathyContact *contact; + + contact = empathy_contact_from_folks_individual (individual); + + g_return_if_fail (EMPATHY_IS_CONTACT (contact)); + + empathy_send_file_with_file_chooser (contact); + + g_object_unref (contact); +} + +GtkWidget * +empathy_individual_file_transfer_menu_item_new (FolksIndividual *individual) +{ + GtkWidget *item; + GtkWidget *image; + EmpathyContact *contact; + + g_return_val_if_fail (FOLKS_IS_INDIVIDUAL (individual), NULL); + + contact = empathy_contact_from_folks_individual (individual); + + 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 (individual_file_transfer_menu_item_activate_cb), individual); + + g_object_unref (contact); + + return item; +} + +static void +individual_share_my_desktop_menu_item_activate_cb (FolksIndividual *individual) +{ + EmpathyContact *contact; + + contact = empathy_contact_from_folks_individual (individual); + + g_return_if_fail (EMPATHY_IS_CONTACT (contact)); + + empathy_share_my_desktop_share_with_contact (contact); + + g_object_unref (contact); +} + +/* FIXME we should check if the individual supports vnc stream tube */ +GtkWidget * +empathy_individual_share_my_desktop_menu_item_new (FolksIndividual *individual) +{ + GtkWidget *item; + GtkWidget *image; + EmpathyContact *contact; + + g_return_val_if_fail (FOLKS_IS_INDIVIDUAL (individual), NULL); + + contact = empathy_contact_from_folks_individual (individual); + + g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL); + + item = gtk_image_menu_item_new_with_mnemonic (_("Share My Desktop")); + image = gtk_image_new_from_icon_name (GTK_STOCK_NETWORK, GTK_ICON_SIZE_MENU); + gtk_widget_set_sensitive (item, + empathy_contact_can_use_stream_tube (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 (individual_share_my_desktop_menu_item_activate_cb), + individual); + + g_object_unref (contact); + + return item; +} + +#if HAVE_FAVOURITE_CONTACTS +static void +favourite_menu_item_toggled_cb (GtkCheckMenuItem *item, + FolksIndividual *individual) +{ + EmpathyIndividualManager *manager; + FolksIndividualList *list; + + manager = empathy_individual_manager_dup_singleton (); + list = EMPATHY_INDIVIDUAL_MANAGER (manager); + + if (gtk_check_menu_item_get_active (item)) + empathy_individual_manager_add_to_favourites (list, individual); + else + empathy_individual_manager_remove_from_favourites (list, individual); + + g_object_unref (manager); +} + +GtkWidget * +empathy_individual_favourite_menu_item_new (FolksIndividual *individual) +{ + GtkWidget *item; + EmpathyIndividualManager *manager; + + item = gtk_check_menu_item_new_with_label (_("Favorite")); + + manager = empathy_individual_manager_dup_singleton (); + gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (item), + empathy_individual_manager_is_favourite ( + EMPATHY_INDIVIDUAL_MANAGER (manager), individual)); + + g_signal_connect (item, "toggled", + G_CALLBACK (favourite_menu_item_toggled_cb), individual); + + g_object_unref (manager); + return item; +} +#endif + +static void +individual_info_menu_item_activate_cb (FolksIndividual *individual) +{ + EmpathyContact *contact; + + contact = empathy_contact_from_folks_individual (individual); + empathy_contact_information_dialog_show (contact, NULL); +} + +GtkWidget * +empathy_individual_info_menu_item_new (FolksIndividual *individual) +{ + GtkWidget *item; + GtkWidget *image; + + g_return_val_if_fail (FOLKS_IS_INDIVIDUAL (individual), NULL); + g_return_val_if_fail (empathy_folks_individual_contains_contact (individual), + NULL); + + item = gtk_image_menu_item_new_with_mnemonic (_("Infor_mation")); + image = gtk_image_new_from_icon_name (EMPATHY_IMAGE_CONTACT_INFORMATION, + GTK_ICON_SIZE_MENU); + gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image); + gtk_widget_show (image); + + g_signal_connect_swapped (item, "activate", + G_CALLBACK (individual_info_menu_item_activate_cb), + individual); + + return item; +} + +static void +individual_edit_menu_item_activate_cb (FolksIndividual *individual) +{ + EmpathyContact *contact; + + contact = empathy_contact_from_folks_individual (individual); + empathy_contact_edit_dialog_show (contact, NULL); +} + +GtkWidget * +empathy_individual_edit_menu_item_new (FolksIndividual *individual) +{ + EmpathyIndividualManager *manager; + GtkWidget *item; + GtkWidget *image; + gboolean enable = FALSE; + EmpathyContact *contact; + + g_return_val_if_fail (FOLKS_IS_INDIVIDUAL (individual), NULL); + + contact = empathy_contact_from_folks_individual (individual); + + g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL); + + if (empathy_individual_manager_initialized ()) + { + TpConnection *connection; + EmpathyIndividualManagerFlags flags; + + manager = empathy_individual_manager_dup_singleton (); + connection = empathy_contact_get_connection (contact); + flags = empathy_individual_manager_get_flags_for_connection ( + manager, connection); + + enable = (flags & EMPATHY_INDIVIDUAL_MANAGER_CAN_ALIAS || + flags & EMPATHY_INDIVIDUAL_MANAGER_CAN_GROUP); + + g_object_unref (manager); + } + + item = gtk_image_menu_item_new_with_mnemonic ( + C_("Edit individual (contextual menu)", "_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 (individual_edit_menu_item_activate_cb), individual); + + g_object_unref (contact); + + return item; +} + +typedef struct +{ + FolksIndividual *individual; + EmpathyChatroom *chatroom; +} RoomSubMenuData; + +static RoomSubMenuData * +room_sub_menu_data_new (FolksIndividual *individual, + EmpathyChatroom *chatroom) +{ + RoomSubMenuData *data; + + data = g_slice_new (RoomSubMenuData); + data->individual = g_object_ref (individual); + data->chatroom = g_object_ref (chatroom); + return data; +} + +static void +room_sub_menu_data_free (RoomSubMenuData *data) +{ + g_object_unref (data->individual); + g_object_unref (data->chatroom); + g_slice_free (RoomSubMenuData, data); +} + +static void +room_sub_menu_activate_cb (GtkWidget *item, + RoomSubMenuData *data) +{ + EmpathyTpChat *chat; + EmpathyContact *contact; + + chat = empathy_chatroom_get_tp_chat (data->chatroom); + if (chat == NULL) + { + /* channel was invalidated. Ignoring */ + return; + } + + contact = empathy_contact_from_folks_individual (data->individual); + + g_return_if_fail (EMPATHY_IS_CONTACT (contact)); + + /* send invitation */ + empathy_contact_list_add (EMPATHY_CONTACT_LIST (chat), + contact, _("Inviting you to this room")); + + g_object_unref (contact); +} + +static GtkWidget * +create_room_sub_menu (FolksIndividual *individual, + EmpathyChatroom *chatroom) +{ + GtkWidget *item; + RoomSubMenuData *data; + + item = gtk_menu_item_new_with_label (empathy_chatroom_get_name (chatroom)); + data = room_sub_menu_data_new (individual, 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_individual_invite_menu_item_new (FolksIndividual *individual) +{ + GtkWidget *item; + GtkWidget *image; + GtkWidget *room_item; + EmpathyChatroomManager *mgr; + GList *rooms, *l; + GtkWidget *submenu = NULL; + EmpathyContact *contact; + + g_return_val_if_fail (FOLKS_IS_INDIVIDUAL (individual), NULL); + + contact = empathy_contact_from_folks_individual (individual); + + g_return_val_if_fail (EMPATHY_IS_CONTACT (contact), NULL); + + item = gtk_image_menu_item_new_with_mnemonic (_("_Invite to Chat Room")); + 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 (individual, 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 (contact); + g_object_unref (mgr); + g_list_free (rooms); + + return item; +} diff --git a/libempathy-gtk/empathy-individual-menu.h b/libempathy-gtk/empathy-individual-menu.h index 5d228972d..37b93ea4b 100644 --- a/libempathy-gtk/empathy-individual-menu.h +++ b/libempathy-gtk/empathy-individual-menu.h @@ -38,6 +38,26 @@ typedef enum { EMPATHY_INDIVIDUAL_FEATURE_ALL = (1 << 6) - 1, } EmpathyIndividualFeatureFlags; +GtkWidget * empathy_individual_menu_new (FolksIndividual *individual, + EmpathyIndividualFeatureFlags features); +GtkWidget * empathy_individual_add_menu_item_new (FolksIndividual *individual); +GtkWidget * empathy_individual_chat_menu_item_new (FolksIndividual *individual); +GtkWidget * empathy_individual_audio_call_menu_item_new ( + FolksIndividual *individual); +GtkWidget * empathy_individual_video_call_menu_item_new ( + FolksIndividual *individual); +GtkWidget * empathy_individual_log_menu_item_new (FolksIndividual *individual); +GtkWidget * empathy_individual_info_menu_item_new (FolksIndividual *individual); +GtkWidget * empathy_individual_edit_menu_item_new (FolksIndividual *individual); +GtkWidget * empathy_individual_invite_menu_item_new ( + FolksIndividual *individual); +GtkWidget * empathy_individual_file_transfer_menu_item_new ( + FolksIndividual *individual); +GtkWidget * empathy_individual_share_my_desktop_menu_item_new ( + FolksIndividual *individual); +GtkWidget * empathy_individual_favourite_menu_item_new ( + FolksIndividual *individual); + G_END_DECLS #endif /* __EMPATHY_INDIVIDUAL_MENU_H__ */ diff --git a/libempathy-gtk/empathy-individual-store.c b/libempathy-gtk/empathy-individual-store.c index 0e3dd259e..3390f31df 100644 --- a/libempathy-gtk/empathy-individual-store.c +++ b/libempathy-gtk/empathy-individual-store.c @@ -117,10 +117,11 @@ G_DEFINE_TYPE (EmpathyIndividualStore, empathy_individual_store, static void add_individual_to_store (GtkTreeStore *self, GtkTreeIter *iter, + GtkTreeIter *parent, FolksIndividual *individual, EmpathyIndividualManagerFlags flags) { - gtk_tree_store_set (self, iter, + gtk_tree_store_insert_with_values (self, iter, parent, 0, EMPATHY_INDIVIDUAL_STORE_COL_NAME, folks_individual_get_alias (individual), EMPATHY_INDIVIDUAL_STORE_COL_INDIVIDUAL, individual, @@ -132,7 +133,8 @@ add_individual_to_store (GtkTreeStore *self, EMPATHY_INDIVIDUAL_STORE_COL_CAN_VIDEO_CALL, folks_individual_get_capabilities (individual) & FOLKS_CAPABILITIES_FLAGS_VIDEO, - EMPATHY_INDIVIDUAL_STORE_COL_FLAGS, flags, -1); + EMPATHY_INDIVIDUAL_STORE_COL_FLAGS, flags, + -1); } static gboolean @@ -391,10 +393,7 @@ individual_store_add_individual (EmpathyIndividualStore *self, &iter_group, NULL, NULL, TRUE); } - gtk_tree_store_insert_after (GTK_TREE_STORE (self), &iter, - parent, NULL); - - add_individual_to_store (GTK_TREE_STORE (self), &iter, + add_individual_to_store (GTK_TREE_STORE (self), &iter, parent, individual, flags); } @@ -406,10 +405,7 @@ individual_store_add_individual (EmpathyIndividualStore *self, individual_store_get_group (self, l->data, &iter_group, NULL, NULL, FALSE); - gtk_tree_store_insert_after (GTK_TREE_STORE (self), &iter, - &iter_group, NULL); - - add_individual_to_store (GTK_TREE_STORE (self), &iter, + add_individual_to_store (GTK_TREE_STORE (self), &iter, &iter_group, individual, flags); } g_list_free (groups); @@ -426,10 +422,7 @@ individual_store_add_individual (EmpathyIndividualStore *self, individual_store_get_group (self, EMPATHY_INDIVIDUAL_STORE_FAVORITE, &iter_group, NULL, NULL, TRUE); - gtk_tree_store_insert_after (GTK_TREE_STORE (self), &iter, - &iter_group, NULL); - - add_individual_to_store (GTK_TREE_STORE (self), &iter, + add_individual_to_store (GTK_TREE_STORE (self), &iter, &iter_group, individual, flags); } #endif @@ -456,7 +449,8 @@ individual_store_contact_set_active (EmpathyIndividualStore *self, GtkTreePath *path; gtk_tree_store_set (GTK_TREE_STORE (self), l->data, - EMPATHY_INDIVIDUAL_STORE_COL_IS_ACTIVE, active, -1); + EMPATHY_INDIVIDUAL_STORE_COL_IS_ACTIVE, active, + -1); DEBUG ("Set item %s", active ? "active" : "inactive"); @@ -686,21 +680,22 @@ individual_store_contact_update (EmpathyIndividualStore *self, EMPATHY_INDIVIDUAL_STORE_COL_ICON_STATUS, pixbuf_status, EMPATHY_INDIVIDUAL_STORE_COL_PIXBUF_AVATAR_VISIBLE, show_avatar, EMPATHY_INDIVIDUAL_STORE_COL_NAME, - folks_individual_get_alias (individual), + folks_individual_get_alias (individual), EMPATHY_INDIVIDUAL_STORE_COL_PRESENCE_TYPE, - folks_individual_get_presence_type (individual), + folks_individual_get_presence_type (individual), EMPATHY_INDIVIDUAL_STORE_COL_STATUS, - folks_individual_get_presence_message (individual), + folks_individual_get_presence_message (individual), EMPATHY_INDIVIDUAL_STORE_COL_CAN_AUDIO_CALL, - folks_individual_get_capabilities (individual) & - FOLKS_CAPABILITIES_FLAGS_AUDIO, + folks_individual_get_capabilities (individual) & + FOLKS_CAPABILITIES_FLAGS_AUDIO, EMPATHY_INDIVIDUAL_STORE_COL_CAN_VIDEO_CALL, - folks_individual_get_capabilities (individual) & - FOLKS_CAPABILITIES_FLAGS_VIDEO, + folks_individual_get_capabilities (individual) & + FOLKS_CAPABILITIES_FLAGS_VIDEO, EMPATHY_INDIVIDUAL_STORE_COL_COMPACT, priv->is_compact, EMPATHY_INDIVIDUAL_STORE_COL_IS_GROUP, FALSE, EMPATHY_INDIVIDUAL_STORE_COL_IS_ONLINE, now_online, - EMPATHY_INDIVIDUAL_STORE_COL_IS_SEPARATOR, FALSE, -1); + EMPATHY_INDIVIDUAL_STORE_COL_IS_SEPARATOR, FALSE, + -1); } if (priv->show_active && do_set_active) diff --git a/libempathy-gtk/empathy-individual-view.c b/libempathy-gtk/empathy-individual-view.c index 83b01964b..b6df6d7c9 100644 --- a/libempathy-gtk/empathy-individual-view.c +++ b/libempathy-gtk/empathy-individual-view.c @@ -770,20 +770,17 @@ individual_view_popup_menu_idle_cb (gpointer user_data) GtkWidget *menu; menu = empathy_individual_view_get_individual_menu (data->view); - if (!menu) - { - menu = empathy_individual_view_get_group_menu (data->view); - } + if (menu == NULL) + menu = empathy_individual_view_get_group_menu (data->view); - if (menu) + if (menu != NULL) { - g_signal_connect (menu, "deactivate", - G_CALLBACK (gtk_menu_detach), NULL); - gtk_menu_attach_to_widget (GTK_MENU (menu), - GTK_WIDGET (data->view), NULL); + g_signal_connect (menu, "deactivate", G_CALLBACK (gtk_menu_detach), NULL); + gtk_menu_attach_to_widget (GTK_MENU (menu), GTK_WIDGET (data->view), + NULL); gtk_widget_show (menu); - gtk_menu_popup (GTK_MENU (menu), - NULL, NULL, NULL, NULL, data->button, data->time); + gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, data->button, + data->time); g_object_ref_sink (menu); g_object_unref (menu); } @@ -2064,8 +2061,7 @@ empathy_individual_view_get_individual_menu (EmpathyIndividualView *view) } flags = empathy_individual_view_get_flags (view); - /* TODO: implement (create the menu here */ - DEBUG ("individual menu not implemented"); + menu = empathy_individual_menu_new (individual, priv->individual_features); /* Remove contact */ if (priv->view_features & diff --git a/libempathy/empathy-individual-manager.c b/libempathy/empathy-individual-manager.c index 4b27e74a0..0af191ad1 100644 --- a/libempathy/empathy-individual-manager.c +++ b/libempathy/empathy-individual-manager.c @@ -288,3 +288,33 @@ empathy_individual_manager_remove (EmpathyIndividualManager *self, /* TODO: implement */ DEBUG (G_STRLOC ": individual removal not implemented"); } + +EmpathyIndividualManagerFlags +empathy_individual_manager_get_flags_for_connection ( + EmpathyIndividualManager *self, + TpConnection *connection) +{ + EmpathyIndividualManagerPriv *priv; + EmpathyContactListFlags list_flags; + EmpathyIndividualManagerFlags flags; + + g_return_val_if_fail (EMPATHY_IS_INDIVIDUAL_MANAGER (self), + EMPATHY_INDIVIDUAL_MANAGER_NO_FLAGS); + + priv = GET_PRIV (self); + + list_flags = empathy_contact_manager_get_flags_for_connection ( + priv->contact_manager, connection); + + flags = EMPATHY_INDIVIDUAL_MANAGER_NO_FLAGS; + if (list_flags & EMPATHY_CONTACT_LIST_CAN_ADD) + flags |= EMPATHY_INDIVIDUAL_MANAGER_CAN_ADD; + if (list_flags & EMPATHY_CONTACT_LIST_CAN_REMOVE) + flags |= EMPATHY_INDIVIDUAL_MANAGER_CAN_REMOVE; + if (list_flags & EMPATHY_CONTACT_LIST_CAN_ALIAS) + flags |= EMPATHY_INDIVIDUAL_MANAGER_CAN_ALIAS; + if (list_flags & EMPATHY_CONTACT_LIST_CAN_GROUP) + flags |= EMPATHY_INDIVIDUAL_MANAGER_CAN_GROUP; + + return flags; +} diff --git a/libempathy/empathy-individual-manager.h b/libempathy/empathy-individual-manager.h index 1823dec5a..be95ab357 100644 --- a/libempathy/empathy-individual-manager.h +++ b/libempathy/empathy-individual-manager.h @@ -37,6 +37,7 @@ G_BEGIN_DECLS #define EMPATHY_INDIVIDUAL_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), EMPATHY_TYPE_INDIVIDUAL_MANAGER, EmpathyIndividualManagerClass)) typedef enum { + EMPATHY_INDIVIDUAL_MANAGER_NO_FLAGS = 0, EMPATHY_INDIVIDUAL_MANAGER_CAN_ADD = 1 << 0, EMPATHY_INDIVIDUAL_MANAGER_CAN_REMOVE = 1 << 1, EMPATHY_INDIVIDUAL_MANAGER_CAN_ALIAS = 1 << 2, @@ -78,5 +79,10 @@ gboolean empathy_individual_manager_is_favourite ( EmpathyIndividualManager *manager, FolksIndividual *individual); +EmpathyIndividualManagerFlags +empathy_individual_manager_get_flags_for_connection ( + EmpathyIndividualManager *manager, + TpConnection *connection); + G_END_DECLS #endif /* __EMPATHY_INDIVIDUAL_MANAGER_H__ */ diff --git a/libempathy/empathy-utils.c b/libempathy/empathy-utils.c index 56da323b9..df2a41abd 100644 --- a/libempathy/empathy-utils.c +++ b/libempathy/empathy-utils.c @@ -569,6 +569,30 @@ empathy_folks_presence_type_to_tp (FolksPresenceType type) return (TpConnectionPresenceType) type; } +gboolean +empathy_folks_individual_contains_contact (FolksIndividual *individual) +{ + GList *personas, *l; + + g_return_val_if_fail (FOLKS_IS_INDIVIDUAL (individual), FALSE); + + personas = folks_individual_get_personas (individual); + for (l = personas; l != NULL; l = l->next) + { + TpfPersona *persona = l->data; + + if (TPF_IS_PERSONA (persona)) + { + TpContact *contact = tpf_persona_get_contact (persona); + + if (TP_IS_CONTACT (contact)) + return TRUE; + } + } + + return FALSE; +} + EmpathyContact * empathy_contact_from_folks_individual (FolksIndividual *individual) { diff --git a/libempathy/empathy-utils.h b/libempathy/empathy-utils.h index 1ba7e53f8..c6de97a8f 100644 --- a/libempathy/empathy-utils.h +++ b/libempathy/empathy-utils.h @@ -91,6 +91,7 @@ void empathy_connect_new_account (TpAccount *account, TpAccountManager *account_manager); TpConnectionPresenceType empathy_folks_presence_type_to_tp (FolksPresenceType type); +gboolean empathy_folks_individual_contains_contact (FolksIndividual *individual); EmpathyContact * empathy_contact_from_folks_individual (FolksIndividual *individual); G_END_DECLS diff --git a/src/empathy-main-window.c b/src/empathy-main-window.c index 9117c1b62..0e596fe0a 100644 --- a/src/empathy-main-window.c +++ b/src/empathy-main-window.c @@ -182,6 +182,9 @@ main_window_flash_foreach (GtkTreeModel *model, &individual, -1); + if (individual == NULL) + return FALSE; + contact = empathy_contact_from_folks_individual (individual); if (contact != data->event->contact) { if (contact) { |