#include "empathy-chat.h"
#include "empathy-conf.h"
#include "empathy-spell.h"
-#include "empathy-spell-dialog.h"
#include "empathy-contact-list-store.h"
#include "empathy-contact-list-view.h"
#include "empathy-contact-menu.h"
#define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyChat)
typedef struct {
EmpathyTpChat *tp_chat;
- gulong tp_chat_destroy_handler;
McAccount *account;
gchar *id;
gchar *name;
}
static void
-chat_connection_changed_cb (EmpathyAccountManager *manager,
- McAccount *account,
- TpConnectionStatusReason reason,
- TpConnectionStatus current,
- TpConnectionStatus previous,
- EmpathyChat *chat)
+chat_connect_channel_reconnected (EmpathyDispatchOperation *dispatch,
+ const GError *error,
+ gpointer user_data)
+{
+ EmpathyChat *chat = EMPATHY_CHAT (user_data);
+ EmpathyTpChat *tpchat;
+
+ if (error != NULL) {
+ empathy_chat_view_append_event (chat->view,
+ _("Failed to reconnect this chat"));
+ return;
+ }
+
+ tpchat = EMPATHY_TP_CHAT (
+ empathy_dispatch_operation_get_channel_wrapper (dispatch));
+
+ if (empathy_dispatch_operation_claim (dispatch)) {
+ empathy_chat_set_tp_chat (chat, tpchat);
+ }
+}
+
+static void
+chat_new_connection_cb (EmpathyAccountManager *manager,
+ TpConnection *connection,
+ EmpathyChat *chat)
{
EmpathyChatPriv *priv = GET_PRIV (chat);
+ McAccount *account;
- if (current == TP_CONNECTION_STATUS_CONNECTED && !priv->tp_chat &&
- empathy_account_equal (account, priv->account) &&
+ account = empathy_account_manager_get_account (manager, connection);
+ if (!priv->tp_chat && empathy_account_equal (account, priv->account) &&
priv->handle_type != TP_HANDLE_TYPE_NONE &&
- !EMP_IS_EMPTY (priv->id)) {
+ !EMP_STR_EMPTY (priv->id)) {
DEBUG ("Account reconnected, request a new Text channel");
switch (priv->handle_type) {
case TP_HANDLE_TYPE_CONTACT:
- empathy_dispatcher_chat_with_contact_id (account, priv->id,
- NULL, NULL);
+ empathy_dispatcher_chat_with_contact_id (
+ connection, priv->id,
+ chat_connect_channel_reconnected,
+ chat);
break;
case TP_HANDLE_TYPE_ROOM:
- empathy_dispatcher_join_muc (account, priv->id, NULL, NULL);
+ empathy_dispatcher_join_muc (connection,
+ priv->id,
+ chat_connect_channel_reconnected,
+ chat);
break;
default:
g_assert_not_reached ();
EmpathyChatPriv *priv;
EmpathyMessage *message;
- priv = GET_PRIV (chat);
-
if (EMP_STR_EMPTY (msg)) {
return;
}
+ priv = GET_PRIV (chat);
+
chat_sent_message_add (chat, msg);
if (g_str_has_prefix (msg, "/clear")) {
return;
}
- message = empathy_message_new (msg);
+ /* Blacklist messages begining by '/', except for "/me" and "/say"
+ * because they are handled in EmpathyMessage */
+ if (msg[0] == '/' &&
+ !g_str_has_prefix (msg, "/me") &&
+ !g_str_has_prefix (msg, "/say")) {
+ empathy_chat_view_append_event (chat->view,
+ _("Unsupported command"));
+ return;
+ }
+ /* We can send the message */
+ message = empathy_message_new (msg);
empathy_tp_chat_send (priv->tp_chat, message);
-
g_object_unref (message);
}
}
}
-static gboolean
-chat_get_is_command (const gchar *str)
-{
- g_return_val_if_fail (str != NULL, FALSE);
-
- if (str[0] != '/') {
- return FALSE;
- }
-
- if (g_str_has_prefix (str, "/me")) {
- return TRUE;
- }
- else if (g_str_has_prefix (str, "/nick")) {
- return TRUE;
- }
- else if (g_str_has_prefix (str, "/topic")) {
- return TRUE;
- }
-
- return FALSE;
-}
-
static void
chat_input_text_buffer_changed_cb (GtkTextBuffer *buffer,
- EmpathyChat *chat)
+ EmpathyChat *chat)
{
EmpathyChatPriv *priv;
GtkTextIter start, end;
}
empathy_conf_get_bool (empathy_conf_get (),
- EMPATHY_PREFS_CHAT_SPELL_CHECKER_ENABLED,
- &spell_checker);
+ EMPATHY_PREFS_CHAT_SPELL_CHECKER_ENABLED,
+ &spell_checker);
gtk_text_buffer_get_start_iter (buffer, &start);
str = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
- /* spell check string */
- if (!chat_get_is_command (str)) {
+ /* spell check string if not a command */
+ if (str[0] != '/') {
correct = empathy_spell_check (str);
} else {
correct = TRUE;
}
static void
-chat_text_check_word_spelling_cb (GtkMenuItem *menuitem,
- EmpathyChatSpell *chat_spell)
+chat_spelling_menu_activate_cb (GtkMenuItem *menu_item,
+ EmpathyChatSpell *chat_spell)
{
- empathy_spell_dialog_show (chat_spell->chat,
- &chat_spell->start,
- &chat_spell->end,
- chat_spell->word);
+ empathy_chat_correct_word (chat_spell->chat,
+ &(chat_spell->start),
+ &(chat_spell->end),
+ gtk_menu_item_get_label (menu_item));
+}
+
+static GtkWidget*
+chat_spelling_build_menu (EmpathyChatSpell *chat_spell)
+{
+ GtkWidget *menu, *menu_item;
+ GList *suggestions, *l;
+
+ menu = gtk_menu_new ();
+ suggestions = empathy_spell_get_suggestions (chat_spell->word);
+ if (suggestions == NULL) {
+ menu_item = gtk_menu_item_new_with_label (_("(No Suggestions)"));
+ gtk_widget_set_sensitive (menu_item, FALSE);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
+ } else {
+ for (l = suggestions; l; l = l->next) {
+ menu_item = gtk_menu_item_new_with_label (l->data);
+ g_signal_connect (G_OBJECT (menu_item),
+ "activate",
+ G_CALLBACK (chat_spelling_menu_activate_cb),
+ chat_spell);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
+ }
+ }
+ empathy_spell_free_suggestions (suggestions);
+
+ gtk_widget_show_all (menu);
+
+ return menu;
}
static void
GtkTextIter iter, start, end;
GtkWidget *item;
gchar *str = NULL;
- EmpathyChatSpell *chat_spell;
+ EmpathyChatSpell *chat_spell;
+ GtkWidget *spell_menu;
EmpathySmileyManager *smiley_manager;
GtkWidget *smiley_menu;
GtkWidget *image;
gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), item);
gtk_widget_show (item);
- item = gtk_image_menu_item_new_with_mnemonic (_("_Check Word Spelling..."));
+ item = gtk_image_menu_item_new_with_mnemonic (_("_Spelling Suggestions"));
image = gtk_image_new_from_icon_name (GTK_STOCK_SPELL_CHECK,
GTK_ICON_SIZE_MENU);
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (item), image);
- g_signal_connect (item,
- "activate",
- G_CALLBACK (chat_text_check_word_spelling_cb),
- chat_spell);
+
+ spell_menu = chat_spelling_build_menu (chat_spell);
+ gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), spell_menu);
+
gtk_menu_shell_prepend (GTK_MENU_SHELL (menu), item);
gtk_widget_show (item);
}
if (priv->block_events_timeout_id == 0) {
gchar *str;
- empathy_contact_run_until_ready (contact,
- EMPATHY_CONTACT_READY_NAME,
- NULL);
-
if (is_member) {
str = g_strdup_printf (_("%s has joined the room"),
empathy_contact_get_name (contact));
return;
}
+ chat_composing_remove_timeout (chat);
g_object_unref (priv->tp_chat);
priv->tp_chat = NULL;
g_object_notify (G_OBJECT (chat), "tp-chat");
chat_create_ui (EmpathyChat *chat)
{
EmpathyChatPriv *priv = GET_PRIV (chat);
- GladeXML *glade;
+ GtkBuilder *gui;
GList *list = NULL;
gchar *filename;
GtkTextBuffer *buffer;
- filename = empathy_file_lookup ("empathy-chat.glade",
+ filename = empathy_file_lookup ("empathy-chat.ui",
"libempathy-gtk");
- glade = empathy_glade_get_file (filename,
- "chat_widget",
- NULL,
+ gui = empathy_builder_get_file (filename,
"chat_widget", &priv->widget,
"hpaned", &priv->hpaned,
"vbox_left", &priv->vbox_left,
"scrolled_window_contacts", &priv->scrolled_window_contacts,
NULL);
g_free (filename);
- g_object_unref (glade);
/* Add message view. */
chat->view = empathy_theme_manager_create_view (empathy_theme_manager_get ());
/* Add the main widget in the chat widget */
gtk_container_add (GTK_CONTAINER (chat), priv->widget);
+ g_object_unref (gui);
}
static void
chat_composing_remove_timeout (chat);
g_signal_handlers_disconnect_by_func (priv->account_manager,
- chat_connection_changed_cb, object);
+ chat_new_connection_cb, object);
g_object_unref (priv->account_manager);
g_object_unref (priv->log_manager);
if (priv->tp_chat) {
- g_signal_handler_disconnect (priv->tp_chat, priv->tp_chat_destroy_handler);
+ g_signal_handlers_disconnect_by_func (priv->tp_chat,
+ chat_destroy_cb, chat);
+ g_signal_handlers_disconnect_by_func (priv->tp_chat,
+ chat_message_received_cb, chat);
+ g_signal_handlers_disconnect_by_func (priv->tp_chat,
+ chat_send_error_cb, chat);
+ g_signal_handlers_disconnect_by_func (priv->tp_chat,
+ chat_state_changed_cb, chat);
+ g_signal_handlers_disconnect_by_func (priv->tp_chat,
+ chat_property_changed_cb, chat);
+ g_signal_handlers_disconnect_by_func (priv->tp_chat,
+ chat_members_changed_cb, chat);
+ g_signal_handlers_disconnect_by_func (priv->tp_chat,
+ chat_remote_contact_changed_cb, chat);
empathy_tp_chat_close (priv->tp_chat);
g_object_unref (priv->tp_chat);
}
g_free (priv->id);
g_free (priv->name);
g_free (priv->subject);
+ g_completion_free (priv->completion);
G_OBJECT_CLASS (empathy_chat_parent_class)->finalize (object);
}
priv->account_manager = empathy_account_manager_dup_singleton ();
g_signal_connect (priv->account_manager,
- "account-connection-changed",
- G_CALLBACK (chat_connection_changed_cb),
+ "new-connection",
+ G_CALLBACK (chat_new_connection_cb),
chat);
/* Block events for some time to avoid having "has come online" or
EmpathyTpChat *tp_chat)
{
EmpathyChatPriv *priv = GET_PRIV (chat);
+ TpConnection *connection;
g_return_if_fail (EMPATHY_IS_CHAT (chat));
g_return_if_fail (EMPATHY_IS_TP_CHAT (tp_chat));
}
priv->tp_chat = g_object_ref (tp_chat);
- priv->account = g_object_ref (empathy_tp_chat_get_account (tp_chat));
+ connection = empathy_tp_chat_get_connection (priv->tp_chat);
+ priv->account = empathy_account_manager_get_account (priv->account_manager,
+ connection);
+ g_object_ref (priv->account);
+ g_signal_connect (tp_chat, "destroy",
+ G_CALLBACK (chat_destroy_cb),
+ chat);
g_signal_connect (tp_chat, "message-received",
G_CALLBACK (chat_message_received_cb),
chat);
g_signal_connect_swapped (tp_chat, "notify::remote-contact",
G_CALLBACK (chat_remote_contact_changed_cb),
chat);
- priv->tp_chat_destroy_handler =
- g_signal_connect (tp_chat, "destroy",
- G_CALLBACK (chat_destroy_cb),
- chat);
chat_remote_contact_changed_cb (chat);
return priv->remote_contact;
}
-guint
-empathy_chat_get_members_count (EmpathyChat *chat)
-{
- EmpathyChatPriv *priv = GET_PRIV (chat);
-
- g_return_val_if_fail (EMPATHY_IS_CHAT (chat), 0);
-
- if (priv->tp_chat) {
- return empathy_tp_chat_get_members_count (priv->tp_chat);
- }
-
- return 0;
-}
-
GtkWidget *
empathy_chat_get_contact_menu (EmpathyChat *chat)
{