From: Xavier Claessens Date: Wed, 2 Apr 2008 09:41:50 +0000 (+0000) Subject: Rework EmpathyChat's API, it is now a subclass of GtkBin. X-Git-Url: https://git.0d.be/?p=empathy.git;a=commitdiff_plain;h=137e275fa6bf039dd5581483bf0cd9ed5be88914 Rework EmpathyChat's API, it is now a subclass of GtkBin. svn path=/trunk/; revision=840 --- diff --git a/libempathy-gtk/empathy-chat-view.c b/libempathy-gtk/empathy-chat-view.c index d67f9c4d..bd13f299 100644 --- a/libempathy-gtk/empathy-chat-view.c +++ b/libempathy-gtk/empathy-chat-view.c @@ -749,6 +749,61 @@ empathy_chat_view_new (void) return g_object_new (EMPATHY_TYPE_CHAT_VIEW, NULL); } +/* Code stolen from pidgin/gtkimhtml.c */ +static gboolean +chat_view_scroll_cb (EmpathyChatView *view) +{ + EmpathyChatViewPriv *priv; + GtkAdjustment *adj; + gdouble max_val; + + priv = GET_PRIV (view); + adj = GTK_TEXT_VIEW (view)->vadjustment; + max_val = adj->upper - adj->page_size; + + g_return_val_if_fail (priv->scroll_time != NULL, FALSE); + + if (g_timer_elapsed (priv->scroll_time, NULL) > MAX_SCROLL_TIME) { + /* time's up. jump to the end and kill the timer */ + gtk_adjustment_set_value (adj, max_val); + g_timer_destroy (priv->scroll_time); + priv->scroll_time = NULL; + priv->scroll_timeout = 0; + return FALSE; + } + + /* scroll by 1/3rd the remaining distance */ + gtk_adjustment_set_value (adj, gtk_adjustment_get_value (adj) + ((max_val - gtk_adjustment_get_value (adj)) / 3)); + return TRUE; +} + +void +empathy_chat_view_scroll_down (EmpathyChatView *view) +{ + EmpathyChatViewPriv *priv; + + g_return_if_fail (EMPATHY_IS_CHAT_VIEW (view)); + + priv = GET_PRIV (view); + + if (!priv->allow_scrolling) { + return; + } + + empathy_debug (DEBUG_DOMAIN, "Scrolling down"); + + if (priv->scroll_time) { + g_timer_reset (priv->scroll_time); + } else { + priv->scroll_time = g_timer_new(); + } + if (!priv->scroll_timeout) { + priv->scroll_timeout = g_timeout_add (SCROLL_DELAY, + (GSourceFunc) chat_view_scroll_cb, + view); + } +} + void empathy_chat_view_append_message (EmpathyChatView *view, EmpathyMessage *msg) @@ -884,70 +939,16 @@ void empathy_chat_view_scroll (EmpathyChatView *view, gboolean allow_scrolling) { - EmpathyChatViewPriv *priv; + EmpathyChatViewPriv *priv = GET_PRIV (view); g_return_if_fail (EMPATHY_IS_CHAT_VIEW (view)); - priv = GET_PRIV (view); - - priv->allow_scrolling = allow_scrolling; - empathy_debug (DEBUG_DOMAIN, "Scrolling %s", allow_scrolling ? "enabled" : "disabled"); -} - -/* Code stolen from pidgin/gtkimhtml.c */ -static gboolean -chat_view_scroll_cb (EmpathyChatView *view) -{ - EmpathyChatViewPriv *priv; - GtkAdjustment *adj; - gdouble max_val; - - priv = GET_PRIV (view); - adj = GTK_TEXT_VIEW (view)->vadjustment; - max_val = adj->upper - adj->page_size; - - g_return_val_if_fail (priv->scroll_time != NULL, FALSE); - - if (g_timer_elapsed (priv->scroll_time, NULL) > MAX_SCROLL_TIME) { - /* time's up. jump to the end and kill the timer */ - gtk_adjustment_set_value (adj, max_val); - g_timer_destroy (priv->scroll_time); - priv->scroll_time = NULL; - priv->scroll_timeout = 0; - return FALSE; - } - - /* scroll by 1/3rd the remaining distance */ - gtk_adjustment_set_value (adj, gtk_adjustment_get_value (adj) + ((max_val - gtk_adjustment_get_value (adj)) / 3)); - return TRUE; -} - -void -empathy_chat_view_scroll_down (EmpathyChatView *view) -{ - EmpathyChatViewPriv *priv; - g_return_if_fail (EMPATHY_IS_CHAT_VIEW (view)); - - priv = GET_PRIV (view); - - if (!priv->allow_scrolling) { - return; - } - - empathy_debug (DEBUG_DOMAIN, "Scrolling down"); - - if (priv->scroll_time) { - g_timer_reset (priv->scroll_time); - } else { - priv->scroll_time = g_timer_new(); - } - if (!priv->scroll_timeout) { - priv->scroll_timeout = g_timeout_add (SCROLL_DELAY, - (GSourceFunc) chat_view_scroll_cb, - view); + priv->allow_scrolling = allow_scrolling; + if (allow_scrolling) { + empathy_chat_view_scroll_down (view); } } diff --git a/libempathy-gtk/empathy-chat.c b/libempathy-gtk/empathy-chat.c index 6d022595..59837830 100644 --- a/libempathy-gtk/empathy-chat.c +++ b/libempathy-gtk/empathy-chat.c @@ -25,7 +25,7 @@ * Xavier Claessens */ -#include "config.h" +#include #include #include @@ -35,21 +35,17 @@ #include #include - #include -#include #include #include #include #include "empathy-chat.h" -#include "empathy-geometry.h" #include "empathy-conf.h" #include "empathy-spell.h" #include "empathy-spell-dialog.h" #include "empathy-ui-utils.h" -#include "empathy-gtk-marshal.h" #define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EMPATHY_TYPE_CHAT, EmpathyChatPriv)) @@ -57,33 +53,25 @@ #define CHAT_DIR_CREATE_MODE (S_IRUSR | S_IWUSR | S_IXUSR) #define CHAT_FILE_CREATE_MODE (S_IRUSR | S_IWUSR) - #define IS_ENTER(v) (v == GDK_Return || v == GDK_ISO_Enter || v == GDK_KP_Enter) - #define MAX_INPUT_HEIGHT 150 - #define COMPOSING_STOP_TIMEOUT 5 struct _EmpathyChatPriv { EmpathyTpChat *tp_chat; + McAccount *account; gchar *name; - gchar *tooltip; - const gchar *icon_name; - GtkWidget *widget; + gchar *subject; + EmpathyContact *selected_contact; + gchar *id; EmpathyLogManager *log_manager; - McAccount *account; MissionControl *mc; - guint composing_stop_timeout_id; - gboolean sensitive; - gchar *id; GSList *sent_messages; gint sent_messages_index; GList *compositors; - guint scroll_idle_id; - gboolean first_tp_chat; GList *backlog_messages; - gboolean is_first_char; + guint composing_stop_timeout_id; guint block_events_timeout_id; TpHandleType handle_type; /* Used to automatically shrink a window that has temporarily @@ -93,6 +81,7 @@ struct _EmpathyChatPriv { gint default_window_height; gint last_input_height; gboolean vscroll_visible; + gboolean is_first_char; }; static void empathy_chat_class_init (EmpathyChatClass *klass); @@ -107,15 +96,16 @@ enum { enum { PROP_0, PROP_TP_CHAT, + PROP_ACCOUNT, PROP_NAME, - PROP_TOOLTIP, - PROP_ICON_NAME, - PROP_WIDGET + PROP_SUBJECT, + PROP_SELECTED_CONTACT, + PROP_ID }; static guint signals[LAST_SIGNAL] = { 0 }; -G_DEFINE_TYPE (EmpathyChat, empathy_chat, G_TYPE_OBJECT); +G_DEFINE_TYPE (EmpathyChat, empathy_chat, GTK_TYPE_BIN); static void chat_get_property (GObject *object, @@ -129,17 +119,20 @@ chat_get_property (GObject *object, case PROP_TP_CHAT: g_value_set_object (value, priv->tp_chat); break; + case PROP_ACCOUNT: + g_value_set_object (value, priv->account); + break; case PROP_NAME: g_value_set_string (value, priv->name); break; - case PROP_TOOLTIP: - g_value_set_string (value, priv->tooltip); + case PROP_SUBJECT: + g_value_set_string (value, priv->subject); break; - case PROP_ICON_NAME: - g_value_set_string (value, priv->icon_name); + case PROP_SELECTED_CONTACT: + g_value_set_object (value, priv->selected_contact); break; - case PROP_WIDGET: - g_value_set_object (value, priv->widget); + case PROP_ID: + g_value_set_string (value, priv->id); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); @@ -157,8 +150,7 @@ chat_set_property (GObject *object, switch (param_id) { case PROP_TP_CHAT: - empathy_chat_set_tp_chat (chat, - EMPATHY_TP_CHAT (g_value_get_object (value))); + empathy_chat_set_tp_chat (chat, EMPATHY_TP_CHAT (g_value_get_object (value))); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); @@ -272,13 +264,16 @@ chat_finalize (GObject *object) g_list_foreach (priv->compositors, (GFunc) g_object_unref, NULL); g_list_free (priv->compositors); + g_list_foreach (priv->backlog_messages, (GFunc) g_object_unref, NULL); + g_list_free (priv->backlog_messages); + chat_composing_remove_timeout (chat); - g_object_unref (priv->log_manager); dbus_g_proxy_disconnect_signal (DBUS_G_PROXY (priv->mc), "AccountStatusChanged", G_CALLBACK (chat_status_changed_cb), chat); g_object_unref (priv->mc); + g_object_unref (priv->log_manager); if (priv->tp_chat) { @@ -289,8 +284,8 @@ chat_finalize (GObject *object) g_object_unref (priv->account); } - if (priv->scroll_idle_id) { - g_source_remove (priv->scroll_idle_id); + if (priv->selected_contact) { + g_object_unref (priv->selected_contact); } if (priv->block_events_timeout_id) { @@ -299,7 +294,7 @@ chat_finalize (GObject *object) g_free (priv->id); g_free (priv->name); - g_free (priv->tooltip); + g_free (priv->subject); G_OBJECT_CLASS (empathy_chat_parent_class)->finalize (object); } @@ -316,14 +311,9 @@ chat_destroy_cb (EmpathyTpChat *tp_chat, g_object_unref (priv->tp_chat); priv->tp_chat = NULL; } - priv->sensitive = FALSE; empathy_chat_view_append_event (chat->view, _("Disconnected")); gtk_widget_set_sensitive (chat->input_text_view, FALSE); - - if (priv->block_events_timeout_id != 0) { - g_source_remove (priv->block_events_timeout_id); - } } static void @@ -463,7 +453,6 @@ chat_input_text_view_send (EmpathyChat *chat) gtk_text_buffer_set_text (buffer, "", -1); chat_send (chat, msg); - g_free (msg); priv->is_first_char = TRUE; @@ -580,16 +569,12 @@ chat_message_received_cb (EmpathyTpChat *tp_chat, empathy_chat_view_append_message (chat->view, message); - if (empathy_chat_should_play_sound (chat)) { - // FIXME: empathy_sound_play (EMPATHY_SOUND_CHAT); - } - /* We received a message so the contact is no more composing */ chat_state_changed_cb (tp_chat, sender, TP_CHANNEL_CHAT_STATE_ACTIVE, chat); - g_signal_emit (chat, signals[NEW_MESSAGE], 0, message, FALSE); + g_signal_emit (chat, signals[NEW_MESSAGE], 0, message); } static void @@ -629,6 +614,74 @@ chat_send_error_cb (EmpathyTpChat *tp_chat, g_free (str); } +static void +chat_property_changed_cb (EmpathyTpChat *tp_chat, + const gchar *name, + GValue *value, + EmpathyChat *chat) +{ + EmpathyChatPriv *priv = GET_PRIV (chat); + + if (!tp_strdiff (name, "subject")) { + g_free (priv->subject); + priv->subject = g_value_dup_string (value); + g_object_notify (G_OBJECT (chat), "subject"); + } + else if (!tp_strdiff (name, "name")) { + g_free (priv->name); + priv->name = g_value_dup_string (value); + g_object_notify (G_OBJECT (chat), "name"); + } +} + +static void +chat_remote_contact_notify_cb (EmpathyChat *chat) +{ + EmpathyChatPriv *priv = GET_PRIV (chat); + EmpathyContact *contact; + + contact = empathy_tp_chat_get_remote_contact (priv->tp_chat); + if (contact == priv->selected_contact) { + return; + } + + if (priv->selected_contact) { + g_object_unref (priv->selected_contact); + priv->selected_contact = NULL; + } + + if (contact) { + g_free (priv->name); + priv->selected_contact = g_object_ref (contact); + priv->name = g_strdup (empathy_contact_get_name (contact)); + g_object_notify (G_OBJECT (chat), "name"); + } + + g_object_notify (G_OBJECT (chat), "selected-contact"); +} + +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) @@ -657,7 +710,7 @@ chat_input_text_buffer_changed_cb (GtkTextBuffer *buffer, GtkAllocation *allocation; /* Save the window's size */ - dialog = empathy_get_toplevel_window (priv->widget); + dialog = empathy_get_toplevel_window (GTK_WIDGET (chat)); if (dialog) { gtk_window_get_size (GTK_WINDOW (dialog), NULL, &window_height); gtk_widget_size_request (chat->input_text_view, &req); @@ -710,7 +763,7 @@ chat_input_text_buffer_changed_cb (GtkTextBuffer *buffer, str = gtk_text_buffer_get_text (buffer, &start, &end, FALSE); /* spell check string */ - if (!empathy_chat_get_is_command (str)) { + if (!chat_get_is_command (str)) { correct = empathy_spell_check (str); } else { correct = TRUE; @@ -848,7 +901,9 @@ chat_text_view_scroll_hide_cb (GtkWidget *widget, priv = GET_PRIV (chat); priv->vscroll_visible = FALSE; - g_signal_handlers_disconnect_by_func (widget, chat_text_view_scroll_hide_cb, chat); + g_signal_handlers_disconnect_by_func (widget, + chat_text_view_scroll_hide_cb, + chat); sw = gtk_widget_get_parent (chat->input_text_view); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw), @@ -904,7 +959,7 @@ chat_text_view_size_allocate_cb (GtkWidget *widget, view_allocation = >K_WIDGET (chat->view)->allocation; - dialog = empathy_get_toplevel_window (priv->widget); + dialog = empathy_get_toplevel_window (GTK_WIDGET (widget)); gtk_window_get_size (dialog, NULL, ¤t_height); new_height = view_allocation->height + priv->padding_height + allocation->height - diff; @@ -1082,21 +1137,6 @@ chat_text_populate_popup_cb (GtkTextView *view, gtk_widget_show (item); } -static gboolean -chat_scroll_down_idle_func (EmpathyChat *chat) -{ - EmpathyChatPriv *priv; - - priv = GET_PRIV (chat); - - empathy_chat_scroll_down (chat); - g_object_unref (chat); - - priv->scroll_idle_id = 0; - - return FALSE; -} - static void chat_add_logs (EmpathyChat *chat) { @@ -1133,12 +1173,12 @@ chat_add_logs (EmpathyChat *chat) /* Turn back on scrolling */ empathy_chat_view_scroll (chat->view, TRUE); +} - /* Scroll to the most recent messages, we reference the chat - * for the duration of the scroll func. - */ - priv->scroll_idle_id = g_idle_add ((GSourceFunc) chat_scroll_down_idle_func, - g_object_ref (chat)); +static void +chat_constructed (GObject *object) +{ + chat_add_logs (EMPATHY_CHAT (object)); } static void @@ -1151,6 +1191,7 @@ empathy_chat_class_init (EmpathyChatClass *klass) object_class->finalize = chat_finalize; object_class->get_property = chat_get_property; object_class->set_property = chat_set_property; + object_class->constructed = chat_constructed; g_object_class_install_property (object_class, PROP_TP_CHAT, @@ -1160,6 +1201,13 @@ empathy_chat_class_init (EmpathyChatClass *klass) EMPATHY_TYPE_TP_CHAT, G_PARAM_CONSTRUCT | G_PARAM_READWRITE)); + g_object_class_install_property (object_class, + PROP_ACCOUNT, + g_param_spec_object ("account", + "Account of the chat", + "The account of the chat", + MC_TYPE_ACCOUNT, + G_PARAM_READABLE)); g_object_class_install_property (object_class, PROP_NAME, g_param_spec_string ("name", @@ -1168,25 +1216,27 @@ empathy_chat_class_init (EmpathyChatClass *klass) NULL, G_PARAM_READABLE)); g_object_class_install_property (object_class, - PROP_TOOLTIP, - g_param_spec_string ("tooltip", - "Chat's tooltip", - "The tooltip of the chat", + PROP_SUBJECT, + g_param_spec_string ("subject", + "Chat's subject", + "The subject or topic of the chat", NULL, G_PARAM_READABLE)); g_object_class_install_property (object_class, - PROP_ICON_NAME, - g_param_spec_string ("icon-name", - "Chat's icon name", - "The icon name of the chat", - NULL, + PROP_SELECTED_CONTACT, + g_param_spec_object ("selected-contact", + "The selected contact", + "The selected contact, " + "either the remote contact or " + "the one selected on the contact list", + EMPATHY_TYPE_CONTACT, G_PARAM_READABLE)); g_object_class_install_property (object_class, - PROP_WIDGET, - g_param_spec_object ("widget", - "Chat's widget", - "The widget of the chat", - GTK_TYPE_WIDGET, + PROP_ID, + g_param_spec_string ("id", + "Chat's id", + "The id of the chat", + NULL, G_PARAM_READABLE)); signals[COMPOSING] = @@ -1205,9 +1255,9 @@ empathy_chat_class_init (EmpathyChatClass *klass) G_SIGNAL_RUN_LAST, 0, NULL, NULL, - _empathy_gtk_marshal_VOID__OBJECT_BOOLEAN, + g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, - 2, EMPATHY_TYPE_MESSAGE, G_TYPE_BOOLEAN); + 1, EMPATHY_TYPE_MESSAGE); g_type_class_add_private (object_class, sizeof (EmpathyChatPriv)); } @@ -1234,10 +1284,8 @@ empathy_chat_init (EmpathyChat *chat) priv->log_manager = empathy_log_manager_new (); priv->default_window_height = -1; priv->vscroll_visible = FALSE; - priv->sensitive = TRUE; priv->sent_messages = NULL; priv->sent_messages_index = -1; - priv->first_tp_chat = TRUE; priv->mc = empathy_mission_control_new (); dbus_g_proxy_connect_signal (DBUS_G_PROXY (priv->mc), "AccountStatusChanged", @@ -1287,142 +1335,21 @@ empathy_chat_new (EmpathyTpChat *tp_chat) return g_object_new (EMPATHY_TYPE_CHAT, "tp-chat", tp_chat, NULL); } -gboolean -empathy_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; -} - -void -empathy_chat_correct_word (EmpathyChat *chat, - GtkTextIter start, - GtkTextIter end, - const gchar *new_word) -{ - GtkTextBuffer *buffer; - - g_return_if_fail (chat != NULL); - g_return_if_fail (new_word != NULL); - - buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (chat->input_text_view)); - - gtk_text_buffer_delete (buffer, &start, &end); - gtk_text_buffer_insert (buffer, &start, - new_word, - -1); -} - -const gchar * -empathy_chat_get_name (EmpathyChat *chat) +EmpathyTpChat * +empathy_chat_get_tp_chat (EmpathyChat *chat) { EmpathyChatPriv *priv = GET_PRIV (chat); g_return_val_if_fail (EMPATHY_IS_CHAT (chat), NULL); - return priv->name; -} - -const gchar * -empathy_chat_get_tooltip (EmpathyChat *chat) -{ - EmpathyChatPriv *priv = GET_PRIV (chat); - - g_return_val_if_fail (EMPATHY_IS_CHAT (chat), NULL); - - return priv->tooltip; -} - -const gchar * -empathy_chat_get_status_icon_name (EmpathyChat *chat) -{ - EmpathyChatPriv *priv = GET_PRIV (chat); - - g_return_val_if_fail (EMPATHY_IS_CHAT (chat), NULL); - - return priv->icon_name; -} - -GtkWidget * -empathy_chat_get_widget (EmpathyChat *chat) -{ - EmpathyChatPriv *priv = GET_PRIV (chat); - - g_return_val_if_fail (EMPATHY_IS_CHAT (chat), NULL); - - return priv->widget; -} - -gboolean -empathy_chat_is_connected (EmpathyChat *chat) -{ - EmpathyChatPriv *priv; - - g_return_val_if_fail (EMPATHY_IS_CHAT (chat), FALSE); - - priv = GET_PRIV (chat); - - return (priv->tp_chat != NULL); -} - -static const gchar * -chat_get_window_id_for_geometry (EmpathyChat *chat) -{ - gboolean separate_windows; - - empathy_conf_get_bool (empathy_conf_get (), - EMPATHY_PREFS_UI_SEPARATE_CHAT_WINDOWS, - &separate_windows); - - if (separate_windows) { - return empathy_chat_get_id (chat); - } else { - return "chat-window"; - } -} - -void -empathy_chat_save_geometry (EmpathyChat *chat, - gint x, - gint y, - gint w, - gint h) -{ - empathy_geometry_save (chat_get_window_id_for_geometry (chat), x, y, w, h); -} - -void -empathy_chat_load_geometry (EmpathyChat *chat, - gint *x, - gint *y, - gint *w, - gint *h) -{ - empathy_geometry_load (chat_get_window_id_for_geometry (chat), x, y, w, h); + return priv->tp_chat; } static gboolean chat_block_events_timeout_cb (gpointer data) { - EmpathyChat *chat = EMPATHY_CHAT (data); - EmpathyChatPriv *priv = GET_PRIV (chat); + EmpathyChatPriv *priv = GET_PRIV (data); - chat->block_events = FALSE; priv->block_events_timeout_id = 0; return FALSE; @@ -1444,42 +1371,20 @@ empathy_chat_set_tp_chat (EmpathyChat *chat, return; } - /* Block events for some time to avoid having "has come online" or - * "joined" messages. */ - chat->block_events = TRUE; - if (priv->block_events_timeout_id != 0) { - g_source_remove (priv->block_events_timeout_id); - } - priv->block_events_timeout_id = - g_timeout_add_seconds (1, chat_block_events_timeout_cb, chat); - if (priv->tp_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_destroy_cb, - chat); g_object_unref (priv->tp_chat); } if (priv->account) { g_object_unref (priv->account); } - g_free (priv->id); + priv->tp_chat = g_object_ref (tp_chat); priv->id = g_strdup (empathy_tp_chat_get_id (tp_chat)); priv->account = g_object_ref (empathy_tp_chat_get_account (tp_chat)); tp_chan = empathy_tp_chat_get_channel (tp_chat); priv->handle_type = tp_chan->handle_type; - - if (priv->first_tp_chat) { - chat_add_logs (chat); - priv->first_tp_chat = FALSE; - } + chat_remote_contact_notify_cb (chat); g_signal_connect (tp_chat, "message-received", G_CALLBACK (chat_message_received_cb), @@ -1490,35 +1395,79 @@ empathy_chat_set_tp_chat (EmpathyChat *chat, g_signal_connect (tp_chat, "chat-state-changed", G_CALLBACK (chat_state_changed_cb), chat); + g_signal_connect (tp_chat, "property-changed", + G_CALLBACK (chat_property_changed_cb), + chat); + g_signal_connect_swapped (tp_chat, "notify::remote-contact", + G_CALLBACK (chat_remote_contact_notify_cb), + chat); g_signal_connect (tp_chat, "destroy", G_CALLBACK (chat_destroy_cb), chat); - if (!priv->sensitive) { - gtk_widget_set_sensitive (chat->input_text_view, TRUE); - empathy_chat_view_append_event (chat->view, _("Connected")); - priv->sensitive = TRUE; + /* Block events for some time to avoid having "has come online" or + * "joined" messages. */ + if (priv->block_events_timeout_id == 0) { + priv->block_events_timeout_id = + g_timeout_add_seconds (1, chat_block_events_timeout_cb, chat); } + gtk_widget_set_sensitive (chat->input_text_view, TRUE); + empathy_chat_view_append_event (chat->view, _("Connected")); + g_object_notify (G_OBJECT (chat), "tp-chat"); + g_object_notify (G_OBJECT (chat), "id"); + g_object_notify (G_OBJECT (chat), "account"); +} + +McAccount * +empathy_chat_get_account (EmpathyChat *chat) +{ + EmpathyChatPriv *priv = GET_PRIV (chat); + + g_return_val_if_fail (EMPATHY_IS_CHAT (chat), NULL); + + return priv->account; } const gchar * -empathy_chat_get_id (EmpathyChat *chat) +empathy_chat_get_name (EmpathyChat *chat) { - EmpathyChatPriv *priv; + EmpathyChatPriv *priv = GET_PRIV (chat); - priv = GET_PRIV (chat); + g_return_val_if_fail (EMPATHY_IS_CHAT (chat), NULL); - return priv->id; + return priv->name; } -McAccount * -empathy_chat_get_account (EmpathyChat *chat) +const gchar * +empathy_chat_get_subject (EmpathyChat *chat) { EmpathyChatPriv *priv = GET_PRIV (chat); - return priv->account; + g_return_val_if_fail (EMPATHY_IS_CHAT (chat), NULL); + + return priv->subject; +} + +EmpathyContact * +empathy_chat_get_selected_contact (EmpathyChat *chat) +{ + EmpathyChatPriv *priv = GET_PRIV (chat); + + g_return_val_if_fail (EMPATHY_IS_CHAT (chat), NULL); + + return priv->selected_contact; +} + +const gchar * +empathy_chat_get_id (EmpathyChat *chat) +{ + EmpathyChatPriv *priv = GET_PRIV (chat); + + g_return_val_if_fail (EMPATHY_IS_CHAT (chat), NULL); + + return priv->id; } void @@ -1590,88 +1539,22 @@ empathy_chat_paste (EmpathyChat *chat) gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE); } -gboolean -empathy_chat_should_play_sound (EmpathyChat *chat) -{ - EmpathyChatPriv *priv = GET_PRIV (chat); - GtkWindow *window; - gboolean has_focus = FALSE; - - g_return_val_if_fail (EMPATHY_IS_CHAT (chat), FALSE); - - window = empathy_get_toplevel_window (priv->widget); - if (window) { - g_object_get (window, "has-toplevel-focus", &has_focus, NULL); - } - - return !has_focus; -} - -gboolean -empathy_chat_should_highlight_nick (EmpathyMessage *message) +void +empathy_chat_correct_word (EmpathyChat *chat, + GtkTextIter start, + GtkTextIter end, + const gchar *new_word) { - EmpathyContact *contact; - const gchar *msg, *to; - gchar *cf_msg, *cf_to; - gchar *ch; - gboolean ret_val; - - g_return_val_if_fail (EMPATHY_IS_MESSAGE (message), FALSE); - - empathy_debug (DEBUG_DOMAIN, "Highlighting nickname"); - - ret_val = FALSE; - - msg = empathy_message_get_body (message); - if (!msg) { - return FALSE; - } - - contact = empathy_message_get_receiver (message); - if (!contact || !empathy_contact_is_user (contact)) { - return FALSE; - } - - to = empathy_contact_get_name (contact); - if (!to) { - return FALSE; - } - - cf_msg = g_utf8_casefold (msg, -1); - cf_to = g_utf8_casefold (to, -1); - - ch = strstr (cf_msg, cf_to); - if (ch == NULL) { - goto finished; - } - - if (ch != cf_msg) { - /* Not first in the message */ - if ((*(ch - 1) != ' ') && - (*(ch - 1) != ',') && - (*(ch - 1) != '.')) { - goto finished; - } - } - - ch = ch + strlen (cf_to); - if (ch >= cf_msg + strlen (cf_msg)) { - ret_val = TRUE; - goto finished; - } + GtkTextBuffer *buffer; - if ((*ch == ' ') || - (*ch == ',') || - (*ch == '.') || - (*ch == ':')) { - ret_val = TRUE; - goto finished; - } + g_return_if_fail (chat != NULL); + g_return_if_fail (new_word != NULL); -finished: - g_free (cf_msg); - g_free (cf_to); + buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (chat->input_text_view)); - return ret_val; + gtk_text_buffer_delete (buffer, &start, &end); + gtk_text_buffer_insert (buffer, &start, + new_word, + -1); } diff --git a/libempathy-gtk/empathy-chat.glade b/libempathy-gtk/empathy-chat.glade index 33664692..0a801adc 100644 --- a/libempathy-gtk/empathy-chat.glade +++ b/libempathy-gtk/empathy-chat.glade @@ -7,7 +7,7 @@ Group Chat system-users - + True 4 6 diff --git a/libempathy-gtk/empathy-chat.h b/libempathy-gtk/empathy-chat.h index 53e7d127..174c4506 100644 --- a/libempathy-gtk/empathy-chat.h +++ b/libempathy-gtk/empathy-chat.h @@ -28,14 +28,13 @@ #ifndef __EMPATHY_CHAT_H__ #define __EMPATHY_CHAT_H__ -#include +#include #include #include #include #include "empathy-chat-view.h" -#include "empathy-spell.h" G_BEGIN_DECLS @@ -51,53 +50,36 @@ typedef struct _EmpathyChatClass EmpathyChatClass; typedef struct _EmpathyChatPriv EmpathyChatPriv; struct _EmpathyChat { - GObject parent; + GtkBin parent; /* Protected */ EmpathyChatView *view; GtkWidget *input_text_view; - gboolean block_events; }; struct _EmpathyChatClass { - GObjectClass parent; + GtkBinClass parent; }; -GType empathy_chat_get_type (void); -EmpathyChat * empathy_chat_new (EmpathyTpChat *tp_chat); -void empathy_chat_clear (EmpathyChat *chat); -void empathy_chat_scroll_down (EmpathyChat *chat); -void empathy_chat_cut (EmpathyChat *chat); -void empathy_chat_copy (EmpathyChat *chat); -void empathy_chat_paste (EmpathyChat *chat); -const gchar * empathy_chat_get_name (EmpathyChat *chat); -const gchar * empathy_chat_get_tooltip (EmpathyChat *chat); -const gchar * empathy_chat_get_status_icon_name (EmpathyChat *chat); -GtkWidget * empathy_chat_get_widget (EmpathyChat *chat); -gboolean empathy_chat_is_connected (EmpathyChat *chat); -void empathy_chat_save_geometry (EmpathyChat *chat, - gint x, - gint y, - gint w, - gint h); -void empathy_chat_load_geometry (EmpathyChat *chat, - gint *x, - gint *y, - gint *w, - gint *h); -void empathy_chat_set_tp_chat (EmpathyChat *chat, - EmpathyTpChat *tp_chat); -const gchar * empathy_chat_get_id (EmpathyChat *chat); -McAccount * empathy_chat_get_account (EmpathyChat *chat); - -/* For spell checker dialog to correct the misspelled word. */ -gboolean empathy_chat_get_is_command (const gchar *str); -void empathy_chat_correct_word (EmpathyChat *chat, - GtkTextIter start, - GtkTextIter end, - const gchar *new_word); -gboolean empathy_chat_should_play_sound (EmpathyChat *chat); -gboolean empathy_chat_should_highlight_nick (EmpathyMessage *message); +GType empathy_chat_get_type (void); +EmpathyChat * empathy_chat_new (EmpathyTpChat *tp_chat); +EmpathyTpChat * empathy_chat_get_tp_chat (EmpathyChat *chat); +void empathy_chat_set_tp_chat (EmpathyChat *chat, + EmpathyTpChat *tp_chat); +McAccount * empathy_chat_get_account (EmpathyChat *chat); +const gchar * empathy_chat_get_name (EmpathyChat *chat); +const gchar * empathy_chat_get_subject (EmpathyChat *chat); +EmpathyContact * empathy_chat_get_selected_contact (EmpathyChat *chat); +const gchar * empathy_chat_get_id (EmpathyChat *chat); +void empathy_chat_clear (EmpathyChat *chat); +void empathy_chat_scroll_down (EmpathyChat *chat); +void empathy_chat_cut (EmpathyChat *chat); +void empathy_chat_copy (EmpathyChat *chat); +void empathy_chat_paste (EmpathyChat *chat); +void empathy_chat_correct_word (EmpathyChat *chat, + GtkTextIter start, + GtkTextIter end, + const gchar *new_word); G_END_DECLS diff --git a/libempathy-gtk/empathy-log-window.c b/libempathy-gtk/empathy-log-window.c index 150d1d31..7441911c 100644 --- a/libempathy-gtk/empathy-log-window.c +++ b/libempathy-gtk/empathy-log-window.c @@ -93,9 +93,6 @@ static void log_window_chats_populate (EmpathyLogWindow *wi static void log_window_chats_setup (EmpathyLogWindow *window); static void log_window_chats_accounts_changed_cb (GtkWidget *combobox, EmpathyLogWindow *window); -static void log_window_chats_new_message_cb (EmpathyContact *own_contact, - EmpathyMessage *message, - EmpathyLogWindow *window); static void log_window_chats_set_selected (EmpathyLogWindow *window, McAccount *account, const gchar *chat_id, @@ -274,10 +271,6 @@ static void log_window_destroy_cb (GtkWidget *widget, EmpathyLogWindow *window) { - g_signal_handlers_disconnect_by_func (window->log_manager, - log_window_chats_new_message_cb, - window); - g_free (window->last_find); g_object_unref (window->log_manager); @@ -742,17 +735,6 @@ log_window_chats_accounts_changed_cb (GtkWidget *combobox, log_window_chats_populate (window); } -static void -log_window_chats_new_message_cb (EmpathyContact *own_contact, - EmpathyMessage *message, - EmpathyLogWindow *window) -{ - empathy_chat_view_append_message (window->chatview_chats, message); - - /* Scroll to the most recent messages */ - empathy_chat_view_scroll_down (window->chatview_chats); -} - static void log_window_chats_set_selected (EmpathyLogWindow *window, McAccount *account, @@ -977,9 +959,6 @@ log_window_chats_get_messages (EmpathyLogWindow *window, /* Turn back on scrolling */ empathy_chat_view_scroll (window->chatview_find, TRUE); - /* Scroll to the most recent messages */ - empathy_chat_view_scroll_down (window->chatview_chats); - /* Give the search entry main focus */ gtk_widget_grab_focus (window->entry_chats); diff --git a/libempathy-gtk/empathy-spell-dialog.c b/libempathy-gtk/empathy-spell-dialog.c index 59e5867b..830cfd0f 100644 --- a/libempathy-gtk/empathy-spell-dialog.c +++ b/libempathy-gtk/empathy-spell-dialog.c @@ -35,6 +35,7 @@ #include #include "empathy-chat.h" +#include "empathy-spell.h" #include "empathy-spell-dialog.h" #include "empathy-ui-utils.h" diff --git a/libempathy-gtk/empathy-theme-irc.c b/libempathy-gtk/empathy-theme-irc.c index 7cd9588b..07ee6781 100644 --- a/libempathy-gtk/empathy-theme-irc.c +++ b/libempathy-gtk/empathy-theme-irc.c @@ -215,7 +215,7 @@ theme_irc_append_message (EmpathyTheme *theme, nick_tag = "irc-nick-self"; body_tag = "irc-body-self"; } else { - if (empathy_chat_should_highlight_nick (message)) { + if (empathy_message_should_highlight (message)) { nick_tag = "irc-nick-highlight"; } else { nick_tag = "irc-nick-other"; diff --git a/libempathy/empathy-message.c b/libempathy/empathy-message.c index 76b49bd1..d6b8e532 100644 --- a/libempathy/empathy-message.c +++ b/libempathy/empathy-message.c @@ -437,6 +437,67 @@ empathy_message_get_date_and_time (EmpathyMessage *message, time_t *timestamp) return date; } +#define IS_SEPARATOR(ch) (ch == ' ' || ch == ',' || ch == '.' || ch == ':') +gboolean +empathy_message_should_highlight (EmpathyMessage *message) +{ + EmpathyContact *contact; + const gchar *msg, *to; + gchar *cf_msg, *cf_to; + gchar *ch; + gboolean ret_val; + + g_return_val_if_fail (EMPATHY_IS_MESSAGE (message), FALSE); + + ret_val = FALSE; + + msg = empathy_message_get_body (message); + if (!msg) { + return FALSE; + } + + contact = empathy_message_get_receiver (message); + if (!contact || !empathy_contact_is_user (contact)) { + return FALSE; + } + + to = empathy_contact_get_name (contact); + if (!to) { + return FALSE; + } + + cf_msg = g_utf8_casefold (msg, -1); + cf_to = g_utf8_casefold (to, -1); + + ch = strstr (cf_msg, cf_to); + if (ch == NULL) { + goto finished; + } + if (ch != cf_msg) { + /* Not first in the message */ + if (!IS_SEPARATOR (*(ch - 1))) { + goto finished; + } + } + + ch = ch + strlen (cf_to); + if (ch >= cf_msg + strlen (cf_msg)) { + ret_val = TRUE; + goto finished; + } + + if (IS_SEPARATOR (*ch)) { + ret_val = TRUE; + goto finished; + } + +finished: + g_free (cf_msg); + g_free (cf_to); + + return ret_val; +} + EmpathyMessageType empathy_message_type_from_str (const gchar *type_str) { diff --git a/libempathy/empathy-message.h b/libempathy/empathy-message.h index d1c995fe..d07565b0 100644 --- a/libempathy/empathy-message.h +++ b/libempathy/empathy-message.h @@ -58,27 +58,28 @@ typedef enum { EMPATHY_MESSAGE_TYPE_LAST } EmpathyMessageType; -GType empathy_message_get_gtype (void) G_GNUC_CONST; -EmpathyMessage * empathy_message_new (const gchar *body); -EmpathyMessageType empathy_message_get_type (EmpathyMessage *message); -void empathy_message_set_type (EmpathyMessage *message, - EmpathyMessageType type); -EmpathyContact * empathy_message_get_sender (EmpathyMessage *message); -void empathy_message_set_sender (EmpathyMessage *message, - EmpathyContact *contact); -EmpathyContact * empathy_message_get_receiver (EmpathyMessage *message); -void empathy_message_set_receiver (EmpathyMessage *message, - EmpathyContact *contact); -const gchar * empathy_message_get_body (EmpathyMessage *message); -void empathy_message_set_body (EmpathyMessage *message, - const gchar *body); -time_t empathy_message_get_timestamp (EmpathyMessage *message); -void empathy_message_set_timestamp (EmpathyMessage *message, - time_t timestamp); -GDate * empathy_message_get_date_and_time (EmpathyMessage *message, - time_t *timestamp); -EmpathyMessageType empathy_message_type_from_str (const gchar *type_str); -const gchar * empathy_message_type_to_str (EmpathyMessageType type); +GType empathy_message_get_gtype (void) G_GNUC_CONST; +EmpathyMessage * empathy_message_new (const gchar *body); +EmpathyMessageType empathy_message_get_type (EmpathyMessage *message); +void empathy_message_set_type (EmpathyMessage *message, + EmpathyMessageType type); +EmpathyContact * empathy_message_get_sender (EmpathyMessage *message); +void empathy_message_set_sender (EmpathyMessage *message, + EmpathyContact *contact); +EmpathyContact * empathy_message_get_receiver (EmpathyMessage *message); +void empathy_message_set_receiver (EmpathyMessage *message, + EmpathyContact *contact); +const gchar * empathy_message_get_body (EmpathyMessage *message); +void empathy_message_set_body (EmpathyMessage *message, + const gchar *body); +time_t empathy_message_get_timestamp (EmpathyMessage *message); +void empathy_message_set_timestamp (EmpathyMessage *message, + time_t timestamp); +GDate * empathy_message_get_date_and_time (EmpathyMessage *message, + time_t *timestamp); +gboolean empathy_message_should_highlight (EmpathyMessage *message); +EmpathyMessageType empathy_message_type_from_str (const gchar *type_str); +const gchar * empathy_message_type_to_str (EmpathyMessageType type); G_END_DECLS diff --git a/libempathy/empathy-tp-chat.c b/libempathy/empathy-tp-chat.c index 0cbd5eea..4c7702cd 100644 --- a/libempathy/empathy-tp-chat.c +++ b/libempathy/empathy-tp-chat.c @@ -43,7 +43,7 @@ struct _EmpathyTpChatPriv { EmpathyContactFactory *factory; EmpathyContact *user; - EmpathyContact *initiator; + EmpathyContact *remote_contact; EmpathyTpGroup *group; McAccount *account; TpChannel *channel; @@ -74,6 +74,7 @@ enum { PROP_TP_CHAN, PROP_CHANNEL, PROP_ACKNOWLEDGE, + PROP_REMOTE_CONTACT, }; enum { @@ -202,7 +203,7 @@ tp_chat_get_members (EmpathyContactList *list) members = empathy_tp_group_get_members (priv->group); } else { members = g_list_prepend (members, g_object_ref (priv->user)); - members = g_list_prepend (members, g_object_ref (priv->initiator)); + members = g_list_prepend (members, g_object_ref (priv->remote_contact)); } return members; @@ -670,23 +671,54 @@ empathy_tp_chat_set_property (EmpathyTpChat *chat, } } -static gboolean +static void tp_chat_channel_ready_cb (EmpathyTpChat *chat) { EmpathyTpChatPriv *priv = GET_PRIV (chat); empathy_debug (DEBUG_DOMAIN, "Channel ready"); + if (tp_proxy_has_interface_by_id (priv->channel, + TP_IFACE_QUARK_CHANNEL_INTERFACE_GROUP)) { + priv->group = empathy_tp_group_new (priv->account, priv->tp_chan); + + g_signal_connect (priv->group, "member-added", + G_CALLBACK (tp_chat_member_added_cb), + chat); + g_signal_connect (priv->group, "member-removed", + G_CALLBACK (tp_chat_member_removed_cb), + chat); + g_signal_connect (priv->group, "local-pending", + G_CALLBACK (tp_chat_local_pending_cb), + chat); + } else { + priv->remote_contact = empathy_contact_factory_get_from_handle (priv->factory, + priv->account, + priv->tp_chan->handle); + g_object_notify (G_OBJECT (chat), "remote-contact"); + } + + if (tp_proxy_has_interface_by_id (priv->channel, + TP_IFACE_QUARK_PROPERTIES_INTERFACE)) { + tp_cli_properties_interface_call_list_properties (priv->channel, -1, + tp_chat_list_properties_cb, + NULL, NULL, + G_OBJECT (chat)); + tp_cli_properties_interface_connect_to_properties_changed (priv->channel, + tp_chat_properties_changed_cb, + NULL, NULL, + G_OBJECT (chat), NULL); + tp_cli_properties_interface_connect_to_property_flags_changed (priv->channel, + tp_chat_property_flags_changed_cb, + NULL, NULL, + G_OBJECT (chat), NULL); + } + tp_cli_channel_type_text_call_list_pending_messages (priv->channel, -1, priv->acknowledge, tp_chat_list_pending_messages_cb, NULL, NULL, G_OBJECT (chat)); - tp_cli_properties_interface_call_list_properties (priv->channel, -1, - tp_chat_list_properties_cb, - NULL, NULL, - G_OBJECT (chat)); - tp_cli_channel_type_text_connect_to_received (priv->channel, tp_chat_received_cb, @@ -708,16 +740,6 @@ tp_chat_channel_ready_cb (EmpathyTpChat *chat) tp_chat_state_changed_cb, NULL, NULL, G_OBJECT (chat), NULL); - tp_cli_properties_interface_connect_to_properties_changed (priv->channel, - tp_chat_properties_changed_cb, - NULL, NULL, - G_OBJECT (chat), NULL); - tp_cli_properties_interface_connect_to_property_flags_changed (priv->channel, - tp_chat_property_flags_changed_cb, - NULL, NULL, - G_OBJECT (chat), NULL); - - return FALSE; } static void @@ -758,8 +780,8 @@ tp_chat_finalize (GObject *object) g_ptr_array_free (priv->properties, TRUE); } - if (priv->initiator) { - g_object_unref (priv->initiator); + if (priv->remote_contact) { + g_object_unref (priv->remote_contact); } if (priv->group) { g_object_unref (priv->group); @@ -803,25 +825,6 @@ tp_chat_constructor (GType type, chat); } - if (tp_proxy_has_interface_by_id (priv->channel, - TP_IFACE_QUARK_CHANNEL_INTERFACE_GROUP)) { - priv->group = empathy_tp_group_new (priv->account, priv->tp_chan); - - g_signal_connect (priv->group, "member-added", - G_CALLBACK (tp_chat_member_added_cb), - chat); - g_signal_connect (priv->group, "member-removed", - G_CALLBACK (tp_chat_member_removed_cb), - chat); - g_signal_connect (priv->group, "local-pending", - G_CALLBACK (tp_chat_local_pending_cb), - chat); - } else { - priv->initiator = empathy_contact_factory_get_from_handle (priv->factory, - priv->account, - priv->tp_chan->handle); - } - return chat; } @@ -846,6 +849,9 @@ tp_chat_get_property (GObject *object, case PROP_ACKNOWLEDGE: g_value_set_boolean (value, priv->acknowledge); break; + case PROP_REMOTE_CONTACT: + g_value_set_object (value, priv->remote_contact); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec); break; @@ -906,7 +912,6 @@ empathy_tp_chat_class_init (EmpathyTpChatClass *klass) TELEPATHY_CHAN_TYPE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - g_object_class_install_property (object_class, PROP_CHANNEL, g_param_spec_object ("channel", @@ -915,7 +920,6 @@ empathy_tp_chat_class_init (EmpathyTpChatClass *klass) TP_TYPE_CHANNEL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - g_object_class_install_property (object_class, PROP_ACKNOWLEDGE, g_param_spec_boolean ("acknowledge", @@ -923,7 +927,14 @@ empathy_tp_chat_class_init (EmpathyTpChatClass *klass) "Wheter or not received messages should be acknowledged", FALSE, G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY)); + G_PARAM_CONSTRUCT)); + g_object_class_install_property (object_class, + PROP_REMOTE_CONTACT, + g_param_spec_object ("remote-contact", + "The remote contact", + "The remote contact if there is no group iface on the channel", + EMPATHY_TYPE_CONTACT, + G_PARAM_READABLE)); /* Signals */ signals[MESSAGE_RECEIVED] = @@ -1150,3 +1161,13 @@ empathy_tp_chat_get_id (EmpathyTpChat *chat) return priv->id; } +EmpathyContact * +empathy_tp_chat_get_remote_contact (EmpathyTpChat *chat) +{ + EmpathyTpChatPriv *priv = GET_PRIV (chat); + + g_return_val_if_fail (EMPATHY_IS_TP_CHAT (chat), NULL); + + return priv->remote_contact; +} + diff --git a/libempathy/empathy-tp-chat.h b/libempathy/empathy-tp-chat.h index 72c0c012..3911e1dd 100644 --- a/libempathy/empathy-tp-chat.h +++ b/libempathy/empathy-tp-chat.h @@ -61,11 +61,12 @@ EmpathyTpChat *empathy_tp_chat_new (McAccount *account EmpathyTpChat *empathy_tp_chat_new_with_contact (EmpathyContact *contact); McAccount * empathy_tp_chat_get_account (EmpathyTpChat *chat); TpChan * empathy_tp_chat_get_channel (EmpathyTpChat *chat); +const gchar * empathy_tp_chat_get_id (EmpathyTpChat *chat); +EmpathyContact*empathy_tp_chat_get_remote_contact (EmpathyTpChat *chat); void empathy_tp_chat_send (EmpathyTpChat *chat, EmpathyMessage *message); void empathy_tp_chat_set_state (EmpathyTpChat *chat, TpChannelChatState state); -const gchar * empathy_tp_chat_get_id (EmpathyTpChat *chat); void empathy_tp_chat_set_property (EmpathyTpChat *chat, const gchar *name, const GValue *value); diff --git a/src/empathy-chat-window.c b/src/empathy-chat-window.c index 898f5496..eef89118 100644 --- a/src/empathy-chat-window.c +++ b/src/empathy-chat-window.c @@ -958,8 +958,7 @@ chat_window_composing_cb (EmpathyChat *chat, static void chat_window_new_message_cb (EmpathyChat *chat, EmpathyMessage *message, - gboolean is_backlog, - EmpathyChatWindow *window) +s EmpathyChatWindow *window) { EmpathyChatWindowPriv *priv; gboolean has_focus; @@ -970,29 +969,17 @@ chat_window_new_message_cb (EmpathyChat *chat, has_focus = empathy_chat_window_has_focus (window); if (has_focus && priv->current_chat == chat) { - empathy_debug (DEBUG_DOMAIN, "New message, we have focus"); return; } - empathy_debug (DEBUG_DOMAIN, "New message, no focus"); - - needs_urgency = FALSE; - if (empathy_chat_is_group_chat (chat)) { - if (!is_backlog && - empathy_chat_should_highlight_nick (message)) { - empathy_debug (DEBUG_DOMAIN, "Highlight this nick"); - needs_urgency = TRUE; - } - } else { - needs_urgency = TRUE; - } + needs_urgency = (empathy_chat_is_group_chat (chat) && + empathy_message_should_highlight (message)); if (needs_urgency && !has_focus) { chat_window_set_urgency_hint (window, TRUE); } - if (!is_backlog && - !g_list_find (priv->chats_new_msg, chat)) { + if (!g_list_find (priv->chats_new_msg, chat)) { priv->chats_new_msg = g_list_prepend (priv->chats_new_msg, chat); chat_window_update_status (window, chat); } @@ -1786,3 +1773,57 @@ empathy_chat_window_present_chat (EmpathyChat *chat) gtk_widget_grab_focus (chat->input_text_view); } + +static gboolean +chat_should_play_sound (EmpathyChat *chat) +{ + EmpathyChatPriv *priv = GET_PRIV (chat); + GtkWindow *window; + gboolean has_focus = FALSE; + + g_return_val_if_fail (EMPATHY_IS_CHAT (chat), FALSE); + + window = empathy_get_toplevel_window (priv->widget); + if (window) { + g_object_get (window, "has-toplevel-focus", &has_focus, NULL); + } + + return !has_focus; +} +static const gchar * +chat_get_window_id_for_geometry (EmpathyChat *chat) +{ + gboolean separate_windows; + + empathy_conf_get_bool (empathy_conf_get (), + EMPATHY_PREFS_UI_SEPARATE_CHAT_WINDOWS, + &separate_windows); + + if (separate_windows) { + return empathy_chat_get_id (chat); + } else { + return "chat-window"; + } +} + +void +empathy_chat_save_geometry (EmpathyChat *chat, + gint x, + gint y, + gint w, + gint h) +{ + empathy_geometry_save (chat_get_window_id_for_geometry (chat), x, y, w, h); +} + +void +empathy_chat_load_geometry (EmpathyChat *chat, + gint *x, + gint *y, + gint *w, + gint *h) +{ + empathy_geometry_load (chat_get_window_id_for_geometry (chat), x, y, w, h); +} + + diff --git a/src/empathy-chat-window.h b/src/empathy-chat-window.h index 32ca13a9..893642e7 100644 --- a/src/empathy-chat-window.h +++ b/src/empathy-chat-window.h @@ -71,6 +71,18 @@ gboolean empathy_chat_window_has_focus (EmpathyChatWindow *window EmpathyChat * empathy_chat_window_find_chat (McAccount *account, const gchar *id); void empathy_chat_window_present_chat (EmpathyChat *chat); +void empathy_chat_save_geometry (EmpathyChat *chat, + gint x, + gint y, + gint w, + gint h); +void empathy_chat_load_geometry (EmpathyChat *chat, + gint *x, + gint *y, + gint *w, + gint *h); + + G_END_DECLS #endif /* __EMPATHY_CHAT_WINDOW_H__ */