summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Hult <rhult@codefactory.se>2002-10-29 22:57:07 +0000
committerRichard Hult <rhult@src.gnome.org>2002-10-29 22:57:07 +0000
commit0dba170b30cf911eb0934adcd6c6377a659c8f08 (patch)
treefd4bebe015e6aa336fbd44b99677745f15dfaca4
parent885863b48b6ee9f285b07c73ac1222330afa5a9b (diff)
downloadyelp-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--ChangeLog4
-rw-r--r--src/yelp-html-gtkhtml2.c92
-rw-r--r--src/yelp-html.h1
-rw-r--r--src/yelp-window.c116
4 files changed, 155 insertions, 58 deletions
diff --git a/ChangeLog b/ChangeLog
index 074ca7c0..510199c2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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)
{