#include "empathy-conf.h"
#include "empathy-ui-utils.h"
#include "empathy-plist.h"
+#include "empathy-string-parser.h"
#define DEBUG_FLAG EMPATHY_DEBUG_CHAT
#include <libempathy/empathy-debug.h>
}
static void
-theme_adium_parser_escape (GString *string,
- const gchar *text,
+theme_adium_match_newline (const gchar *text,
gssize len,
+ EmpathyStringReplace replace_func,
+ EmpathyStringParser *sub_parsers,
gpointer user_data)
{
- gchar *escaped;
-
- escaped = g_markup_escape_text (text, len);
- g_string_append (string, escaped);
- g_free (escaped);
-}
-
-static void
-theme_adium_parser_newline (GString *string,
- const gchar *text,
- gssize len,
- gpointer user_data)
-{
+ GString *string = user_data;
gint i;
gint prev = 0;
/* Replace \n by <br/> */
for (i = 0; i < len && text[i] != '\0'; i++) {
if (text[i] == '\n') {
- empathy_string_parser_substr (string, text + prev,
- i - prev, user_data);
+ empathy_string_parser_substr (text + prev,
+ i - prev, sub_parsers,
+ user_data);
g_string_append (string, "<br/>");
prev = i + 1;
}
}
- empathy_string_parser_substr (string, text + prev, i - prev, user_data);
+ empathy_string_parser_substr (text + prev, i - prev,
+ sub_parsers, user_data);
}
static void
-theme_adium_parser_smiley (GString *string,
- const gchar *text,
- gssize len,
- gpointer user_data)
-{
- gboolean use_smileys = FALSE;
- gint last = 0;
-
- empathy_conf_get_bool (empathy_conf_get (),
- EMPATHY_PREFS_CHAT_SHOW_SMILEYS,
- &use_smileys);
-
- if (use_smileys) {
- EmpathySmileyManager *smiley_manager;
- GSList *hits, *l;
-
- smiley_manager = empathy_smiley_manager_dup_singleton ();
- hits = empathy_smiley_manager_parse_len (smiley_manager, text, len);
-
- for (l = hits; l; l = l->next) {
- EmpathySmileyHit *hit = l->data;
-
- if (hit->start > last) {
- /* Append the text between last smiley (or the
- * start of the message) and this smiley */
- empathy_string_parser_substr (string, text + last,
- hit->start - last,
- user_data);
- }
-
- /* Replace smileys by a <img/> tag */
- g_string_append (string, "<abbr title=\"");
- g_string_append_len (string, text + hit->start,
- hit->end - hit->start);
- g_string_append_printf (string, "\"><img src=\"%s\" alt=\"",
- hit->path);
- g_string_append_len (string, text + hit->start,
- hit->end - hit->start);
- g_string_append (string, "\"/></abbr>");
-
- last = hit->end;
-
- empathy_smiley_hit_free (hit);
- }
- g_slist_free (hits);
- g_object_unref (smiley_manager);
- }
-
- empathy_string_parser_substr (string, text + last, len - last, user_data);
-}
-
-static void
-theme_adium_parser_url (GString *string,
- const gchar *text,
- gssize len,
- gpointer user_data)
+theme_adium_replace_smiley (const gchar *text,
+ gssize len,
+ gpointer match_data,
+ gpointer user_data)
{
- GRegex *uri_regex;
- GMatchInfo *match_info;
- gboolean match;
- gint last = 0;
-
- /* Add <a href></a> arround links */
- uri_regex = empathy_uri_regex_dup_singleton ();
- match = g_regex_match_full (uri_regex, text, len, 0, 0, &match_info, NULL);
- if (match) {
- gint s = 0, e = 0;
-
- do {
- gchar *real_url;
-
- g_match_info_fetch_pos (match_info, 0, &s, &e);
-
- if (s > last) {
- /* Append the text between last link (or the
- * start of the message) and this link */
- empathy_string_parser_substr (string, text + last,
- s - last,
- user_data);
- }
-
- /* Append the link inside <a href=""></a> tag */
- real_url = empathy_make_absolute_url_len (text + s, e - s);
-
- g_string_append_printf (string, "<a href=\"%s\">",
- real_url);
- g_string_append_len (string, text + s, e - s);
- g_string_append (string, "</a>");
-
- g_free (real_url);
- last = e;
- } while (g_match_info_next (match_info, NULL));
- }
+ EmpathySmileyHit *hit = match_data;
+ GString *string = user_data;
- empathy_string_parser_substr (string, text + last, len - last, user_data);
-
- g_match_info_free (match_info);
- g_regex_unref (uri_regex);
+ /* Replace smiley by a <img/> tag */
+ g_string_append_printf (string,
+ "<img src=\"%s\" alt=\"%.*s\" title=\"%.*s\"/>",
+ hit->path, (int)len, text, (int)len, text);
}
static EmpathyStringParser string_parsers[] = {
- theme_adium_parser_url,
- theme_adium_parser_smiley,
- theme_adium_parser_newline,
- theme_adium_parser_escape,
- NULL,
+ {empathy_string_match_link, empathy_string_replace_link},
+ {theme_adium_match_newline, NULL},
+ {empathy_string_match_all, empathy_string_replace_escaped},
+ {NULL, NULL}
+};
+
+static EmpathyStringParser string_parsers_with_smiley[] = {
+ {empathy_string_match_link, empathy_string_replace_link},
+ {empathy_string_match_smiley, theme_adium_replace_smiley},
+ {theme_adium_match_newline, NULL},
+ {empathy_string_match_all, empathy_string_replace_escaped},
+ {NULL, NULL}
};
static gchar *
theme_adium_parse_body (const gchar *text)
{
+ EmpathyStringParser *parsers;
GString *string;
+ gboolean use_smileys;
- /* We parse text in 4 steps: url, smiley, newline, escape.
- * For each step, we detect the position of tokens in the text, and
- * we give text between each token to the next level parser.
- *
- * For example the string "Hello :)\n www.test.com"
- * 1) The url parser detects "www.test.com" and gives "Hello :)\n " to
- * the smiley parser, then insert the <a> tag for the link.
- * 2) The smiley parser will detect ":)". It first gives "Hello "
- * to the newline parser, then insert the <img/> tag for the smiley,
- * and finally give "\n " to the newline parser.
- * 3a) The newline parser gets "Hello " and escape it.
- * 3b) The newline parser gets "\n " and replace to "<br/> ".
- */
-
+ /* Check if we have to parse smileys */
+ empathy_conf_get_bool (empathy_conf_get (),
+ EMPATHY_PREFS_CHAT_SHOW_SMILEYS,
+ &use_smileys);
+ if (use_smileys)
+ parsers = string_parsers_with_smiley;
+ else
+ parsers = string_parsers;
+
+ /* Parse text and construct string with links and smileys replaced
+ * by html tags. Also escape text to make sure html code is
+ * displayed verbatim. */
string = g_string_sized_new (strlen (text));
- empathy_string_parser_substr (string, text, -1, string_parsers);
+ empathy_string_parser_substr (text, -1, parsers, string);
return g_string_free (string, FALSE);
}
g_free (script);
}
+static void
+theme_adium_append_event_escaped (EmpathyChatView *view,
+ const gchar *escaped)
+{
+ EmpathyThemeAdium *theme = EMPATHY_THEME_ADIUM (view);
+ EmpathyThemeAdiumPriv *priv = GET_PRIV (theme);
+
+ if (priv->data->status_html) {
+ theme_adium_append_html (theme, "appendMessage",
+ priv->data->status_html,
+ priv->data->status_len,
+ escaped, NULL, NULL, NULL, NULL,
+ "event", empathy_time_get_current ());
+ }
+
+ /* There is no last contact */
+ if (priv->last_contact) {
+ g_object_unref (priv->last_contact);
+ priv->last_contact = NULL;
+ }
+}
+
static void
theme_adium_append_message (EmpathyChatView *view,
EmpathyMessage *msg)
gchar *str;
str = g_strdup_printf ("%s %s", name, body_escaped);
- empathy_chat_view_append_event (view, str);
+ theme_adium_append_event_escaped (view, str);
+
g_free (str);
g_free (body_escaped);
return;
theme_adium_append_event (EmpathyChatView *view,
const gchar *str)
{
- EmpathyThemeAdium *theme = EMPATHY_THEME_ADIUM (view);
- EmpathyThemeAdiumPriv *priv = GET_PRIV (theme);
-
- if (priv->data->status_html) {
- gchar *str_escaped;
+ gchar *str_escaped;
- str_escaped = g_markup_escape_text (str, -1);
- theme_adium_append_html (theme, "appendMessage",
- priv->data->status_html,
- priv->data->status_len,
- str_escaped, NULL, NULL, NULL, NULL,
- "event", empathy_time_get_current ());
- g_free (str_escaped);
- }
-
- /* There is no last contact */
- if (priv->last_contact) {
- g_object_unref (priv->last_contact);
- priv->last_contact = NULL;
- }
+ str_escaped = g_markup_escape_text (str, -1);
+ theme_adium_append_event_escaped (view, str_escaped);
+ g_free (str_escaped);
}
static void
static gboolean
theme_adium_find_previous (EmpathyChatView *view,
const gchar *search_criteria,
- gboolean new_search)
+ gboolean new_search,
+ gboolean match_case)
{
+ /* FIXME: Doesn't respect new_search */
return webkit_web_view_search_text (WEBKIT_WEB_VIEW (view),
- search_criteria, FALSE,
+ search_criteria, match_case,
FALSE, TRUE);
}
static gboolean
theme_adium_find_next (EmpathyChatView *view,
const gchar *search_criteria,
- gboolean new_search)
+ gboolean new_search,
+ gboolean match_case)
{
+ /* FIXME: Doesn't respect new_search */
return webkit_web_view_search_text (WEBKIT_WEB_VIEW (view),
- search_criteria, FALSE,
+ search_criteria, match_case,
TRUE, TRUE);
}
static void
theme_adium_find_abilities (EmpathyChatView *view,
const gchar *search_criteria,
+ gboolean match_case,
gboolean *can_do_previous,
gboolean *can_do_next)
{
static void
theme_adium_highlight (EmpathyChatView *view,
- const gchar *text)
+ const gchar *text,
+ gboolean match_case)
{
webkit_web_view_unmark_text_matches (WEBKIT_WEB_VIEW (view));
webkit_web_view_mark_text_matches (WEBKIT_WEB_VIEW (view),
- text, FALSE, 0);
+ text, match_case, 0);
webkit_web_view_set_highlight_text_matches (WEBKIT_WEB_VIEW (view),
TRUE);
}
gtk_widget_show_all (menu);
gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL,
event->button, event->time);
+ g_object_ref_sink (menu);
+ g_object_unref (menu);
}
static gboolean