From aded85c91fb409bafb06492ddb85aa1224178d4c Mon Sep 17 00:00:00 2001 From: Will Thompson Date: Wed, 18 Jan 2012 15:41:07 +0000 Subject: Use /\b\b/ to decide whether to highlight MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The current highlighting code finds the first occurrence of the nickname, then checks whether the characters before or after are a space, a comma, a colon or a full stop (or the start or end of the string). This means that someone saying “no! That's wjt’s coffee!” didn’t highlight me, because the apostrophe isn't in the whitelist. It also means that saying “borrow some Sudafed from daf” would not highlight daf, since the first match is in the middle of a word. We’re trying to check whether the nickname occurs as a complete word within the message. The regex metacharacter \b matches word boundaries, so /\b\b/ is what we actually want. It gets the above cases right, including Unicode punctuation. https://bugzilla.gnome.org/show_bug.cgi?id=591667 --- libempathy/empathy-message.c | 67 ++++++++++++++++++++++---------------------- 1 file changed, 34 insertions(+), 33 deletions(-) diff --git a/libempathy/empathy-message.c b/libempathy/empathy-message.c index 995f49ab7..9841cbb61 100644 --- a/libempathy/empathy-message.c +++ b/libempathy/empathy-message.c @@ -39,6 +39,9 @@ # include #endif +#define DEBUG_FLAG EMPATHY_DEBUG_CHAT +#include "empathy-debug.h" + #include "empathy-client-factory.h" #include "empathy-message.h" #include "empathy-utils.h" @@ -633,21 +636,42 @@ empathy_message_is_backlog (EmpathyMessage *message) return priv->is_backlog; } -#define IS_SEPARATOR(ch) (ch == ' ' || ch == ',' || ch == '.' || ch == ':') +static GRegex * +get_highlight_regex_for (const gchar *name) +{ + GRegex *regex; + gchar *name_esc, *pattern; + GError *error = NULL; + + name_esc = g_regex_escape_string (name, -1); + pattern = g_strdup_printf ("\\b%s\\b", name_esc); + regex = g_regex_new (pattern, G_REGEX_CASELESS | G_REGEX_OPTIMIZE, 0, + &error); + + if (regex == NULL) { + DEBUG ("couldn't compile regex /%s/: %s", pattern, + error->message); + + g_error_free (error); + } + + g_free (pattern); + g_free (name_esc); + + return regex; +} + gboolean empathy_message_should_highlight (EmpathyMessage *message) { EmpathyContact *contact; const gchar *msg, *to; - gchar *cf_msg, *cf_to; - gchar *ch; - gboolean ret_val; + gboolean ret_val = FALSE; TpChannelTextMessageFlags flags; + GRegex *regex; g_return_val_if_fail (EMPATHY_IS_MESSAGE (message), FALSE); - ret_val = FALSE; - msg = empathy_message_get_body (message); if (!msg) { return FALSE; @@ -670,34 +694,11 @@ empathy_message_should_highlight (EmpathyMessage *message) 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; + regex = get_highlight_regex_for (to); + if (regex != NULL) { + ret_val = g_regex_match (regex, msg, 0, NULL); + g_regex_unref (regex); } - 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; } -- cgit v1.2.3 From 3030fa4e082c695fa25b564e513307f3423feaae Mon Sep 17 00:00:00 2001 From: Will Thompson Date: Wed, 18 Jan 2012 15:54:48 +0000 Subject: chat_view_append_message: take a should_highlight argument Rather than the EmpathyChatView implementations calling empathy_message_should_highlight() themselves, this patch makes EmpathyChat take responsibility for doing so. The theme preview in Preferences, whether deliberately or otherwise, highlights the line in which Juliet mentions Romeo. This behaviour is preserved. --- libempathy-gtk/empathy-chat-text-view.c | 6 ++++-- libempathy-gtk/empathy-chat-text-view.h | 3 ++- libempathy-gtk/empathy-chat-view.c | 6 ++++-- libempathy-gtk/empathy-chat-view.h | 6 ++++-- libempathy-gtk/empathy-chat.c | 9 ++++++--- libempathy-gtk/empathy-theme-adium.c | 19 ++++++++++++------- libempathy-gtk/empathy-theme-boxes.c | 3 ++- libempathy-gtk/empathy-theme-irc.c | 5 +++-- src/empathy-preferences.c | 16 +++++++++------- 9 files changed, 46 insertions(+), 27 deletions(-) diff --git a/libempathy-gtk/empathy-chat-text-view.c b/libempathy-gtk/empathy-chat-text-view.c index c251f1f42..60d642ccb 100644 --- a/libempathy-gtk/empathy-chat-text-view.c +++ b/libempathy-gtk/empathy-chat-text-view.c @@ -717,7 +717,8 @@ chat_text_view_scroll_down (EmpathyChatView *view) static void chat_text_view_append_message (EmpathyChatView *view, - EmpathyMessage *msg) + EmpathyMessage *msg, + gboolean should_highlight) { EmpathyChatTextView *text_view = EMPATHY_CHAT_TEXT_VIEW (view); EmpathyChatTextViewPriv *priv = GET_PRIV (text_view); @@ -739,7 +740,8 @@ chat_text_view_append_message (EmpathyChatView *view, chat_text_maybe_append_date_and_time (text_view, timestamp); if (EMPATHY_CHAT_TEXT_VIEW_GET_CLASS (view)->append_message) { EMPATHY_CHAT_TEXT_VIEW_GET_CLASS (view)->append_message (text_view, - msg); + msg, + should_highlight); } if (bottom) { diff --git a/libempathy-gtk/empathy-chat-text-view.h b/libempathy-gtk/empathy-chat-text-view.h index 12edbcc64..ce83fd2fa 100644 --- a/libempathy-gtk/empathy-chat-text-view.h +++ b/libempathy-gtk/empathy-chat-text-view.h @@ -56,7 +56,8 @@ struct _EmpathyChatTextViewClass { /* */ void (*append_message) (EmpathyChatTextView *view, - EmpathyMessage *message); + EmpathyMessage *message, + gboolean should_highlight); }; #define EMPATHY_CHAT_TEXT_VIEW_TAG_CUT "cut" diff --git a/libempathy-gtk/empathy-chat-view.c b/libempathy-gtk/empathy-chat-view.c index 088b12084..f5d6ddf09 100644 --- a/libempathy-gtk/empathy-chat-view.c +++ b/libempathy-gtk/empathy-chat-view.c @@ -61,13 +61,15 @@ chat_view_base_init (gpointer klass) void empathy_chat_view_append_message (EmpathyChatView *view, - EmpathyMessage *msg) + EmpathyMessage *msg, + gboolean should_highlight) { g_return_if_fail (EMPATHY_IS_CHAT_VIEW (view)); if (EMPATHY_TYPE_CHAT_VIEW_GET_IFACE (view)->append_message) { EMPATHY_TYPE_CHAT_VIEW_GET_IFACE (view)->append_message (view, - msg); + msg, + should_highlight); } } diff --git a/libempathy-gtk/empathy-chat-view.h b/libempathy-gtk/empathy-chat-view.h index bc9e91761..2c47e0429 100644 --- a/libempathy-gtk/empathy-chat-view.h +++ b/libempathy-gtk/empathy-chat-view.h @@ -43,7 +43,8 @@ struct _EmpathyChatViewIface { /* VTabled */ void (*append_message) (EmpathyChatView *view, - EmpathyMessage *msg); + EmpathyMessage *msg, + gboolean should_highlight); void (*append_event) (EmpathyChatView *view, const gchar *str); void (*append_event_markup) (EmpathyChatView *view, @@ -81,7 +82,8 @@ struct _EmpathyChatViewIface { GType empathy_chat_view_get_type (void) G_GNUC_CONST; void empathy_chat_view_append_message (EmpathyChatView *view, - EmpathyMessage *msg); + EmpathyMessage *msg, + gboolean should_highlight); void empathy_chat_view_append_event (EmpathyChatView *view, const gchar *str); void empathy_chat_view_append_event_markup (EmpathyChatView *view, diff --git a/libempathy-gtk/empathy-chat.c b/libempathy-gtk/empathy-chat.c index 1496f582d..c8ef24809 100644 --- a/libempathy-gtk/empathy-chat.c +++ b/libempathy-gtk/empathy-chat.c @@ -1400,12 +1400,13 @@ chat_message_received (EmpathyChat *chat, empathy_chat_view_edit_message (chat->view, message); } else { + gboolean should_highlight = empathy_message_should_highlight (message); DEBUG ("Appending new message '%s' from %s (%d)", empathy_message_get_token (message), empathy_contact_get_alias (sender), empathy_contact_get_handle (sender)); - empathy_chat_view_append_message (chat->view, message); + empathy_chat_view_append_message (chat->view, message, should_highlight); if (empathy_message_is_incoming (message)) { priv->unread_messages++; @@ -2491,13 +2492,15 @@ got_filtered_messages_cb (GObject *manager, "sender", empathy_message_get_sender (message), NULL); - empathy_chat_view_append_message (chat->view, syn_msg); + empathy_chat_view_append_message (chat->view, syn_msg, + empathy_message_should_highlight (syn_msg)); empathy_chat_view_edit_message (chat->view, message); g_object_unref (syn_msg); } else { /* append the latest message */ - empathy_chat_view_append_message (chat->view, message); + empathy_chat_view_append_message (chat->view, message, + empathy_message_should_highlight (message)); } g_object_unref (message); diff --git a/libempathy-gtk/empathy-theme-adium.c b/libempathy-gtk/empathy-theme-adium.c index 7b0cd2169..98df46b79 100644 --- a/libempathy-gtk/empathy-theme-adium.c +++ b/libempathy-gtk/empathy-theme-adium.c @@ -132,13 +132,15 @@ typedef struct { guint type; EmpathyMessage *msg; char *str; + gboolean should_highlight; } QueuedItem; static QueuedItem * queue_item (GQueue *queue, guint type, EmpathyMessage *msg, - const char *str) + const char *str, + gboolean should_highlight) { QueuedItem *item = g_slice_new0 (QueuedItem); @@ -146,6 +148,7 @@ queue_item (GQueue *queue, if (msg != NULL) item->msg = g_object_ref (msg); item->str = g_strdup (str); + item->should_highlight = should_highlight; g_queue_push_tail (queue, item); @@ -775,7 +778,8 @@ theme_adium_remove_all_focus_marks (EmpathyThemeAdium *theme) static void theme_adium_append_message (EmpathyChatView *view, - EmpathyMessage *msg) + EmpathyMessage *msg, + gboolean should_highlight) { EmpathyThemeAdium *theme = EMPATHY_THEME_ADIUM (view); EmpathyThemeAdiumPriv *priv = GET_PRIV (theme); @@ -797,7 +801,7 @@ theme_adium_append_message (EmpathyChatView *view, gboolean action; if (priv->pages_loading != 0) { - queue_item (&priv->message_queue, QUEUED_MESSAGE, msg, NULL); + queue_item (&priv->message_queue, QUEUED_MESSAGE, msg, NULL, should_highlight); return; } @@ -886,7 +890,7 @@ theme_adium_append_message (EmpathyChatView *view, } else { g_string_append (message_classes, " incoming"); } - if (empathy_message_should_highlight (msg)) { + if (should_highlight) { g_string_append (message_classes, " mention"); } if (empathy_message_get_tptype (msg) == TP_CHANNEL_TEXT_MESSAGE_TYPE_AUTO_REPLY) { @@ -975,7 +979,7 @@ theme_adium_append_event (EmpathyChatView *view, gchar *str_escaped; if (priv->pages_loading != 0) { - queue_item (&priv->message_queue, QUEUED_EVENT, NULL, str); + queue_item (&priv->message_queue, QUEUED_EVENT, NULL, str, FALSE); return; } @@ -1005,7 +1009,7 @@ theme_adium_edit_message (EmpathyChatView *view, GError *error = NULL; if (priv->pages_loading != 0) { - queue_item (&priv->message_queue, QUEUED_EDIT, message, NULL); + queue_item (&priv->message_queue, QUEUED_EDIT, message, NULL, FALSE); return; } @@ -1345,7 +1349,8 @@ theme_adium_load_finished_cb (WebKitWebView *view, switch (item->type) { case QUEUED_MESSAGE: - theme_adium_append_message (chat_view, item->msg); + theme_adium_append_message (chat_view, item->msg, + item->should_highlight); break; case QUEUED_EDIT: diff --git a/libempathy-gtk/empathy-theme-boxes.c b/libempathy-gtk/empathy-theme-boxes.c index b9fd08d84..cf0c65268 100644 --- a/libempathy-gtk/empathy-theme-boxes.c +++ b/libempathy-gtk/empathy-theme-boxes.c @@ -337,7 +337,8 @@ theme_boxes_maybe_append_header (EmpathyThemeBoxes *theme, static void theme_boxes_append_message (EmpathyChatTextView *view, - EmpathyMessage *message) + EmpathyMessage *message, + gboolean should_highlight) { EmpathyContact *sender; diff --git a/libempathy-gtk/empathy-theme-irc.c b/libempathy-gtk/empathy-theme-irc.c index 2ee81a23e..ed8e3b380 100644 --- a/libempathy-gtk/empathy-theme-irc.c +++ b/libempathy-gtk/empathy-theme-irc.c @@ -50,7 +50,8 @@ theme_irc_create_tags (EmpathyThemeIrc *theme) static void theme_irc_append_message (EmpathyChatTextView *view, - EmpathyMessage *message) + EmpathyMessage *message, + gboolean should_highlight) { GtkTextBuffer *buffer; const gchar *name; @@ -77,7 +78,7 @@ theme_irc_append_message (EmpathyChatTextView *view, if (empathy_contact_is_user (contact)) { nick_tag = EMPATHY_THEME_IRC_TAG_NICK_SELF; } else { - if (empathy_message_should_highlight (message)) { + if (should_highlight) { nick_tag = EMPATHY_THEME_IRC_TAG_NICK_HIGHLIGHT; } else { nick_tag = EMPATHY_THEME_IRC_TAG_NICK_OTHER; diff --git a/src/empathy-preferences.c b/src/empathy-preferences.c index 6775d4a24..cd755a9ae 100644 --- a/src/empathy-preferences.c +++ b/src/empathy-preferences.c @@ -678,7 +678,8 @@ static void preferences_preview_theme_append_message (EmpathyChatView *view, EmpathyContact *sender, EmpathyContact *receiver, - const gchar *text) + const gchar *text, + gboolean should_highlight) { EmpathyMessage *message; @@ -688,7 +689,7 @@ preferences_preview_theme_append_message (EmpathyChatView *view, "body", text, NULL); - empathy_chat_view_append_message (view, message); + empathy_chat_view_append_message (view, message, should_highlight); g_object_unref (message); } @@ -735,19 +736,20 @@ preferences_preview_theme_changed_cb (EmpathyThemeManager *manager, preferences_preview_theme_append_message (priv->chat_theme_preview, /* translators: Quote from Romeo & Julier, for chat theme preview */ - juliet, romeo, _("O Romeo, Romeo, wherefore art thou Romeo?")); + juliet, romeo, _("O Romeo, Romeo, wherefore art thou Romeo?"), + TRUE /* this message mentions Romeo */); preferences_preview_theme_append_message (priv->chat_theme_preview, /* translators: Quote from Romeo & Julier, for chat theme preview */ - juliet, romeo, _("Deny thy father and refuse thy name;")); + juliet, romeo, _("Deny thy father and refuse thy name;"), FALSE); preferences_preview_theme_append_message (priv->chat_theme_preview, /* translators: Quote from Romeo & Julier, for chat theme preview */ - juliet, romeo, _("Or if thou wilt not, be but sworn my love")); + juliet, romeo, _("Or if thou wilt not, be but sworn my love"), FALSE); preferences_preview_theme_append_message (priv->chat_theme_preview, /* translators: Quote from Romeo & Julier, for chat theme preview */ - juliet, romeo, _("And I'll no longer be a Capulet.")); + juliet, romeo, _("And I'll no longer be a Capulet."), FALSE); preferences_preview_theme_append_message (priv->chat_theme_preview, /* translators: Quote from Romeo & Julier, for chat theme preview */ - romeo, juliet, _("Shall I hear more, or shall I speak at this?")); + romeo, juliet, _("Shall I hear more, or shall I speak at this?"), FALSE); /* translators: Quote from Romeo & Julier, for chat theme preview */ empathy_chat_view_append_event (priv->chat_theme_preview, _("Juliet has disconnected")); -- cgit v1.2.3 From be14bbb863d0fc83402f9307e5193175d77e6d0d Mon Sep 17 00:00:00 2001 From: Will Thompson Date: Wed, 18 Jan 2012 16:03:00 +0000 Subject: EmpathyChat: include should_highlight in ::new-message This allows EmpathyChatWindow to use this rather than calling empathy_message_should_highlight() itself. --- libempathy-gtk/empathy-chat.c | 13 +++++++++++-- src/empathy-chat-window.c | 3 ++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/libempathy-gtk/empathy-chat.c b/libempathy-gtk/empathy-chat.c index c8ef24809..267cdca2a 100644 --- a/libempathy-gtk/empathy-chat.c +++ b/libempathy-gtk/empathy-chat.c @@ -1413,7 +1413,8 @@ chat_message_received (EmpathyChat *chat, g_object_notify (G_OBJECT (chat), "nb-unread-messages"); } - g_signal_emit (chat, signals[NEW_MESSAGE], 0, message, pending); + g_signal_emit (chat, signals[NEW_MESSAGE], 0, message, pending, + should_highlight); } /* We received a message so the contact is no longer @@ -3299,6 +3300,14 @@ empathy_chat_class_init (EmpathyChatClass *klass) G_TYPE_NONE, 1, G_TYPE_BOOLEAN); + /** + * EmpathyChat::new-message: + * @self: the #EmpathyChat + * @message: the new message + * @pending: whether the message was in the pending queue when @self + * was created + * @should_highlight: %TRUE if the message mentions the local user + */ signals[NEW_MESSAGE] = g_signal_new ("new-message", G_OBJECT_CLASS_TYPE (object_class), @@ -3307,7 +3316,7 @@ empathy_chat_class_init (EmpathyChatClass *klass) NULL, NULL, g_cclosure_marshal_generic, G_TYPE_NONE, - 2, EMPATHY_TYPE_MESSAGE, G_TYPE_BOOLEAN); + 3, EMPATHY_TYPE_MESSAGE, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN); signals[PART_COMMAND_ENTERED] = g_signal_new ("part-command-entered", diff --git a/src/empathy-chat-window.c b/src/empathy-chat-window.c index 1bb9de4aa..3e197796d 100644 --- a/src/empathy-chat-window.c +++ b/src/empathy-chat-window.c @@ -1437,6 +1437,7 @@ static void chat_window_new_message_cb (EmpathyChat *chat, EmpathyMessage *message, gboolean pending, + gboolean should_highlight, EmpathyChatWindow *window) { EmpathyChatWindowPriv *priv; @@ -1496,7 +1497,7 @@ chat_window_new_message_cb (EmpathyChat *chat, if (chatroom != NULL && empathy_chatroom_is_always_urgent (chatroom)) { needs_urgency = TRUE; } else { - needs_urgency = empathy_message_should_highlight (message); + needs_urgency = should_highlight; } } else { needs_urgency = TRUE; -- cgit v1.2.3 From b12ce233dce1dcd581b34ea9944e36e59f511497 Mon Sep 17 00:00:00 2001 From: Will Thompson Date: Wed, 18 Jan 2012 16:31:28 +0000 Subject: Move empathy_message_should_highlight to EmpathyChat This will give us a place to cache the GRegex object. (Of course, this also depends on monitoring changes to the TpChat's self contact's alias, and changes to the TpChat's self contact!) --- libempathy-gtk/empathy-chat.c | 74 +++++++++++++++++++++++++++++++++++++++++-- libempathy/empathy-message.c | 70 ---------------------------------------- libempathy/empathy-message.h | 1 - 3 files changed, 71 insertions(+), 74 deletions(-) diff --git a/libempathy-gtk/empathy-chat.c b/libempathy-gtk/empathy-chat.c index 267cdca2a..ea46e6b76 100644 --- a/libempathy-gtk/empathy-chat.c +++ b/libempathy-gtk/empathy-chat.c @@ -1383,6 +1383,74 @@ chat_state_changed_cb (EmpathyTpChat *tp_chat, } } +static GRegex * +get_highlight_regex_for (const gchar *name) +{ + GRegex *regex; + gchar *name_esc, *pattern; + GError *error = NULL; + + name_esc = g_regex_escape_string (name, -1); + pattern = g_strdup_printf ("\\b%s\\b", name_esc); + regex = g_regex_new (pattern, G_REGEX_CASELESS | G_REGEX_OPTIMIZE, 0, + &error); + + if (regex == NULL) { + DEBUG ("couldn't compile regex /%s/: %s", pattern, + error->message); + + g_error_free (error); + } + + g_free (pattern); + g_free (name_esc); + + return regex; +} + +static gboolean +chat_should_highlight (EmpathyChat *chat, + EmpathyMessage *message) +{ + EmpathyContact *contact; + const gchar *msg, *to; + gboolean ret_val = FALSE; + TpChannelTextMessageFlags flags; + GRegex *regex; + + g_return_val_if_fail (EMPATHY_IS_MESSAGE (message), FALSE); + + msg = empathy_message_get_body (message); + if (!msg) { + 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 + * have already been received by the user before (and so are in the logs) */ + return FALSE; + } + + regex = get_highlight_regex_for (to); + if (regex != NULL) { + ret_val = g_regex_match (regex, msg, 0, NULL); + g_regex_unref (regex); + } + + return ret_val; +} + static void chat_message_received (EmpathyChat *chat, EmpathyMessage *message, @@ -1400,7 +1468,7 @@ chat_message_received (EmpathyChat *chat, empathy_chat_view_edit_message (chat->view, message); } else { - gboolean should_highlight = empathy_message_should_highlight (message); + gboolean should_highlight = chat_should_highlight (chat, message); DEBUG ("Appending new message '%s' from %s (%d)", empathy_message_get_token (message), empathy_contact_get_alias (sender), @@ -2494,14 +2562,14 @@ got_filtered_messages_cb (GObject *manager, NULL); empathy_chat_view_append_message (chat->view, syn_msg, - empathy_message_should_highlight (syn_msg)); + chat_should_highlight (chat, syn_msg)); empathy_chat_view_edit_message (chat->view, message); g_object_unref (syn_msg); } else { /* append the latest message */ empathy_chat_view_append_message (chat->view, message, - empathy_message_should_highlight (message)); + chat_should_highlight (chat, message)); } g_object_unref (message); diff --git a/libempathy/empathy-message.c b/libempathy/empathy-message.c index 9841cbb61..6111bcd8c 100644 --- a/libempathy/empathy-message.c +++ b/libempathy/empathy-message.c @@ -39,9 +39,6 @@ # include #endif -#define DEBUG_FLAG EMPATHY_DEBUG_CHAT -#include "empathy-debug.h" - #include "empathy-client-factory.h" #include "empathy-message.h" #include "empathy-utils.h" @@ -636,73 +633,6 @@ empathy_message_is_backlog (EmpathyMessage *message) return priv->is_backlog; } -static GRegex * -get_highlight_regex_for (const gchar *name) -{ - GRegex *regex; - gchar *name_esc, *pattern; - GError *error = NULL; - - name_esc = g_regex_escape_string (name, -1); - pattern = g_strdup_printf ("\\b%s\\b", name_esc); - regex = g_regex_new (pattern, G_REGEX_CASELESS | G_REGEX_OPTIMIZE, 0, - &error); - - if (regex == NULL) { - DEBUG ("couldn't compile regex /%s/: %s", pattern, - error->message); - - g_error_free (error); - } - - g_free (pattern); - g_free (name_esc); - - return regex; -} - -gboolean -empathy_message_should_highlight (EmpathyMessage *message) -{ - EmpathyContact *contact; - const gchar *msg, *to; - gboolean ret_val = FALSE; - TpChannelTextMessageFlags flags; - GRegex *regex; - - g_return_val_if_fail (EMPATHY_IS_MESSAGE (message), 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_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 - * have already been received by the user before (and so are in the logs) */ - return FALSE; - } - - regex = get_highlight_regex_for (to); - if (regex != NULL) { - ret_val = g_regex_match (regex, msg, 0, NULL); - g_regex_unref (regex); - } - - return ret_val; -} - TpChannelTextMessageType empathy_message_type_from_str (const gchar *type_str) { diff --git a/libempathy/empathy-message.h b/libempathy/empathy-message.h index 0c27c09e9..81da7bf43 100644 --- a/libempathy/empathy-message.h +++ b/libempathy/empathy-message.h @@ -77,7 +77,6 @@ gint64 empathy_message_get_original_timestamp (EmpathyMessage gboolean empathy_message_is_backlog (EmpathyMessage *message); gboolean empathy_message_is_incoming (EmpathyMessage *message); -gboolean empathy_message_should_highlight (EmpathyMessage *message); TpChannelTextMessageType empathy_message_type_from_str (const gchar *type_str); const gchar * empathy_message_type_to_str (TpChannelTextMessageType type); -- cgit v1.2.3 From 7e3040b5be5fd1e4793ba14c89a380b8e526b499 Mon Sep 17 00:00:00 2001 From: Will Thompson Date: Wed, 18 Jan 2012 16:37:17 +0000 Subject: Don't highlight messages the user sent themself If a message is outgoing, then why on earth would we check whether it mentions our own nick and highlight it? --- libempathy-gtk/empathy-chat.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libempathy-gtk/empathy-chat.c b/libempathy-gtk/empathy-chat.c index ea46e6b76..ae6c0d934 100644 --- a/libempathy-gtk/empathy-chat.c +++ b/libempathy-gtk/empathy-chat.c @@ -1420,6 +1420,10 @@ chat_should_highlight (EmpathyChat *chat, g_return_val_if_fail (EMPATHY_IS_MESSAGE (message), FALSE); + if (!empathy_message_is_incoming (message)) { + return FALSE; + } + msg = empathy_message_get_body (message); if (!msg) { return FALSE; -- cgit v1.2.3 From 6d3a71637df970d2cf52d653399b66a213bae502 Mon Sep 17 00:00:00 2001 From: Will Thompson Date: Wed, 18 Jan 2012 16:40:16 +0000 Subject: Don't highlight messages in 1-1 chats. https://bugzilla.gnome.org/show_bug.cgi?id=576912 --- libempathy-gtk/empathy-chat.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libempathy-gtk/empathy-chat.c b/libempathy-gtk/empathy-chat.c index ae6c0d934..b1fb93d02 100644 --- a/libempathy-gtk/empathy-chat.c +++ b/libempathy-gtk/empathy-chat.c @@ -1420,6 +1420,10 @@ chat_should_highlight (EmpathyChat *chat, g_return_val_if_fail (EMPATHY_IS_MESSAGE (message), FALSE); + if (!empathy_chat_is_room (chat)) { + return FALSE; + } + if (!empathy_message_is_incoming (message)) { return FALSE; } -- cgit v1.2.3 From 06c82312669b409db53928d6d5fbe21ad3f5569a Mon Sep 17 00:00:00 2001 From: Will Thompson Date: Wed, 18 Jan 2012 16:57:51 +0000 Subject: TpChat: add a :self-contact property. --- libempathy/empathy-tp-chat.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/libempathy/empathy-tp-chat.c b/libempathy/empathy-tp-chat.c index 96eda77b8..fcef6e8a7 100644 --- a/libempathy/empathy-tp-chat.c +++ b/libempathy/empathy-tp-chat.c @@ -69,6 +69,7 @@ static void tp_chat_iface_init (EmpathyContactListIface *iface); enum { PROP_0, PROP_ACCOUNT, + PROP_SELF_CONTACT, PROP_REMOTE_CONTACT, PROP_N_MESSAGES_SENDING, PROP_TITLE, @@ -948,6 +949,7 @@ tp_chat_got_renamed_contacts_cb (TpConnection *connection, /* We change our nick */ tp_clear_object (&self->priv->user); self->priv->user = g_object_ref (new); + g_object_notify (chat, "self-contact"); } check_almost_ready (self); @@ -1068,6 +1070,7 @@ tp_chat_got_self_contact_cb (TpConnection *connection, self->priv->user = g_object_ref (contact); empathy_contact_set_is_user (self->priv->user, TRUE); + g_object_notify (chat, "self-contact"); check_almost_ready (self); } @@ -1083,6 +1086,9 @@ tp_chat_get_property (GObject *object, case PROP_ACCOUNT: g_value_set_object (value, self->priv->account); break; + case PROP_SELF_CONTACT: + g_value_set_object (value, self->priv->user); + break; case PROP_REMOTE_CONTACT: g_value_set_object (value, self->priv->remote_contact); break; @@ -1171,6 +1177,19 @@ empathy_tp_chat_class_init (EmpathyTpChatClass *klass) G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS)); + /** + * EmpathyTpChat:self-contact: + * + * Not to be confused with TpChannel:group-self-contact. + */ + g_object_class_install_property (object_class, + PROP_SELF_CONTACT, + g_param_spec_object ("self-contact", + "The local contact", + "The EmpathyContact for the local user on this channel", + EMPATHY_TYPE_CONTACT, + G_PARAM_READABLE)); + g_object_class_install_property (object_class, PROP_REMOTE_CONTACT, g_param_spec_object ("remote-contact", -- cgit v1.2.3 From 4280d01cb8eca11f4b076076f112d0b28560a402 Mon Sep 17 00:00:00 2001 From: Will Thompson Date: Wed, 18 Jan 2012 17:26:15 +0000 Subject: EmpathyChat: track self contact. --- libempathy-gtk/empathy-chat.c | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-) diff --git a/libempathy-gtk/empathy-chat.c b/libempathy-gtk/empathy-chat.c index b1fb93d02..cef45972b 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; @@ -896,14 +897,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); @@ -1412,7 +1411,6 @@ static gboolean chat_should_highlight (EmpathyChat *chat, EmpathyMessage *message) { - EmpathyContact *contact; const gchar *msg, *to; gboolean ret_val = FALSE; TpChannelTextMessageFlags flags; @@ -1433,12 +1431,11 @@ chat_should_highlight (EmpathyChat *chat, return FALSE; } - contact = empathy_tp_chat_get_self_contact (chat->priv->tp_chat); - if (!contact) { + if (!chat->priv->self_contact) { return FALSE; } - to = empathy_contact_get_alias (contact); + to = empathy_contact_get_alias (chat->priv->self_contact); if (!to) { return FALSE; } @@ -2875,6 +2872,19 @@ 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); + + 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); + } +} + static void chat_remote_contact_changed_cb (EmpathyChat *chat) { @@ -3229,6 +3239,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 +3253,9 @@ chat_finalize (GObject *object) if (priv->account) { g_object_unref (priv->account); } + if (priv->self_contact) { + g_object_unref (priv->self_contact); + } if (priv->remote_contact) { g_object_unref (priv->remote_contact); } @@ -3958,6 +3973,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 +3997,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); -- cgit v1.2.3 From cb4d7495d1ed8fabe40e552a4107ce6398814323 Mon Sep 17 00:00:00 2001 From: Will Thompson Date: Wed, 18 Jan 2012 17:45:32 +0000 Subject: EmpathyChat: cache highlight regex. --- libempathy-gtk/empathy-chat.c | 62 +++++++++++++++++++++++++++++++------------ 1 file changed, 45 insertions(+), 17 deletions(-) diff --git a/libempathy-gtk/empathy-chat.c b/libempathy-gtk/empathy-chat.c index cef45972b..d3c503206 100644 --- a/libempathy-gtk/empathy-chat.c +++ b/libempathy-gtk/empathy-chat.c @@ -156,6 +156,10 @@ 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; }; typedef struct { @@ -1407,14 +1411,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) { - 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); @@ -1431,15 +1452,6 @@ chat_should_highlight (EmpathyChat *chat, return FALSE; } - if (!chat->priv->self_contact) { - return FALSE; - } - - to = empathy_contact_get_alias (chat->priv->self_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 @@ -1447,13 +1459,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 @@ -2877,12 +2887,25 @@ 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 @@ -3254,6 +3277,9 @@ chat_finalize (GObject *object) 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) { @@ -3269,6 +3295,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); } -- cgit v1.2.3