X-Git-Url: https://git.0d.be/?p=empathy.git;a=blobdiff_plain;f=libempathy-gtk%2Fempathy-chat.c;h=d273a3792536b161095434f2e5c31d7f4a052478;hp=b1fb93d0200510cee51b5217788a150424e3c06c;hb=9b3306a89a8419217e9c2350d7c32c1a83704eca;hpb=6d3a71637df970d2cf52d653399b66a213bae502 diff --git a/libempathy-gtk/empathy-chat.c b/libempathy-gtk/empathy-chat.c index b1fb93d0..d273a379 100644 --- a/libempathy-gtk/empathy-chat.c +++ b/libempathy-gtk/empathy-chat.c @@ -73,6 +73,7 @@ struct _EmpathyChatPriv { gchar *id; gchar *name; gchar *subject; + EmpathyContact *self_contact; EmpathyContact *remote_contact; gboolean show_contacts; @@ -155,6 +156,14 @@ struct _EmpathyChatPriv { * the keyboard or the mouse. We can't ask GTK for the most recent * event, because it will be a notify event. Instead we track it here */ GdkEventType most_recent_event_type; + + /* A regex matching our own current nickname in the room, or %NULL if + * !empathy_chat_is_room (). */ + GRegex *highlight_regex; + + /* TRUE if empathy_chat_is_room () and there are unread highlighted messages. + * Cleared by empathy_chat_messages_read (). */ + gboolean highlighted; }; typedef struct { @@ -368,11 +377,18 @@ static gboolean chat_composing_stop_timeout_cb (EmpathyChat *chat) { EmpathyChatPriv *priv; + gboolean send_chat_states; priv = GET_PRIV (chat); priv->composing_stop_timeout_id = 0; - set_chat_state (chat, TP_CHANNEL_CHAT_STATE_PAUSED); + send_chat_states = g_settings_get_boolean (priv->gsettings_chat, + EMPATHY_PREFS_CHAT_SEND_CHAT_STATES); + if (!send_chat_states) { + set_chat_state (chat, TP_CHANNEL_CHAT_STATE_ACTIVE); + } else { + set_chat_state (chat, TP_CHANNEL_CHAT_STATE_PAUSED); + } return FALSE; } @@ -381,9 +397,16 @@ static void chat_composing_start (EmpathyChat *chat) { EmpathyChatPriv *priv; + gboolean send_chat_states; priv = GET_PRIV (chat); + send_chat_states = g_settings_get_boolean (priv->gsettings_chat, + EMPATHY_PREFS_CHAT_SEND_CHAT_STATES); + if (!send_chat_states) { + return; + } + if (priv->composing_stop_timeout_id) { /* Just restart the timeout */ chat_composing_remove_timeout (chat); @@ -896,14 +919,12 @@ chat_command_me (EmpathyChat *chat, if (!tp_text_channel_supports_message_type (channel, TP_CHANNEL_TEXT_MESSAGE_TYPE_ACTION)) { /* Action message are not supported, 'simulate' the action */ - EmpathyContact *self_contact; gchar *tmp; - self_contact = empathy_tp_chat_get_self_contact (priv->tp_chat); /* The TpChat can't be ready if it doesn't have the self contact */ - g_assert (self_contact != NULL); + g_assert (priv->self_contact != NULL); - tmp = g_strdup_printf ("%s %s", empathy_contact_get_alias (self_contact), + tmp = g_strdup_printf ("%s %s", empathy_contact_get_alias (priv->self_contact), strv[1]); message = tp_client_message_new_text (TP_CHANNEL_TEXT_MESSAGE_TYPE_NORMAL, tmp); @@ -1408,15 +1429,31 @@ get_highlight_regex_for (const gchar *name) return regex; } +/* Called when priv->self_contact changes, or priv->self_contact:alias changes. + * Only connected if empathy_chat_is_room() is TRUE, for obvious-ish reasons. + */ +static void +chat_self_contact_alias_changed_cb (EmpathyChat *chat) +{ + EmpathyChatPriv *priv = GET_PRIV (chat); + + tp_clear_pointer (&priv->highlight_regex, g_regex_unref); + + if (priv->self_contact != NULL) { + const gchar *alias = empathy_contact_get_alias (priv->self_contact); + + g_return_if_fail (alias != NULL); + priv->highlight_regex = get_highlight_regex_for (alias); + } +} + static gboolean chat_should_highlight (EmpathyChat *chat, EmpathyMessage *message) { - EmpathyContact *contact; - const gchar *msg, *to; - gboolean ret_val = FALSE; + EmpathyChatPriv *priv = GET_PRIV (chat); + const gchar *msg; TpChannelTextMessageFlags flags; - GRegex *regex; g_return_val_if_fail (EMPATHY_IS_MESSAGE (message), FALSE); @@ -1433,16 +1470,6 @@ chat_should_highlight (EmpathyChat *chat, return FALSE; } - contact = empathy_tp_chat_get_self_contact (chat->priv->tp_chat); - if (!contact) { - return FALSE; - } - - to = empathy_contact_get_alias (contact); - if (!to) { - return FALSE; - } - flags = empathy_message_get_flags (message); if (flags & TP_CHANNEL_TEXT_MESSAGE_FLAG_SCROLLBACK) { /* FIXME: Ideally we shouldn't highlight scrollback messages only if they @@ -1450,13 +1477,11 @@ chat_should_highlight (EmpathyChat *chat, return FALSE; } - regex = get_highlight_regex_for (to); - if (regex != NULL) { - ret_val = g_regex_match (regex, msg, 0, NULL); - g_regex_unref (regex); + if (priv->highlight_regex == NULL) { + return FALSE; } - return ret_val; + return g_regex_match (priv->highlight_regex, msg, 0, NULL); } static void @@ -1477,6 +1502,11 @@ chat_message_received (EmpathyChat *chat, empathy_chat_view_edit_message (chat->view, message); } else { gboolean should_highlight = chat_should_highlight (chat, message); + + if (should_highlight) { + priv->highlighted = TRUE; + } + DEBUG ("Appending new message '%s' from %s (%d)", empathy_message_get_token (message), empathy_contact_get_alias (sender), @@ -1682,15 +1712,26 @@ chat_subject_changed_cb (EmpathyChat *chat) gtk_widget_show (priv->hbox_topic); } if (priv->block_events_timeout_id == 0) { - gchar *str; + gchar *str = NULL; if (!EMP_STR_EMPTY (priv->subject)) { - str = g_strdup_printf (_("Topic set to: %s"), priv->subject); - } else { + const gchar *actor = empathy_tp_chat_get_subject_actor (priv->tp_chat); + + if (tp_str_empty (actor)) { + str = g_strdup_printf (_("Topic set to: %s"), priv->subject); + } else { + str = g_strdup_printf (_("Topic set by %s to: %s"), + actor, priv->subject); + } + } else if (empathy_tp_chat_supports_subject (priv->tp_chat)) { + /* No need to display this 'event' is no topic can be defined anyway */ str = g_strdup (_("No topic defined")); } - empathy_chat_view_append_event (EMPATHY_CHAT (chat)->view, str); - g_free (str); + + if (str != NULL) { + empathy_chat_view_append_event (EMPATHY_CHAT (chat)->view, str); + g_free (str); + } } } @@ -2875,6 +2916,32 @@ empathy_chat_set_show_contacts (EmpathyChat *chat, g_object_notify (G_OBJECT (chat), "show-contacts"); } +static void +chat_self_contact_changed_cb (EmpathyChat *chat) +{ + EmpathyChatPriv *priv = GET_PRIV (chat); + + if (priv->self_contact != NULL) { + g_signal_handlers_disconnect_by_func (priv->self_contact, + chat_self_contact_alias_changed_cb, + chat); + } + g_clear_object (&priv->self_contact); + + priv->self_contact = empathy_tp_chat_get_self_contact (priv->tp_chat); + if (priv->self_contact != NULL) { + g_object_ref (priv->self_contact); + + if (empathy_chat_is_room (chat)) { + g_signal_connect_swapped (priv->self_contact, "notify::alias", + G_CALLBACK (chat_self_contact_alias_changed_cb), + chat); + } + } + + chat_self_contact_alias_changed_cb (chat); +} + static void chat_remote_contact_changed_cb (EmpathyChat *chat) { @@ -3229,6 +3296,8 @@ chat_finalize (GObject *object) chat_state_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_self_contact_changed_cb, chat); g_signal_handlers_disconnect_by_func (priv->tp_chat, chat_remote_contact_changed_cb, chat); g_signal_handlers_disconnect_by_func (priv->tp_chat, @@ -3241,6 +3310,12 @@ chat_finalize (GObject *object) if (priv->account) { g_object_unref (priv->account); } + if (priv->self_contact) { + g_signal_handlers_disconnect_by_func (priv->self_contact, + chat_self_contact_alias_changed_cb, + chat); + g_object_unref (priv->self_contact); + } if (priv->remote_contact) { g_object_unref (priv->remote_contact); } @@ -3254,6 +3329,8 @@ chat_finalize (GObject *object) g_free (priv->subject); g_completion_free (priv->completion); + tp_clear_pointer (&priv->highlight_regex, g_regex_unref); + G_OBJECT_CLASS (empathy_chat_parent_class)->finalize (object); } @@ -3958,6 +4035,9 @@ empathy_chat_set_tp_chat (EmpathyChat *chat, g_signal_connect (tp_chat, "member-renamed", G_CALLBACK (chat_member_renamed_cb), chat); + g_signal_connect_swapped (tp_chat, "notify::self-contact", + G_CALLBACK (chat_self_contact_changed_cb), + chat); g_signal_connect_swapped (tp_chat, "notify::remote-contact", G_CALLBACK (chat_remote_contact_changed_cb), chat); @@ -3979,6 +4059,7 @@ empathy_chat_set_tp_chat (EmpathyChat *chat, /* Get initial value of properties */ chat_sms_channel_changed_cb (chat); + chat_self_contact_changed_cb (chat); chat_remote_contact_changed_cb (chat); chat_title_changed_cb (chat); chat_subject_changed_cb (chat); @@ -4088,7 +4169,8 @@ empathy_chat_get_contact_menu (EmpathyChat *chat) if (contact == NULL) return NULL; - individual = empathy_create_individual_from_tp_contact (contact); + individual = empathy_ensure_individual_from_tp_contact (contact); + if (individual == NULL) return NULL; @@ -4250,6 +4332,16 @@ empathy_chat_is_room (EmpathyChat *chat) return (priv->handle_type == TP_HANDLE_TYPE_ROOM); } +gboolean +empathy_chat_is_highlighted (EmpathyChat *chat) +{ + EmpathyChatPriv *priv = GET_PRIV (chat); + + g_return_val_if_fail (EMPATHY_IS_CHAT (chat), FALSE); + + return priv->highlighted; +} + guint empathy_chat_get_nb_unread_messages (EmpathyChat *self) { @@ -4278,6 +4370,8 @@ empathy_chat_messages_read (EmpathyChat *self) TP_TEXT_CHANNEL (priv->tp_chat), NULL, NULL); } + priv->highlighted = FALSE; + if (priv->unread_messages_when_offline > 0) { /* We can't ack those as the connection has gone away so just consider * them as read. */