aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libempathy-gtk/Makefile.am1
-rw-r--r--libempathy-gtk/empathy-individual-menu.c769
-rw-r--r--libempathy-gtk/empathy-individual-menu.h20
-rw-r--r--libempathy-gtk/empathy-individual-store.c41
-rw-r--r--libempathy-gtk/empathy-individual-view.c22
-rw-r--r--libempathy/empathy-individual-manager.c30
-rw-r--r--libempathy/empathy-individual-manager.h6
-rw-r--r--libempathy/empathy-utils.c24
-rw-r--r--libempathy/empathy-utils.h1
-rw-r--r--src/empathy-main-window.c3
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) {