Mercurial > pidgin.yaz
diff pidgin/gtkconv.c @ 23005:f11fc3fb5b8c
Use text-tags to set the weight/color of the nick in conversations. This
simplifies pidgin_conv_write_conv a bit, I think. This also has the added
benefit that the colors in an existing conversation are changed to the
new color retroactively when the colors are changed using the
theme-control plugin.
author | Sadrul Habib Chowdhury <imadil@gmail.com> |
---|---|
date | Mon, 19 May 2008 18:23:25 +0000 |
parents | 396fd93907f1 |
children | 3c78771b520a |
line wrap: on
line diff
--- a/pidgin/gtkconv.c Sun May 18 21:22:38 2008 +0000 +++ b/pidgin/gtkconv.c Mon May 19 18:23:25 2008 +0000 @@ -96,10 +96,10 @@ #define PIDGIN_CONV_ALL ((1 << 7) - 1) +/* XXX: These color defines shouldn't really be here. But the nick-color + * generation algorithm uses them, so keeping these around until we fix that. */ #define DEFAULT_SEND_COLOR "#204a87" -#define DEFAULT_RECV_COLOR "#cc0000" #define DEFAULT_HIGHLIGHT_COLOR "#AF7F00" -#define DEFAULT_ACTION_COLOR "#062585" #define BUDDYICON_SIZE_MIN 32 #define BUDDYICON_SIZE_MAX 96 @@ -163,6 +163,7 @@ static void pidgin_conv_custom_smiley_closed(GdkPixbufLoader *loader, gpointer user_data); static GdkColor* generate_nick_colors(guint *numcolors, GdkColor background); static gboolean color_is_visible(GdkColor foreground, GdkColor background, int color_contrast, int brightness_contrast); +static GtkTextTag *get_buddy_tag(PurpleConversation *conv, const char *who, gboolean create); static void pidgin_conv_update_fields(PurpleConversation *conv, PidginConvFields fields); static void focus_out_from_menubar(GtkWidget *wid, PidginWindow *win); static void pidgin_conv_tab_pack(PidginWindow *win, PidginConversation *gtkconv); @@ -3875,6 +3876,7 @@ gboolean is_buddy; gchar *tmp, *alias_key, *name, *alias; int flags; + GdkColor *color = NULL; alias = cb->alias; name = cb->name; @@ -3901,71 +3903,50 @@ alias_key = g_utf8_collate_key(tmp, -1); g_free(tmp); - if (is_me) - { - GdkColor send_color; - gdk_color_parse(DEFAULT_SEND_COLOR, &send_color); + if (is_me) { + GtkTextTag *tag = gtk_text_tag_table_lookup( + gtk_text_buffer_get_tag_table(GTK_IMHTML(gtkconv->imhtml)->text_buffer), + "send-name"); + g_object_get(tag, "foreground-gdk", &color, NULL); + } else { + color = (GdkColor*)get_nick_color(gtkconv, name); + } #if GTK_CHECK_VERSION(2,6,0) - gtk_list_store_insert_with_values(ls, &iter, + gtk_list_store_insert_with_values(ls, &iter, /* - * The GTK docs are mute about the effects of the "row" value for performance. - * X-Chat hardcodes their value to 0 (prepend) and -1 (append), so we will too. - * It *might* be faster to search the gtk_list_store and set row accurately, - * but no one in #gtk+ seems to know anything about it either. - * Inserting in the "wrong" location has no visible ill effects. - F.P. - */ - -1, /* "row" */ - CHAT_USERS_ICON_COLUMN, pixbuf, - CHAT_USERS_ALIAS_COLUMN, alias, - CHAT_USERS_ALIAS_KEY_COLUMN, alias_key, - CHAT_USERS_NAME_COLUMN, name, - CHAT_USERS_FLAGS_COLUMN, flags, - CHAT_USERS_COLOR_COLUMN, &send_color, - CHAT_USERS_WEIGHT_COLUMN, is_buddy ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL, - -1); - } - else - { - gtk_list_store_insert_with_values(ls, &iter, - -1, /* "row" */ - CHAT_USERS_ICON_COLUMN, pixbuf, - CHAT_USERS_ALIAS_COLUMN, alias, - CHAT_USERS_ALIAS_KEY_COLUMN, alias_key, - CHAT_USERS_NAME_COLUMN, name, - CHAT_USERS_FLAGS_COLUMN, flags, - CHAT_USERS_COLOR_COLUMN, get_nick_color(gtkconv, name), - CHAT_USERS_WEIGHT_COLUMN, is_buddy ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL, - -1); +* The GTK docs are mute about the effects of the "row" value for performance. +* X-Chat hardcodes their value to 0 (prepend) and -1 (append), so we will too. +* It *might* be faster to search the gtk_list_store and set row accurately, +* but no one in #gtk+ seems to know anything about it either. +* Inserting in the "wrong" location has no visible ill effects. - F.P. +*/ + -1, /* "row" */ + CHAT_USERS_ICON_COLUMN, pixbuf, + CHAT_USERS_ALIAS_COLUMN, alias, + CHAT_USERS_ALIAS_KEY_COLUMN, alias_key, + CHAT_USERS_NAME_COLUMN, name, + CHAT_USERS_FLAGS_COLUMN, flags, + CHAT_USERS_COLOR_COLUMN, color, + CHAT_USERS_WEIGHT_COLUMN, is_buddy ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL, + -1); #else - gtk_list_store_append(ls, &iter); - gtk_list_store_set(ls, &iter, - CHAT_USERS_ICON_COLUMN, pixbuf, - CHAT_USERS_ALIAS_COLUMN, alias, - CHAT_USERS_ALIAS_KEY_COLUMN, alias_key, - CHAT_USERS_NAME_COLUMN, name, - CHAT_USERS_FLAGS_COLUMN, flags, - CHAT_USERS_COLOR_COLUMN, &send_color, - CHAT_USERS_WEIGHT_COLUMN, is_buddy ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL, - -1); - } - else - { - gtk_list_store_append(ls, &iter); - gtk_list_store_set(ls, &iter, - CHAT_USERS_ICON_COLUMN, pixbuf, - CHAT_USERS_ALIAS_COLUMN, alias, - CHAT_USERS_ALIAS_KEY_COLUMN, alias_key, - CHAT_USERS_NAME_COLUMN, name, - CHAT_USERS_FLAGS_COLUMN, flags, - CHAT_USERS_COLOR_COLUMN, get_nick_color(gtkconv, name), - CHAT_USERS_WEIGHT_COLUMN, is_buddy ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL, - -1); + gtk_list_store_append(ls, &iter); + gtk_list_store_set(ls, &iter, + CHAT_USERS_ICON_COLUMN, pixbuf, + CHAT_USERS_ALIAS_COLUMN, alias, + CHAT_USERS_ALIAS_KEY_COLUMN, alias_key, + CHAT_USERS_NAME_COLUMN, name, + CHAT_USERS_FLAGS_COLUMN, flags, + CHAT_USERS_COLOR_COLUMN, color, + CHAT_USERS_WEIGHT_COLUMN, is_buddy ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL, + -1); #endif - } if (pixbuf) g_object_unref(pixbuf); + if (is_me && color) + gdk_color_free(color); g_free(alias_key); } @@ -4359,6 +4340,7 @@ GtkTreeModel *model; char *normalized_name; GtkTreeIter iter; + GtkTextTag *texttag; int f; g_return_if_fail(buddy != NULL); @@ -4396,6 +4378,11 @@ g_free(normalized_name); blist_node_aliased_cb((PurpleBlistNode *)buddy, NULL, conv); + + texttag = get_buddy_tag(conv, purple_buddy_get_name(buddy), FALSE); /* XXX: do we want the normalized name? */ + if (texttag) { + g_object_set(texttag, "weight", is_buddy ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL, NULL); + } } static void @@ -5356,7 +5343,8 @@ return FALSE; } -static GtkTextTag *get_buddy_tag(PurpleConversation *conv, const char *who) { +static GtkTextTag *get_buddy_tag(PurpleConversation *conv, const char *who, gboolean create) +{ PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv); GtkTextTag *buddytag; gchar *str; @@ -5367,9 +5355,12 @@ gtk_text_buffer_get_tag_table( GTK_IMHTML(gtkconv->imhtml)->text_buffer), str); - if (buddytag == NULL) { + if (buddytag == NULL && create) { buddytag = gtk_text_buffer_create_tag( - GTK_IMHTML(gtkconv->imhtml)->text_buffer, str, NULL); + GTK_IMHTML(gtkconv->imhtml)->text_buffer, str, + "foreground-gdk", get_nick_color(gtkconv, who), + "weight", purple_find_buddy(purple_conversation_get_account(conv), who) ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL, + NULL); g_signal_connect(G_OBJECT(buddytag), "event", G_CALLBACK(buddytag_event), conv); @@ -5475,7 +5466,6 @@ char buf2[BUF_LONG]; gboolean show_date; char *mdate; - char color[10]; char *str; char *with_font_tag; char *sml_attrib = NULL; @@ -5686,32 +5676,28 @@ * escaped entities making the string longer */ int tag_start_offset = alias ? (strlen(alias_escaped) - strlen(alias)) : 0; int tag_end_offset = 0; + const char *tagname = NULL; /* Enforce direction on alias */ if (is_rtl_message) str_embed_direction_chars(&alias_escaped); + str = g_malloc(1024); if (flags & PURPLE_MESSAGE_WHISPER) { - str = g_malloc(1024); - /* If we're whispering, it's not an autoresponse. */ if (purple_message_meify(new_message, -1 )) { g_snprintf(str, 1024, "***%s", alias_escaped); - strcpy(color, "#6C2585"); tag_start_offset += 3; + tagname = "whisper-action-name"; } else { g_snprintf(str, 1024, "*%s*:", alias_escaped); tag_start_offset += 1; tag_end_offset = 2; - strcpy(color, "#00FF00"); + tagname = "whisper-name"; } - } - else { + } else { if (purple_message_meify(new_message, -1)) { - GdkColor *col; - str = g_malloc(1024); - if (flags & PURPLE_MESSAGE_AUTO_RESP) { g_snprintf(str, 1024, "%s ***%s", AUTO_RESPONSE, alias_escaped); tag_start_offset += 4 @@ -5722,23 +5708,10 @@ } if (flags & PURPLE_MESSAGE_NICK) - gtk_widget_style_get(GTK_WIDGET(gtkconv->imhtml), "highlight-name-color", &col, NULL); + tagname = "highlight-name"; else - gtk_widget_style_get(GTK_WIDGET(gtkconv->imhtml), "action-name-color", &col, NULL); - - if(col) { - g_snprintf(color, sizeof(color), "#%02X%02X%02X", - col->red >> 8, col->green >> 8, col->blue >> 8); - gdk_color_free(col); - } else { - if (flags & PURPLE_MESSAGE_NICK) - strcpy(color, DEFAULT_HIGHLIGHT_COLOR); - else - strcpy(color, DEFAULT_ACTION_COLOR); - } - } - else { - str = g_malloc(1024); + tagname = "action-name"; + } else { if (flags & PURPLE_MESSAGE_AUTO_RESP) { g_snprintf(str, 1024, "%s %s", alias_escaped, AUTO_RESPONSE); tag_start_offset += 1 @@ -5747,105 +5720,48 @@ g_snprintf(str, 1024, "%s:", alias_escaped); tag_end_offset = 1; } + if (flags & PURPLE_MESSAGE_NICK) { - GdkColor *col; - gtk_widget_style_get(GTK_WIDGET(gtkconv->imhtml), "highlight-name-color", &col, NULL); - if(col) { - g_snprintf(color, sizeof(color), "#%02X%02X%02X", - col->red >> 8, col->green >> 8, col->blue >> 8); - gdk_color_free(col); - } else { - strcpy(color, DEFAULT_HIGHLIGHT_COLOR); + tagname = "highlight-name"; + } else if (flags & PURPLE_MESSAGE_RECV) { + /* The tagname and color is handled by get_buddy_tag */ + if (type == PURPLE_CONV_TYPE_IM) { + tagname = "receive-name"; } - } - else if (flags & PURPLE_MESSAGE_RECV) { - if (type == PURPLE_CONV_TYPE_CHAT) { - const GdkColor *col = get_nick_color(gtkconv, name); - - g_snprintf(color, sizeof(color), "#%02X%02X%02X", - col->red >> 8, col->green >> 8, col->blue >> 8); - } else { - GdkColor *col; - gtk_widget_style_get(GTK_WIDGET(gtkconv->imhtml), "receive-name-color", &col, NULL); - if(col) { - g_snprintf(color, sizeof(color), "#%02X%02X%02X", - col->red >> 8, col->green >> 8, col->blue >> 8); - gdk_color_free(col); - } else { - strcpy(color, DEFAULT_RECV_COLOR); - } - } - } - else if (flags & PURPLE_MESSAGE_SEND) { - GdkColor *col; - gtk_widget_style_get(GTK_WIDGET(gtkconv->imhtml), "send-name-color", &col, NULL); - if(col) { - g_snprintf(color, sizeof(color), "#%02X%02X%02X", - col->red >> 8, col->green >> 8, col->blue >> 8); - gdk_color_free(col); - } else { - strcpy(color, DEFAULT_SEND_COLOR); - } - } - else { + } else if (flags & PURPLE_MESSAGE_SEND) { + tagname = "send-name"; + } else { purple_debug_error("gtkconv", "message missing flags\n"); - strcpy(color, "#000000"); } } } g_free(alias_escaped); - /* Are we in a chat where we can tell which users are buddies? */ - if (prpl_info && !(prpl_info->options & OPT_PROTO_UNIQUE_CHATNAME) && - purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT) { - - /* Bold buddies to make them stand out from non-buddies. */ - if (flags & PURPLE_MESSAGE_SEND || - flags & PURPLE_MESSAGE_NICK || - purple_find_buddy(account, name) != NULL) { - g_snprintf(buf2, BUF_LONG, - "<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>" - "%s</FONT> ", - color, sml_attrib ? sml_attrib : "", mdate, str); - - } - } 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>" - "<B>%s</B></FONT> ", - color, sml_attrib ? sml_attrib : "", mdate, str); - } - + g_snprintf(buf2, BUF_LONG, + "<FONT %s><FONT SIZE=\"2\"><!--%s --></FONT>%s</FONT> ", + sml_attrib ? sml_attrib : "", mdate, str); gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), buf2, gtk_font_options_all | GTK_IMHTML_NO_SCROLL); - if (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT && - !(flags & PURPLE_MESSAGE_SEND)) { - + if (tagname || + (purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT && + !(flags & PURPLE_MESSAGE_SEND))) { GtkTextIter start, end; - GtkTextTag *buddytag = get_buddy_tag(conv, name); - - gtk_text_buffer_get_end_iter( - GTK_IMHTML(gtkconv->imhtml)->text_buffer, - &end); - gtk_text_iter_backward_chars(&end, - tag_end_offset + 1); - - gtk_text_buffer_get_end_iter( - GTK_IMHTML(gtkconv->imhtml)->text_buffer, - &start); - gtk_text_iter_backward_chars(&start, - strlen(str) + 1 - tag_start_offset); - - gtk_text_buffer_apply_tag( - GTK_IMHTML(gtkconv->imhtml)->text_buffer, - buddytag, &start, &end); + GtkTextTag *tag; + GtkTextBuffer *buffer = GTK_IMHTML(gtkconv->imhtml)->text_buffer; + + if (tagname) + tag = gtk_text_tag_table_lookup(gtk_text_buffer_get_tag_table(buffer), tagname); + else + tag = get_buddy_tag(conv, name, TRUE); + + gtk_text_buffer_get_end_iter(buffer, &end); + gtk_text_iter_backward_chars(&end, tag_end_offset + 1); + + gtk_text_buffer_get_end_iter(buffer, &start); + gtk_text_iter_backward_chars(&start, strlen(str) + 1 - tag_start_offset); + + gtk_text_buffer_apply_tag(buffer, tag, &start, &end); } g_free(str); @@ -5864,8 +5780,7 @@ length += pre_len + post_len; g_free(pre); - } - else + } else with_font_tag = g_memdup(new_message, length); gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml),