changeset 24328:6c6edb71035d

merge of '37145f1b4ec49b432ea571f96562d44f4c5a908e' and '61ca2fe9d6a8984b52d59c8692a78c71a00fb443'
author Sadrul Habib Chowdhury <imadil@gmail.com>
date Wed, 29 Oct 2008 22:06:50 +0000
parents b6dc71133eb8 (current diff) 1335376ba33f (diff)
children f498f5a5f501 882a1c4c11b4
files
diffstat 1 files changed, 93 insertions(+), 30 deletions(-) [+]
line wrap: on
line diff
--- 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, "<FONT %s SIZE=\"2\"><!--%s --></FONT>", colcode, mdate);
+			const char *color = get_text_tag_color(tag);
+			g_snprintf(buf2, BUF_LONG, "<FONT %s%s%s SIZE=\"2\"><!--%s --></FONT>",
+					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);