diff options
author | Richard Hult <rhult@codefactory.se> | 2002-10-29 22:57:07 +0000 |
---|---|---|
committer | Richard Hult <rhult@src.gnome.org> | 2002-10-29 22:57:07 +0000 |
commit | 0dba170b30cf911eb0934adcd6c6377a659c8f08 (patch) | |
tree | fd4bebe015e6aa336fbd44b99677745f15dfaca4 | |
parent | 885863b48b6ee9f285b07c73ac1222330afa5a9b (diff) | |
download | yelp-0dba170b30cf911eb0934adcd6c6377a659c8f08.tar.gz |
Implement find backward.
2002-10-29 Richard Hult <rhult@codefactory.se>
* src/yelp-html-gtkhtml2.c (yelp_html_find): Implement find
backward.
* src/yelp-window.c (window_find_again_cb): Implement.
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | src/yelp-html-gtkhtml2.c | 92 | ||||
-rw-r--r-- | src/yelp-html.h | 1 | ||||
-rw-r--r-- | src/yelp-window.c | 116 |
4 files changed, 155 insertions, 58 deletions
@@ -1,8 +1,12 @@ 2002-10-29 Richard Hult <rhult@codefactory.se> + * src/yelp-html-gtkhtml2.c (yelp_html_find): Implement find + backward. + * src/yelp-window.c (window_find_response_cb) (window_find_delete_event_cb, window_find_cb): Use the find dialog. + (window_find_again_cb): Implement. * src/yelp-html-gtkhtml2.c (yelp_html_find): Implement find forward. diff --git a/src/yelp-html-gtkhtml2.c b/src/yelp-html-gtkhtml2.c index 26e01acb..d96c292b 100644 --- a/src/yelp-html-gtkhtml2.c +++ b/src/yelp-html-gtkhtml2.c @@ -397,14 +397,17 @@ html_clear_find_data (YelpHtml *html) } } +/* This code is really ugly, need to clean up. */ void yelp_html_find (YelpHtml *html, const gchar *find_string, gboolean match_case, + gboolean wrap, gboolean forward) { YelpHtmlPriv *priv; DomNode *root; + DomNode *tmp_node; DomNode *node; DomNodeIterator *iter; gchar *str; @@ -418,11 +421,6 @@ yelp_html_find (YelpHtml *html, g_return_if_fail (YELP_IS_HTML (html)); g_return_if_fail (find_string != NULL); - if (!forward) { - /* FIXME: Implement find backwards. */ - return; - } - priv = html->priv; if (!priv->find_iter) { @@ -457,9 +455,24 @@ yelp_html_find (YelpHtml *html, NULL, FALSE, NULL); - - priv->find_node = dom_NodeIterator_nextNode (priv->find_iter, NULL); - priv->find_offset = 0; + + if (forward) { + priv->find_node = dom_NodeIterator_nextNode (priv->find_iter, NULL); + priv->find_offset = 0; + } else { + do { + tmp_node = priv->find_node; + priv->find_node = dom_NodeIterator_nextNode (priv->find_iter, NULL); + } while (priv->find_node); + + priv->find_node = tmp_node; + + if (priv->find_node) { + box = html_view_find_layout_box (priv->view, priv->find_node, FALSE); + box_text = html_box_text_get_text (HTML_BOX_TEXT (box), &len); + priv->find_offset = len; + } + } } while (priv->find_node) { @@ -467,7 +480,7 @@ yelp_html_find (YelpHtml *html, /* We get the text from the layout box instead from the DOM node * directly, since the text in the box is canonicalized - * (whitespace stripped in places etc. + * (whitespace stripped in places etc). */ box_text = html_box_text_get_text (HTML_BOX_TEXT (box), &len); if (len) { @@ -479,42 +492,71 @@ yelp_html_find (YelpHtml *html, } if (!match_case) { - haystack = g_utf8_casefold (str + priv->find_offset, len - priv->find_offset); + if (forward) { + haystack = g_utf8_casefold (str + priv->find_offset, len - priv->find_offset); + } else { + haystack = g_utf8_casefold (str, priv->find_offset); + } } else { - haystack = g_strdup (str + priv->find_offset); + if (forward) { + haystack = g_strdup (str + priv->find_offset); + } else { + haystack = g_strndup (str, priv->find_offset); + } + } + + if (forward) { + hit = strstr (haystack, find_string); + } else { + hit = g_strrstr_len (haystack, + priv->find_offset, + find_string); } - g_free (str); - - hit = strstr (haystack, find_string); if (hit) { - html_selection_set (priv->view, - priv->find_node, - hit - haystack + priv->find_offset, - strlen (find_string)); - - priv->find_offset += hit - haystack; - + if (forward) { + html_selection_set (priv->view, + priv->find_node, + hit - haystack + priv->find_offset, + strlen (find_string)); + priv->find_offset += hit - haystack + strlen (find_string); + } else { + html_selection_set (priv->view, + priv->find_node, + hit - haystack, + strlen (find_string)); + priv->find_offset = hit - haystack; + } + html_view_scroll_to_node (priv->view, priv->find_node, HTML_VIEW_SCROLL_TO_TOP); - - priv->find_offset += strlen (find_string); } + g_free (str); g_free (haystack); if (hit) { break; } - priv->find_node = dom_NodeIterator_nextNode (priv->find_iter, NULL); - priv->find_offset = 0; + if (forward) { + priv->find_node = dom_NodeIterator_nextNode (priv->find_iter, NULL); + priv->find_offset = 0; + } else { + priv->find_node = dom_NodeIterator_previousNode (priv->find_iter, NULL); + if (priv->find_node) { + box = html_view_find_layout_box (priv->view, priv->find_node, FALSE); + box_text = html_box_text_get_text (HTML_BOX_TEXT (box), &len); + priv->find_offset = len; + } + } } if (!priv->find_node) { g_object_unref (priv->find_iter); priv->find_iter = NULL; + priv->find_offset = 0; html_selection_clear (priv->view); } } diff --git a/src/yelp-html.h b/src/yelp-html.h index 80c70d91..bbc58cfd 100644 --- a/src/yelp-html.h +++ b/src/yelp-html.h @@ -74,6 +74,7 @@ GtkWidget * yelp_html_get_widget (YelpHtml *html); void yelp_html_find (YelpHtml *html, const gchar *str, gboolean match_case, + gboolean wrap, gboolean forward); #endif /* __YELP_HTML_H__ */ diff --git a/src/yelp-window.c b/src/yelp-window.c index 9df98dc6..d69ddd8b 100644 --- a/src/yelp-window.c +++ b/src/yelp-window.c @@ -95,6 +95,8 @@ static void window_close_window_cb (gpointer data, GtkWidget *widget); static void window_find_cb (gpointer data, guint section, GtkWidget *widget); +static void window_find_again_cb (gpointer data, guint section, + GtkWidget *widget); static void window_history_go_cb (gpointer data, guint section, GtkWidget *widget); @@ -112,8 +114,8 @@ static gboolean window_find_delete_event_cb (GtkWidget *widget, static void window_find_response_cb (GtkWidget *dialog , gint response, YelpWindow *window); +static YelpView * window_get_active_view (YelpWindow *window); static GtkWidget * window_create_toolbar (YelpWindow *window); - static GdkPixbuf * window_load_icon (void); @@ -144,6 +146,10 @@ struct _YelpWindowPriv { GtkWidget *find_dialog; GtkWidget *find_entry; GtkWidget *case_checkbutton; + GtkWidget *wrap_checkbutton; + gchar *find_string; + gboolean match_case; + gboolean wrap; YelpHistory *history; @@ -160,7 +166,7 @@ static GtkItemFactoryEntry menu_items[] = { {N_("/_Edit"), NULL, 0, 0, "<Branch>"}, {N_("/Edit/_Find in page..."), NULL, window_find_cb, 0, "<StockItem>", GTK_STOCK_FIND }, -/* {N_("/Edit/_Find again"), NULL, window_find_again_cb, 0, "<StockItem>", GTK_STOCK_FIND },*/ + {N_("/Edit/_Find again"), "<Control>g", window_find_again_cb, 0, "<StockItem>", GTK_STOCK_FIND }, {N_("/_Go"), NULL, 0, 0, "<Branch>"}, {N_("/Go/_Back"), NULL, window_history_go_cb, YELP_WINDOW_ACTION_BACK, "<StockItem>", GTK_STOCK_GO_BACK }, @@ -212,8 +218,11 @@ window_init (YelpWindow *window) priv->content_view = NULL; priv->index_view = NULL; - priv->history = yelp_history_new (); + priv->match_case = FALSE; + priv->wrap = TRUE; + priv->history = yelp_history_new (); + g_signal_connect (priv->history, "back_exists_changed", G_CALLBACK (window_toggle_history_back), @@ -579,9 +588,7 @@ window_find_cb (gpointer data, guint section, GtkWidget *widget) priv = window->priv; - if (priv->find_dialog) { - gtk_window_present (GTK_WINDOW (priv->find_dialog)); - } else { + if (!priv->find_dialog) { glade = glade_xml_new (DATADIR "/yelp/ui/yelp.glade", "find_dialog", NULL); if (!glade) { g_warning ("Couldn't find necessary glade file " DATADIR "/yelp/ui/yelp.glade"); @@ -589,10 +596,10 @@ window_find_cb (gpointer data, guint section, GtkWidget *widget) } priv->find_dialog = glade_xml_get_widget (glade, "find_dialog"); - gtk_widget_show (priv->find_dialog); priv->find_entry = glade_xml_get_widget (glade, "find_entry"); priv->case_checkbutton = glade_xml_get_widget (glade, "case_check"); + priv->wrap_checkbutton = glade_xml_get_widget (glade, "wrap_check"); g_signal_connect (priv->find_dialog, "delete_event", @@ -606,9 +613,37 @@ window_find_cb (gpointer data, guint section, GtkWidget *widget) g_object_unref (glade); } + + gtk_window_present (GTK_WINDOW (priv->find_dialog)); } static void +window_find_again_cb (gpointer data, guint section, GtkWidget *widget) +{ + YelpWindow *window = data; + YelpWindowPriv *priv; + YelpView *view; + YelpHtml *html; + + g_return_if_fail (YELP_IS_WINDOW (data)); + + window = YELP_WINDOW (data); + + priv = window->priv; + + if (priv->find_string) { + view = window_get_active_view (window); + html = yelp_view_get_html (view); + + yelp_html_find (html, + priv->find_string, + priv->match_case, + priv->wrap, + TRUE); + } +} + +static void window_history_go_cb (gpointer data, guint section, GtkWidget *widget) { window_history_action (data, section); @@ -665,26 +700,14 @@ window_find_response_cb (GtkWidget *dialog , YelpWindow *window) { YelpWindowPriv *priv; + YelpView *view; YelpHtml *html; const gchar *tmp; - gchar *str; - gboolean match_case; - - priv = window->priv; - switch (gtk_notebook_get_current_page (GTK_NOTEBOOK (priv->notebook))) { - case PAGE_TOC_VIEW: - html = yelp_view_get_html (priv->toc_view); - break; - case PAGE_CONTENT_VIEW: - html = yelp_view_get_html (priv->content_view); - break; - case PAGE_INDEX_VIEW: - html = yelp_view_get_html (priv->index_view); - break; - default: - g_assert_not_reached (); - } + priv = window->priv; + + view = window_get_active_view (window); + html = yelp_view_get_html (view); switch (response) { case GTK_RESPONSE_CLOSE: @@ -694,21 +717,26 @@ window_find_response_cb (GtkWidget *dialog , case RESPONSE_PREV: case RESPONSE_NEXT: tmp = gtk_entry_get_text (GTK_ENTRY (priv->find_entry)); - match_case = gtk_toggle_button_get_active ( + + priv->match_case = gtk_toggle_button_get_active ( GTK_TOGGLE_BUTTON (priv->case_checkbutton)); + + priv->wrap = gtk_toggle_button_get_active ( + GTK_TOGGLE_BUTTON (priv->wrap_checkbutton)); + + g_free (priv->find_string); - if (!match_case) { - str = g_utf8_casefold (tmp, -1); + if (!priv->match_case) { + priv->find_string = g_utf8_casefold (tmp, -1); } else { - str = g_strdup (tmp); + priv->find_string = g_strdup (tmp); } - + yelp_html_find (html, - str, - match_case, + priv->find_string, + priv->match_case, + priv->wrap, response == RESPONSE_NEXT); - - g_free (str); break; default: @@ -717,6 +745,28 @@ window_find_response_cb (GtkWidget *dialog , } +static YelpView * +window_get_active_view (YelpWindow *window) +{ + YelpWindowPriv *priv; + + priv = window->priv; + + switch (gtk_notebook_get_current_page (GTK_NOTEBOOK (priv->notebook))) { + case PAGE_TOC_VIEW: + return priv->toc_view; + case PAGE_CONTENT_VIEW: + return priv->content_view; + case PAGE_INDEX_VIEW: + return priv->index_view; + break; + default: + g_assert_not_reached (); + } + + return NULL; +} + static GtkWidget * window_create_toolbar (YelpWindow *window) { |