Mercurial > pidgin.yaz
diff pidgin/gtkconv.c @ 16083:f2a4b05407d7
Patch from shlomil in ticket #78.
This fixes RTL text support in MSN, and lays the framework so it could be
supported in other prpls as well. As added pluses, shlomil removed some
duplicate code and fixed some small related bugs.
committer: Richard Laager <rlaager@wiktel.com>
author | Shlomi Loubaton <shlomister@gmail.com> |
---|---|
date | Fri, 13 Apr 2007 04:13:24 +0000 |
parents | 07554cc5d090 |
children | a5a831a5f186 |
line wrap: on
line diff
--- a/pidgin/gtkconv.c Fri Apr 13 02:43:11 2007 +0000 +++ b/pidgin/gtkconv.c Fri Apr 13 04:13:24 2007 +0000 @@ -4895,6 +4895,73 @@ gtkconv->newday = mktime(tm); } +/* Detect string direction and encapsulate the string in a RLE/LRE/PDF unicode characters + str - pointer to string (string is realocated and new pointer is returned) */ +static void +str_embed_direction_chars(char **str) +{ + char pre_str[4]; + char post_str[10]; + char* ret = g_malloc(strlen(*str)+13); + + if (PANGO_DIRECTION_RTL == pango_find_base_dir(*str, strlen(*str))) + { + g_sprintf(pre_str, "%c%c%c", + 0xE2, 0x80, 0xAB); /* RLE */ + g_sprintf(post_str, "%c%c%c%c%c%c%c%c%c", + 0xE2, 0x80, 0xAC, /* PDF */ + 0xE2, 0x80, 0x8E, /* LRM */ + 0xE2, 0x80, 0xAC); /* PDF */ + } + else + { + g_sprintf(pre_str, "%c%c%c", + 0xE2, 0x80, 0xAA); /* LRE */ + g_sprintf(post_str, "%c%c%c%c%c%c%c%c%c", + 0xE2, 0x80, 0xAC, /* PDF */ + 0xE2, 0x80, 0x8F, /* RLM */ + 0xE2, 0x80, 0xAC); /* PDF */ + } + + g_sprintf(ret, "%s%s%s", pre_str, *str, post_str); + + g_free(*str); + *str = ret; + return; +} + +/* Returns true if the given HTML contains RTL text */ +static gboolean +html_is_rtl(const char *html) +{ + GData *attributes; + const gchar *start, *end; + gboolean res = FALSE; + + if(purple_markup_find_tag("span", html, &start, &end, &attributes)) + { + /* tmp is a member of attributes and is free with g_datalist_clear call */ + const char *tmp = g_datalist_get_data(&attributes, "dir"); + if(tmp && !g_ascii_strcasecmp(tmp, "RTL")) + res = TRUE; + if(!res) + { + char *tmp2 = NULL; + tmp = g_datalist_get_data(&attributes, "style"); + if(tmp) + tmp2 = purple_markup_get_css_property(tmp, "direction"); + if(tmp2 && !g_ascii_strcasecmp(tmp2, "RTL")) + res = TRUE; + if(tmp2) + g_free(tmp2); + + } + g_datalist_clear(&attributes); + } + return res; +} + + static void pidgin_conv_write_conv(PurpleConversation *conv, const char *name, const char *alias, const char *message, PurpleMessageFlags flags, @@ -4922,6 +4989,7 @@ gboolean plugin_return; char *bracket; int tag_count = 0; + gboolean is_rtl_message = FALSE; g_return_if_fail(conv != NULL); gtkconv = PIDGIN_CONVERSATION(conv); @@ -5034,11 +5102,19 @@ if (mdate == NULL) { struct tm *tm = localtime(&mtime); + const char *tmp; if (show_date) - mdate = g_strdup(purple_date_format_long(tm)); + tmp = purple_date_format_long(tm); else - mdate = g_strdup(purple_time_format(tm)); - } + tmp = purple_time_format(tm); + mdate = g_strdup_printf("(%s)", tmp); + } + + /* Bi-Directional support - set timestamp direction using unicode characters */ + is_rtl_message = html_is_rtl(message); + /* Enforce direction only if message is RTL - donesn't effect LTR users */ + if(is_rtl_message) + str_embed_direction_chars(&mdate); if (mtime >= gtkconv->newday) pidgin_conv_calculate_newday(gtkconv, mtime); @@ -5063,14 +5139,14 @@ gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), message, gtk_font_options_all); } else if (flags & PURPLE_MESSAGE_SYSTEM) { g_snprintf(buf2, sizeof(buf2), - "<FONT %s><FONT SIZE=\"2\"><!--(%s) --></FONT><B>%s</B></FONT>", + "<FONT %s><FONT SIZE=\"2\"><!--%s --></FONT><B>%s</B></FONT>", sml_attrib ? sml_attrib : "", mdate, displaying); gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), buf2, gtk_font_options_all); } else if (flags & PURPLE_MESSAGE_ERROR) { g_snprintf(buf2, sizeof(buf2), - "<FONT COLOR=\"#ff0000\"><FONT %s><FONT SIZE=\"2\"><!--(%s) --></FONT><B>%s</B></FONT></FONT>", + "<FONT COLOR=\"#ff0000\"><FONT %s><FONT SIZE=\"2\"><!--%s --></FONT><B>%s</B></FONT></FONT>", sml_attrib ? sml_attrib : "", mdate, displaying); gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), buf2, gtk_font_options_all); @@ -5091,6 +5167,10 @@ GtkSmileyTree *tree = NULL; GHashTable *smiley_data = NULL; + /* Enforce direction on alias */ + if(is_rtl_message) + str_embed_direction_chars(&alias_escaped); + if (flags & PURPLE_MESSAGE_SEND) { /* Temporarily revert to the original smiley-data to avoid showing up @@ -5178,12 +5258,12 @@ flags & PURPLE_MESSAGE_NICK || purple_find_buddy(account, name) != NULL) { g_snprintf(buf2, BUF_LONG, - "<FONT COLOR=\"%s\" %s><FONT SIZE=\"2\"><!--(%s) --></FONT>" + "<FONT COLOR=\"%s\" %s><FONT SIZE=\"2\"><!--%s --></FONT>" "<B>%s</B></FONT> ", color, sml_attrib ? sml_attrib : "", mdate, str); } else { g_snprintf(buf2, BUF_LONG, - "<FONT COLOR=\"%s\" %s><FONT SIZE=\"2\"><!--(%s) --></FONT>" + "<FONT COLOR=\"%s\" %s><FONT SIZE=\"2\"><!--%s --></FONT>" "%s</FONT> ", color, sml_attrib ? sml_attrib : "", mdate, str); @@ -5191,7 +5271,7 @@ } else { /* Bold everyone's name to make the name stand out from the message. */ g_snprintf(buf2, BUF_LONG, - "<FONT COLOR=\"%s\" %s><FONT SIZE=\"2\"><!--(%s) --></FONT>" + "<FONT COLOR=\"%s\" %s><FONT SIZE=\"2\"><!--%s --></FONT>" "<B>%s</B></FONT> ", color, sml_attrib ? sml_attrib : "", mdate, str); }