[balsa] New methods for text search in HTML parts



commit e0102bfc1d6f5c2a364c4494a00b87c78d479218
Author: Peter Bloomfield <PeterBloomfield bellsouth net>
Date:   Tue Oct 27 20:14:33 2009 -0400

    New methods for text search in HTML parts

 ChangeLog               |   11 ++++
 libbalsa/html.c         |   41 +++++++++++++++
 libbalsa/html.h         |    4 ++
 src/balsa-message.c     |  125 +++++++++++++++++++++++++++-------------------
 src/balsa-mime-widget.c |   10 +++-
 5 files changed, 137 insertions(+), 54 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index a42133e..2eec1fb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,16 @@
 2009-10-27  Peter Bloomfield
 
+	* libbalsa/html.h: new methods for text search, to access
+	WebKitWebView capability.
+	* libbalsa/html.c (libbalsa_html_can_search,
+	libbalsa_html_search_text): implement them.
+	* src/balsa-message.c (bm_find_entry_changed_cb,
+	bm_find_again, balsa_message_find_in_message): use them.
+	* src/balsa-mime-widget.c (balsa_mime_widget_destroy): work-around
+	weird WebKitWebView-GtkClipboard issue.
+
+2009-10-27  Peter Bloomfield
+
 	* src/toolbar-factory.c: show text for "compose" instead of
 	"trash/delete".
 
diff --git a/libbalsa/html.c b/libbalsa/html.c
index d8ad72a..3214432 100644
--- a/libbalsa/html.c
+++ b/libbalsa/html.c
@@ -230,6 +230,21 @@ void libbalsa_html_copy(GtkWidget * widget)
     webkit_web_view_copy_clipboard(WEBKIT_WEB_VIEW(widget));
 }
 
+gboolean
+libbalsa_html_can_search(GtkWidget * widget)
+{
+    return WEBKIT_IS_WEB_VIEW(widget);
+}
+
+gboolean
+libbalsa_html_search_text(GtkWidget * widget, const gchar * text,
+                          gboolean find_forward, gboolean wrap)
+{
+    return webkit_web_view_search_text(WEBKIT_WEB_VIEW(widget), text,
+                                       FALSE,   /* case-insensitive */
+                                       find_forward, wrap);
+}
+
 # else                          /* defined(HAVE_WEBKIT) */
 
 /* Common code for both GtkHtml widgets. */
@@ -485,6 +500,19 @@ libbalsa_html_copy(GtkWidget * widget)
     gtk_html_copy(GTK_HTML(widget));
 }
 
+gboolean
+libbalsa_html_can_search(GtkWidget * widget)
+{
+    return FALSE;
+}
+
+gboolean
+libbalsa_html_search_text(GtkWidget * widget, const gchar * text,
+                          gboolean find_forward)
+{
+    return FALSE;
+}
+
 # else				/* HAVE_GTKHTML3 */
 
 /* Code for GtkHtml-2 */
@@ -620,6 +648,19 @@ libbalsa_html_copy(GtkWidget * widget)
 {
 }
 
+gboolean
+libbalsa_html_can_search(GtkWidget * widget)
+{
+    return FALSE;
+}
+
+gboolean
+libbalsa_html_search_text(GtkWidget * widget, const gchar * text,
+                          gboolean find_forward)
+{
+    return FALSE;
+}
+
 # endif				/* HAVE_GTKHTML3 */
 
 /* Common code for both widgets. */
diff --git a/libbalsa/html.h b/libbalsa/html.h
index 1611668..bd09382 100644
--- a/libbalsa/html.h
+++ b/libbalsa/html.h
@@ -60,6 +60,10 @@ void libbalsa_html_copy(GtkWidget * widget);
 guint libbalsa_html_filter(LibBalsaHTMLType html_type, gchar ** text,
 			   guint len);
 
+gboolean libbalsa_html_can_search(GtkWidget * widget);
+gboolean libbalsa_html_search_text(GtkWidget * widget, const gchar * text,
+                                   gboolean find_forward, gboolean wrap);
+
 # endif				/* HAVE_GTKHTML */
 
 LibBalsaHTMLType libbalsa_html_type(const gchar * mime_type);
diff --git a/src/balsa-message.c b/src/balsa-message.c
index 535e834..7dba5cb 100644
--- a/src/balsa-message.c
+++ b/src/balsa-message.c
@@ -448,37 +448,44 @@ bm_find_entry_changed_cb(GtkEditable * editable, gpointer data)
 {
     const gchar *text = gtk_entry_get_text(GTK_ENTRY(editable));
     BalsaMessage *bm = data;
-    GtkTextView *text_view =
-        GTK_TEXT_VIEW(bm->current_part->mime_widget->widget);
-    GtkTextBuffer *buffer = gtk_text_view_get_buffer(text_view);
-    GtkTextIter match_begin, match_end;
-    gboolean found;
+    GtkWidget *widget = bm->current_part->mime_widget->widget;
+    gboolean found = FALSE;
 
-    if (bm->find_forward) {
-        found = FORWARD_SEARCH(&bm->find_iter, text,
-                               &match_begin, &match_end);
-        if (!found) {
-            /* Silently wrap to the top. */
-            gtk_text_buffer_get_start_iter(buffer, &bm->find_iter);
+    if (GTK_IS_TEXT_VIEW(widget)) {
+        GtkTextView *text_view = GTK_TEXT_VIEW(widget);
+        GtkTextBuffer *buffer = gtk_text_view_get_buffer(text_view);
+        GtkTextIter match_begin, match_end;
+
+        if (bm->find_forward) {
             found = FORWARD_SEARCH(&bm->find_iter, text,
                                    &match_begin, &match_end);
-        }
-    } else {
-        found = BACKWARD_SEARCH(&bm->find_iter, text,
-                                &match_begin, &match_end);
-        if (!found) {
-            /* Silently wrap to the bottom. */
-            gtk_text_buffer_get_end_iter(buffer, &bm->find_iter);
+            if (!found) {
+                /* Silently wrap to the top. */
+                gtk_text_buffer_get_start_iter(buffer, &bm->find_iter);
+                found = FORWARD_SEARCH(&bm->find_iter, text,
+                                       &match_begin, &match_end);
+            }
+        } else {
             found = BACKWARD_SEARCH(&bm->find_iter, text,
                                     &match_begin, &match_end);
+            if (!found) {
+                /* Silently wrap to the bottom. */
+                gtk_text_buffer_get_end_iter(buffer, &bm->find_iter);
+                found = BACKWARD_SEARCH(&bm->find_iter, text,
+                                        &match_begin, &match_end);
+            }
         }
-    }
 
-    if (found) {
-        gtk_text_buffer_select_range(buffer, &match_begin, &match_end);
-        bm_find_scroll_to_iter(bm, text_view, &match_begin);
-        bm->find_iter = match_begin;
-    }
+        if (found) {
+            gtk_text_buffer_select_range(buffer, &match_begin, &match_end);
+            bm_find_scroll_to_iter(bm, text_view, &match_begin);
+            bm->find_iter = match_begin;
+        }
+    } else if (libbalsa_html_can_search(widget))
+        found = libbalsa_html_search_text(widget, text, bm->find_forward, TRUE);
+    else
+        g_assert_not_reached();
+
     bm_find_set_status(bm, found ?
                        BM_FIND_STATUS_FOUND : BM_FIND_STATUS_NOT_FOUND);
 }
@@ -487,35 +494,46 @@ static void
 bm_find_again(BalsaMessage * bm, gboolean find_forward)
 {
     const gchar *text = gtk_entry_get_text(GTK_ENTRY(bm->find_entry));
-    GtkTextView *text_view =
-        GTK_TEXT_VIEW(bm->current_part->mime_widget->widget);
-    GtkTextBuffer *buffer = gtk_text_view_get_buffer(text_view);
-    GtkTextIter match_begin, match_end;
+    GtkWidget *widget = bm->current_part->mime_widget->widget;
     gboolean found;
 
-    if (find_forward) {
-        gtk_text_iter_forward_char(&bm->find_iter);
-        found = FORWARD_SEARCH(&bm->find_iter, text,
-                               &match_begin, &match_end);
-        if (!found) {
-            gtk_text_buffer_get_start_iter(buffer, &bm->find_iter);
-            FORWARD_SEARCH(&bm->find_iter, text, &match_begin, &match_end);
-        }
-    } else {
-        gtk_text_iter_backward_char(&bm->find_iter);
-        found = BACKWARD_SEARCH(&bm->find_iter, text,
-                                &match_begin, &match_end);
-        if (!found) {
-            gtk_text_buffer_get_end_iter(buffer, &bm->find_iter);
-            BACKWARD_SEARCH(&bm->find_iter, text, &match_begin, &match_end);
+    if (GTK_IS_TEXT_VIEW(widget)) {
+        GtkTextView *text_view = GTK_TEXT_VIEW(widget);
+        GtkTextBuffer *buffer = gtk_text_view_get_buffer(text_view);
+        GtkTextIter match_begin, match_end;
+
+        if (find_forward) {
+            gtk_text_iter_forward_char(&bm->find_iter);
+            found = FORWARD_SEARCH(&bm->find_iter, text,
+                                   &match_begin, &match_end);
+            if (!found) {
+                gtk_text_buffer_get_start_iter(buffer, &bm->find_iter);
+                FORWARD_SEARCH(&bm->find_iter, text, &match_begin,
+                               &match_end);
+            }
+        } else {
+            gtk_text_iter_backward_char(&bm->find_iter);
+            found = BACKWARD_SEARCH(&bm->find_iter, text,
+                                    &match_begin, &match_end);
+            if (!found) {
+                gtk_text_buffer_get_end_iter(buffer, &bm->find_iter);
+                BACKWARD_SEARCH(&bm->find_iter, text, &match_begin,
+                                &match_end);
+            }
         }
-    }
+
+        gtk_text_buffer_select_range(buffer, &match_begin, &match_end);
+        bm_find_scroll_to_iter(bm, text_view, &match_begin);
+        bm->find_iter = match_begin;
+    } else if (libbalsa_html_can_search(widget)) {
+        found = libbalsa_html_search_text(widget, text, find_forward, FALSE);
+        if (!found)
+            libbalsa_html_search_text(widget, text, find_forward, TRUE);
+    } else
+        g_assert_not_reached();
+
     bm_find_set_status(bm, found ?
                        BM_FIND_STATUS_FOUND : BM_FIND_STATUS_WRAPPED);
-
-    gtk_text_buffer_select_range(buffer, &match_begin, &match_end);
-    bm_find_scroll_to_iter(bm, text_view, &match_begin);
-    bm->find_iter = match_begin;
     bm->find_forward = find_forward;
 }
 
@@ -3239,12 +3257,15 @@ balsa_message_find_in_message(BalsaMessage * bm)
 
     if (bm->current_part
         && (w = bm->current_part->mime_widget->widget)
-        && GTK_IS_TEXT_VIEW(w)) {
-        GtkTextView *text_view = (GtkTextView *) w;
-        GtkTextBuffer *buffer = gtk_text_view_get_buffer(text_view);
+        && (GTK_IS_TEXT_VIEW(w) || libbalsa_html_can_search(w))) {
+        if (GTK_IS_TEXT_VIEW(w)) {
+            GtkTextView *text_view = (GtkTextView *) w;
+            GtkTextBuffer *buffer = gtk_text_view_get_buffer(text_view);
+
+            gtk_text_buffer_get_start_iter(buffer, &bm->find_iter);
+        }
 
         bm->find_forward = TRUE;
-        gtk_text_buffer_get_start_iter(buffer, &bm->find_iter);
         gtk_entry_set_text(GTK_ENTRY(bm->find_entry), "");
         g_signal_connect_swapped(gtk_widget_get_toplevel(GTK_WIDGET(bm)),
                                  "key-press-event",
diff --git a/src/balsa-mime-widget.c b/src/balsa-mime-widget.c
index 1d7f9a1..f9e3232 100644
--- a/src/balsa-mime-widget.c
+++ b/src/balsa-mime-widget.c
@@ -27,6 +27,7 @@
 #include <string.h>
 #include "balsa-icons.h"
 #include "mime-stream-shared.h"
+#include "html.h"
 #include <glib/gi18n.h>
 #include "balsa-mime-widget-message.h"
 #include "balsa-mime-widget-multipart.h"
@@ -199,9 +200,14 @@ balsa_mime_widget_destroy(GObject * object)
     if (mime_widget->container && mime_widget->container != mime_widget->widget)
 	gtk_widget_destroy(mime_widget->container);
     mime_widget->container = NULL;
-    if (mime_widget->widget)
+    if (mime_widget->widget) {
+        /* Work-around for webkit issue: */
+        if (libbalsa_html_can_search(mime_widget->widget))
+            g_object_set_data(G_OBJECT(mime_widget->widget),
+                              "gtk-clipboards-owned", NULL);
 	gtk_widget_destroy(mime_widget->widget);
-    mime_widget->widget = NULL;
+        mime_widget->widget = NULL;
+    }
 
     G_OBJECT_CLASS(parent_class)->finalize(object);
 }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]