# HG changeset patch # User Richard Laager # Date 1137652209 0 # Node ID 7f633dd625a9eab3c9c8859136f0d51726cec418 # Parent 56129c18aa2bc4cb41d13b62b78061ead4fbd2d8 [gaim-migrate @ 15292] SF Patch # from Levi Bard with changes by Sadrul Levi says: " This patch adds anchors to the conversation history so that you can scroll up to the last thing a person said by middle-clicking his nick in the chatter list." Sadrul added a right-click menu item. I modified the text marks to be of the form user:SCREENNAME to make sure we don't end up with any conflicts with other text marks. committer: Tailor Script diff -r 56129c18aa2b -r 7f633dd625a9 ChangeLog --- a/ChangeLog Thu Jan 19 05:54:11 2006 +0000 +++ b/ChangeLog Thu Jan 19 06:30:09 2006 +0000 @@ -45,11 +45,13 @@ * Added tab management options to the tab right-click menu (Sadrul Habib Chowdhury) * Brand new message queueing system (Casey Harkins) + * Ability to find the last message from a user in a chat (Levi Bard + and Sadrul Habib Chowdhury) Sounds: * Beautiful new default sounds (Brad Turcotte) * Use libao for playing sounds via NAS instead of accessing NAS directly - * A volume control in the preferences + * A volume control in the preferences (Casey Harkins) Log Viewer: * Log viewer aggregates logs from the same "Person" diff -r 56129c18aa2b -r 7f633dd625a9 src/gtkconv.c --- a/src/gtkconv.c Thu Jan 19 05:54:11 2006 +0000 +++ b/src/gtkconv.c Thu Jan 19 06:30:09 2006 +0000 @@ -1526,6 +1526,32 @@ gtk_widget_grab_focus(GAIM_GTK_CONVERSATION(conv)->entry); } +static GtkTextMark * +get_mark_for_user(GaimGtkConversation *gtkconv, const char *who) +{ + GtkTextBuffer *buf = gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtkconv->imhtml)); + char *tmp = g_strconcat("user:", who, NULL); + GtkTextMark *mark = gtk_text_buffer_get_mark(buf, tmp); + + g_free(tmp); + return mark; +} + +static void +menu_last_said_cb(GtkWidget *w, GaimGtkConversation *gtkconv) +{ + GtkTextMark *mark; + const char *who; + + who = g_object_get_data(G_OBJECT(w), "user_data"); + mark = get_mark_for_user(gtkconv, who); + + if (mark != NULL) + gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW(gtkconv->imhtml), mark, 0.1, FALSE, 0, 0); + else + g_return_if_reached(); +} + static GtkWidget * create_chat_menu(GaimConversation *conv, const char *who, GaimPluginProtocolInfo *prpl_info, GaimConnection *gc) @@ -1591,6 +1617,12 @@ g_object_set_data_full(G_OBJECT(button), "user_data", g_strdup(who), g_free); } + button = gaim_new_item_from_stock(menu, _("Last said"), GTK_STOCK_INDEX, + G_CALLBACK(menu_last_said_cb), GAIM_GTK_CONVERSATION(conv), 0, 0, NULL); + g_object_set_data_full(G_OBJECT(button), "user_data", g_strdup(who), g_free); + if (!get_mark_for_user(GAIM_GTK_CONVERSATION(conv), who)) + gtk_widget_set_sensitive(button, FALSE); + return menu; } @@ -1673,6 +1705,12 @@ if (event->button == 1 && event->type == GDK_2BUTTON_PRESS) { chat_do_im(gtkconv, who); + } else if (event->button == 2 && event->type == GDK_BUTTON_PRESS) { + /* Move to user's anchor */ + GtkTextMark *mark = get_mark_for_user(gtkconv, who); + + if(mark != NULL) + gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW(gtkconv->imhtml), mark, 0.1, FALSE, 0, 0); } else if (event->button == 3 && event->type == GDK_BUTTON_PRESS) { GtkWidget *menu = create_chat_menu (conv, who, prpl_info, gc); gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL, @@ -4622,6 +4660,18 @@ gtk_imhtml_delete(GTK_IMHTML(gtkconv->imhtml), &start, &end); } + if (type == GAIM_CONV_TYPE_CHAT) + { + /* Create anchor for user */ + GtkTextIter iter; + char *tmp = g_strconcat("user:", name, NULL); + + gtk_text_buffer_get_end_iter(gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtkconv->imhtml)), &iter); + gtk_text_buffer_create_mark(gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtkconv->imhtml)), + tmp, &iter, TRUE); + g_free(tmp); + } + if (gtk_text_buffer_get_char_count(gtk_text_view_get_buffer(GTK_TEXT_VIEW(gtkconv->imhtml)))) gtk_imhtml_append_text(GTK_IMHTML(gtkconv->imhtml), "
", gtk_font_options_all);