# HG changeset patch # User Sadrul Habib Chowdhury # Date 1225318010 0 # Node ID 6c6edb71035d13c5331f6affda50605f81d3fc7e # Parent b6dc71133eb85f120efbd5e98332a1267aa1479a# Parent 1335376ba33fa267afefde6b24b9f4b82d1a13d6 merge of '37145f1b4ec49b432ea571f96562d44f4c5a908e' and '61ca2fe9d6a8984b52d59c8692a78c71a00fb443' diff -r b6dc71133eb8 -r 6c6edb71035d pidgin/gtkconv.c --- a/pidgin/gtkconv.c Wed Oct 29 19:20:03 2008 +0000 +++ b/pidgin/gtkconv.c Wed Oct 29 22:06:50 2008 +0000 @@ -161,7 +161,7 @@ gboolean pidgin_conv_has_focus(PurpleConversation *conv); 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 GtkTextTag *get_buddy_tag(PurpleConversation *conv, const char *who, PurpleMessageFlags flag, 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); @@ -172,7 +172,8 @@ int width, int height); static gboolean pidgin_conv_xy_to_right_infopane(PidginWindow *win, int x, int y); -static const GdkColor *get_nick_color(PidginConversation *gtkconv, const char *name) { +static const GdkColor *get_nick_color(PidginConversation *gtkconv, const char *name) +{ static GdkColor col; GtkStyle *style = gtk_widget_get_style(gtkconv->imhtml); float scale; @@ -1910,6 +1911,40 @@ } static gboolean +gtkconv_cycle_focus(PidginConversation *gtkconv, GtkDirectionType dir) +{ + PurpleConversation *conv = gtkconv->active_conv; + gboolean chat = purple_conversation_get_type(conv) == PURPLE_CONV_TYPE_CHAT; + GtkWidget *next = NULL; + struct { + GtkWidget *from; + GtkWidget *to; + } transitions[] = { + {gtkconv->entry, gtkconv->imhtml}, + {gtkconv->imhtml, chat ? gtkconv->u.chat->list : gtkconv->entry}, + {chat ? gtkconv->u.chat->list : NULL, gtkconv->entry}, + {NULL, NULL} + }, *ptr; + + for (ptr = transitions; !next && ptr->from; ptr++) { + GtkWidget *from, *to; + if (dir == GTK_DIR_TAB_FORWARD) { + from = ptr->from; + to = ptr->to; + } else { + from = ptr->to; + to = ptr->from; + } + if (gtk_widget_is_focus(from)) + next = to; + } + + if (next) + gtk_widget_grab_focus(next); + return !!next; +} + +static gboolean conv_keypress_common(PidginConversation *gtkconv, GdkEventKey *event) { PidginWindow *win; @@ -1970,7 +2005,10 @@ #endif return TRUE; break; - + case GDK_F6: + if (gtkconv_cycle_focus(gtkconv, event->state & GDK_SHIFT_MASK ? GTK_DIR_TAB_BACKWARD : GTK_DIR_TAB_FORWARD)) + return TRUE; + break; } /* End of switch */ } @@ -1997,6 +2035,10 @@ return TRUE; } break; + case GDK_F6: + if (gtkconv_cycle_focus(gtkconv, event->state & GDK_SHIFT_MASK ? GTK_DIR_TAB_BACKWARD : GTK_DIR_TAB_FORWARD)) + return TRUE; + break; } } return FALSE; @@ -4423,7 +4465,7 @@ 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? */ + texttag = get_buddy_tag(conv, purple_buddy_get_name(buddy), 0, FALSE); /* XXX: do we want the normalized name? */ if (texttag) { g_object_set(texttag, "weight", is_buddy ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL, NULL); } @@ -5343,16 +5385,35 @@ purple_conversation_write(conv, who, message, flags, mtime); } +static const char * +get_text_tag_color(GtkTextTag *tag) +{ + GdkColor *color = NULL; + gboolean set = FALSE; + static char colcode[] = "#XXXXXX"; + if (tag) + g_object_get(G_OBJECT(tag), "foreground-set", &set, "foreground-gdk", &color, NULL); + if (set && color) + g_snprintf(colcode, sizeof(colcode), "#%02x%02x%02x", + color->red >> 8, color->green >> 8, color->blue >> 8); + else + colcode[0] = '\0'; + if (color) + gdk_color_free(color); + return colcode; +} + /* The callback for an event on a link tag. */ static gboolean buddytag_event(GtkTextTag *tag, GObject *imhtml, - GdkEvent *event, GtkTextIter *arg2, gpointer data) { + GdkEvent *event, GtkTextIter *arg2, gpointer data) +{ if (event->type == GDK_BUTTON_PRESS || event->type == GDK_2BUTTON_PRESS) { GdkEventButton *btn_event = (GdkEventButton*) event; PurpleConversation *conv = data; char *buddyname; - /* strlen("BUDDY ") == 6 */ + /* strlen("BUDDY " or "HILIT ") == 6 */ g_return_val_if_fail((tag->name != NULL) && (strlen(tag->name) > 6), FALSE); @@ -5392,24 +5453,33 @@ return FALSE; } -static GtkTextTag *get_buddy_tag(PurpleConversation *conv, const char *who, gboolean create) +static GtkTextTag *get_buddy_tag(PurpleConversation *conv, const char *who, PurpleMessageFlags flag, + gboolean create) { PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv); GtkTextTag *buddytag; gchar *str; - - str = g_strdup_printf("BUDDY %s", who); + gboolean highlight = (flag & PURPLE_MESSAGE_NICK); + GtkTextBuffer *buffer = GTK_IMHTML(gtkconv->imhtml)->text_buffer; + + str = g_strdup_printf(highlight ? "HILIT %s" : "BUDDY %s", who); buddytag = gtk_text_tag_table_lookup( - gtk_text_buffer_get_tag_table( - GTK_IMHTML(gtkconv->imhtml)->text_buffer), str); + gtk_text_buffer_get_tag_table(buffer), str); if (buddytag == NULL && create) { - buddytag = gtk_text_buffer_create_tag( - 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); + if (highlight) + buddytag = gtk_text_buffer_create_tag(buffer, str, + "foreground", get_text_tag_color(gtk_text_tag_table_lookup( + gtk_text_buffer_get_tag_table(buffer), "highlight-name")), + "weight", PANGO_WEIGHT_BOLD, + NULL); + else + buddytag = gtk_text_buffer_create_tag( + 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); @@ -5766,7 +5836,9 @@ } if (flags & PURPLE_MESSAGE_NICK) { - tagname = "highlight-name"; + if (type == PURPLE_CONV_TYPE_IM) { + tagname = "highlight-name"; + } } else if (flags & PURPLE_MESSAGE_RECV) { /* The tagname for chats is handled by get_buddy_tag */ if (type == PURPLE_CONV_TYPE_IM) { @@ -5785,7 +5857,7 @@ if (tagname) tag = gtk_text_tag_table_lookup(gtk_text_buffer_get_tag_table(buffer), tagname); else - tag = get_buddy_tag(conv, name, TRUE); + tag = get_buddy_tag(conv, name, flags, TRUE); if (GTK_IMHTML(gtkconv->imhtml)->show_comments) { /* The color for the timestamp has to be set in the font-tags, unfortunately. @@ -5793,19 +5865,10 @@ * bold. I thought applying the "comment" tag again, which has "weight" set * to PANGO_WEIGHT_NORMAL, would remove the boldness. But it doesn't. So * this will have to do. I don't terribly like it. -- sadrul */ - GdkColor *color = NULL; - gboolean set = FALSE; - char colcode[] = "COLOR=\"#XXXXXX\""; - g_object_get(G_OBJECT(tag), "foreground-set", &set, "foreground-gdk", &color, NULL); - if (set && color) - g_snprintf(colcode, sizeof(colcode), "COLOR=\"#%02x%02x%02x\"", - color->red >> 8, color->green >> 8, color->blue >> 8); - else - colcode[0] = '\0'; - g_snprintf(buf2, BUF_LONG, "", colcode, mdate); + const char *color = get_text_tag_color(tag); + g_snprintf(buf2, BUF_LONG, "", + color ? "COLOR=\"" : "", color ? color : "", color ? "\"" : "", mdate); gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), buf2, gtk_font_options_all | GTK_IMHTML_NO_SCROLL); - if (color) - gdk_color_free(color); } gtk_text_buffer_get_end_iter(buffer, &end);