From: Sean E. <sea...@us...> - 2003-10-18 01:58:08
|
Update of /cvsroot/gaim/gaim/src In directory sc8-pr-cvs1:/tmp/cvs-serv24105/src Modified Files: gtkconv.c gtkconv.h gtkimhtml.c gtkimhtml.h Log Message: I added a search feature to conversations. I actually did most of this a while ago for the log viewer. GtkIMHtml has some functions to handle searching itself. I just added a new item to the conversation menu to handle it. This should be useful for long IRC channel backlogs and the sorts. It's case-sensitive right now. That kinda sucks, but that's all GTK lets me do. GtkSourceView has some nice case-insensitive search functions that I'll likely bring in before the release. Index: gtkconv.c =================================================================== RCS file: /cvsroot/gaim/gaim/src/gtkconv.c,v retrieving revision 1.214 retrieving revision 1.215 diff -u -d -p -r1.214 -r1.215 --- gtkconv.c 14 Oct 2003 05:07:38 -0000 1.214 +++ gtkconv.c 18 Oct 2003 01:58:01 -0000 1.215 @@ -715,6 +715,82 @@ menu_view_log_cb(gpointer data, guint ac conv_show_log(NULL, (char *)gaim_conversation_get_name(conv)); } +struct _search { + GaimGtkConversation *gtkconv; + GtkWidget *entry; +}; + +static void do_search_cb(GtkWidget *widget, gint resp, struct _search *s) +{ + switch (resp) { + case GTK_RESPONSE_OK: + gtk_imhtml_search_find(s->gtkconv->imhtml, gtk_entry_get_text(GTK_ENTRY(s->entry))); + break; + case GTK_RESPONSE_CLOSE: + gtk_imhtml_search_clear(s->gtkconv->imhtml); + gtk_widget_destroy(s->gtkconv->dialogs.search); + s->gtkconv->dialogs.search = NULL; + g_free(s); + break; + } +} + +static void +menu_search_cb(gpointer data, guint action, GtkWidget *widget) +{ + GaimConvWindow *win = (GaimConvWindow *)data; + GaimConversation *conv = gaim_conv_window_get_active_conversation(win); + GaimGtkWindow *gtkwin = GAIM_GTK_WINDOW(win); + GaimGtkConversation *gtkconv = GAIM_GTK_CONVERSATION(conv); + GtkWidget *hbox, *vbox; + GtkWidget *img = gtk_image_new_from_stock(GAIM_STOCK_DIALOG_QUESTION, GTK_ICON_SIZE_DIALOG); + GtkWidget *label, *entry; + struct _search *s; + + if (gtkconv->dialogs.search) + return; + + gtkconv->dialogs.search = gtk_dialog_new_with_buttons("", GTK_WINDOW(gtkwin->window), + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, + GTK_STOCK_FIND, GTK_RESPONSE_OK, NULL); + gtk_container_set_border_width (GTK_CONTAINER(gtkconv->dialogs.search), 6); + gtk_window_set_resizable(GTK_WINDOW(gtkconv->dialogs.search), FALSE); + gtk_dialog_set_has_separator(GTK_DIALOG(gtkconv->dialogs.search), FALSE); + gtk_box_set_spacing(GTK_BOX(GTK_DIALOG(gtkconv->dialogs.search)->vbox), 12); + gtk_container_set_border_width (GTK_CONTAINER(GTK_DIALOG(gtkconv->dialogs.search)->vbox), 6); + + hbox = gtk_hbox_new(FALSE, 6); + gtk_container_add(GTK_CONTAINER(GTK_DIALOG(gtkconv->dialogs.search)->vbox), hbox); + gtk_box_pack_start(GTK_BOX(hbox), img, FALSE, FALSE, 0); + gtk_misc_set_alignment(GTK_MISC(img), 0, 0); + + vbox = gtk_vbox_new(FALSE, 0); + gtk_container_add(GTK_CONTAINER(hbox), vbox); + + label = gtk_label_new(NULL); + gtk_label_set_markup(GTK_LABEL(label), _("<span weight='bold' size='larger'>Enter a search phrase\n</span>")); + gtk_label_set_line_wrap(GTK_LABEL(label), TRUE); + gtk_misc_set_alignment(GTK_MISC(label), 0, 0); + gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); + + hbox = gtk_hbox_new(FALSE, 6); + gtk_container_add(GTK_CONTAINER(vbox), hbox); + label = gtk_label_new(_("Search term: ")); + entry = gtk_entry_new(); + gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); + gtk_box_pack_start(GTK_BOX(hbox), entry, FALSE, FALSE, 0); + + s = g_malloc(sizeof(struct _search)); + s->gtkconv = gtkconv; + s->entry = entry; + + gtk_dialog_set_default_response (GTK_DIALOG(gtkconv->dialogs.search), GTK_RESPONSE_OK); + g_signal_connect(G_OBJECT(gtkconv->dialogs.search), "response", G_CALLBACK(do_search_cb), s); + + gtk_widget_show_all(gtkconv->dialogs.search); +} + static void menu_add_pounce_cb(gpointer data, guint action, GtkWidget *widget) { @@ -2837,7 +2913,8 @@ static GtkItemFactoryEntry menu_items[] { N_("/Conversation/_Save As..."), NULL, menu_save_as_cb, 0, "<StockItem>", GTK_STOCK_SAVE_AS }, - { N_("/Conversation/View _Log..."), NULL, menu_view_log_cb, 0, NULL }, + { N_("/Conversation/View _Log"), NULL, menu_view_log_cb, 0, NULL }, + { N_("/Conversation/Search..."), NULL, menu_search_cb, 0, "<StockItem>", GTK_STOCK_FIND }, { "/Conversation/sep1", NULL, NULL, 0, "<Separator>" }, @@ -2916,7 +2993,7 @@ setup_menubar(GaimConvWindow *win) gtkwin->menu.view_log = gtk_item_factory_get_widget(gtkwin->menu.item_factory, - N_("/Conversation/View Log...")); + N_("/Conversation/View Log")); /* --- */ gtkwin->menu.add_pounce = @@ -4246,6 +4323,9 @@ gaim_gtkconv_destroy(GaimConversation *c if (gtkconv->dialogs.log != NULL) gtk_widget_destroy(gtkconv->dialogs.log); + + if (gtkconv->dialogs.search != NULL) + gtk_widget_destroy(gtkconv->dialogs.search); gtk_widget_destroy(gtkconv->tab_cont); g_object_unref(gtkconv->tab_cont); Index: gtkconv.h =================================================================== RCS file: /cvsroot/gaim/gaim/src/gtkconv.h,v retrieving revision 1.23 retrieving revision 1.24 diff -u -d -p -r1.23 -r1.24 --- gtkconv.h 2 Oct 2003 02:54:02 -0000 1.23 +++ gtkconv.h 18 Oct 2003 01:58:01 -0000 1.24 @@ -185,6 +185,7 @@ struct _GaimGtkConversation GtkWidget *link; GtkWidget *image; GtkWidget *log; + GtkWidget *search; } dialogs; Index: gtkimhtml.c =================================================================== RCS file: /cvsroot/gaim/gaim/src/gtkimhtml.c,v retrieving revision 1.203 retrieving revision 1.204 diff -u -d -p -r1.203 -r1.204 --- gtkimhtml.c 17 Oct 2003 05:58:16 -0000 1.203 +++ gtkimhtml.c 18 Oct 2003 01:58:01 -0000 1.204 @@ -409,7 +409,8 @@ static void gtk_imhtml_init (GtkIMHtml * gtk_text_buffer_create_tag(imhtml->text_buffer, "SUB", "rise", -5000, NULL); gtk_text_buffer_create_tag(imhtml->text_buffer, "SUP", "rise", 5000, NULL); gtk_text_buffer_create_tag(imhtml->text_buffer, "PRE", "family", "Monospace", NULL); - + gtk_text_buffer_create_tag(imhtml->text_buffer, "search", "background", "#22ff00", "weight", "bold", NULL); + /* When hovering over a link, we show the hand cursor--elsewhere we show the plain ol' pointer cursor */ imhtml->hand_cursor = gdk_cursor_new (GDK_HAND2); imhtml->arrow_cursor = gdk_cursor_new (GDK_LEFT_PTR); @@ -1763,4 +1764,58 @@ void gtk_imhtml_hr_add_to(GtkIMHtmlScala void gtk_imhtml_hr_free(GtkIMHtmlScalable *scale) { g_free(scale); +} + +gboolean gtk_imhtml_search_find(GtkIMHtml *imhtml, const gchar *text) +{ + GtkTextIter iter, start, end; + gboolean new_search = TRUE; + + g_return_val_if_fail(imhtml != NULL, FALSE); + g_return_val_if_fail(text != NULL, FALSE); + + if (imhtml->search_string && !strcmp(text, imhtml->search_string)) + new_search = FALSE; + + + if (new_search) { + gtk_imhtml_search_clear(imhtml); + gtk_text_buffer_get_start_iter(imhtml->text_buffer, &iter); + } else { + gtk_text_buffer_get_iter_at_mark(imhtml->text_buffer, &iter, + gtk_text_buffer_get_mark(imhtml->text_buffer, "search")); + } + imhtml->search_string = g_strdup(text); + + if (gtk_text_iter_forward_search(&iter, imhtml->search_string, + GTK_TEXT_SEARCH_VISIBLE_ONLY, + &start, &end, NULL)) { + + gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(imhtml), &start, 0, TRUE, 0, 0); + gtk_text_buffer_create_mark(imhtml->text_buffer, "search", &end, FALSE); + if (new_search) { + gtk_text_buffer_remove_tag_by_name(imhtml->text_buffer, "search", &iter, &end); + do + gtk_text_buffer_apply_tag_by_name(imhtml->text_buffer, "search", &start, &end); + while (gtk_text_iter_forward_search(&end, imhtml->search_string, GTK_TEXT_SEARCH_VISIBLE_ONLY, + &start, &end, NULL)); + } + return TRUE; + } + return FALSE; +} + +void gtk_imhtml_search_clear(GtkIMHtml *imhtml) +{ + GtkTextIter start, end; + + g_return_if_fail(imhtml != NULL); + + gtk_text_buffer_get_start_iter(imhtml->text_buffer, &start); + gtk_text_buffer_get_end_iter(imhtml->text_buffer, &end); + + gtk_text_buffer_remove_tag_by_name(imhtml->text_buffer, "search", &start, &end); + if (imhtml->search_string) + g_free(imhtml->search_string); + imhtml->search_string = NULL; } Index: gtkimhtml.h =================================================================== RCS file: /cvsroot/gaim/gaim/src/gtkimhtml.h,v retrieving revision 1.45 retrieving revision 1.46 diff -u -d -p -r1.45 -r1.46 --- gtkimhtml.h 27 Sep 2003 19:17:18 -0000 1.45 +++ gtkimhtml.h 18 Oct 2003 01:58:02 -0000 1.46 @@ -66,6 +66,8 @@ struct _GtkIMHtml { GList *scalables; GdkRectangle old_rect; + + gchar *search_string; }; struct _GtkIMHtmlClass { @@ -167,6 +169,9 @@ void gtk_imhtml_hr_free(GtkIMHtmlScalabl void gtk_imhtml_hr_scale(GtkIMHtmlScalable *, int, int); void gtk_imhtml_hr_add_to(GtkIMHtmlScalable *, GtkIMHtml *, GtkTextIter *); +/* Search functions */ +gboolean gtk_imhtml_search_find(GtkIMHtml *imhtml, const gchar *text); +void gtk_imhtml_search_clear(GtkIMHtml *imhtml); #ifdef __cplusplus } |