]> www.fi.muni.cz Git - evince.git/commitdiff
connect to "found" signal (expose_bin_window): draw find highlights
authorHavoc Pennington <hp@redhat.com>
Wed, 22 Dec 2004 05:30:35 +0000 (05:30 +0000)
committerHavoc Pennington <hp@src.gnome.org>
Wed, 22 Dec 2004 05:30:35 +0000 (05:30 +0000)
2004-12-22  Havoc Pennington  <hp@redhat.com>

* shell/ev-view.c (ev_view_set_document): connect to "found" signal
(expose_bin_window): draw find highlights

* shell/ev-window.c (find_bar_search_changed_cb): implement

* pdf/xpdf/pdf-document.cc (pdf_document_begin_find)
(pdf_document_end_find): implement this interface

* backend/ev-document.c (ev_document_found): add this to emit
signal

ChangeLog
backend/ev-document.c
backend/ev-document.h
pdf/xpdf/pdf-document.cc
shell/ev-view.c
shell/ev-window.c

index b13df8ba1243e8f09e989881b4b8f6b28efbf196..532f307c92026835eb901a733d5cd556350fb83e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2004-12-22  Havoc Pennington  <hp@redhat.com>
+
+       * shell/ev-view.c (ev_view_set_document): connect to "found" signal
+       (expose_bin_window): draw find highlights
+
+       * shell/ev-window.c (find_bar_search_changed_cb): implement 
+       
+       * pdf/xpdf/pdf-document.cc (pdf_document_begin_find) 
+       (pdf_document_end_find): implement this interface
+
+       * backend/ev-document.c (ev_document_found): add this to emit
+       signal
+
 Tue Dec 21 23:57:37 2004  Owen Taylor  <otaylor@redhat.com>
 
        * data/evince-ui.xml: Add a few more toolbar items.
index 4aea1d11c0fbeaf5afc6261c1b20088f484fc8ad..2f50dcc832d05bdbdc14254f00d47f8c12b2ea93 100644 (file)
@@ -159,3 +159,15 @@ ev_document_end_find (EvDocument   *document)
        EvDocumentIface *iface = EV_DOCUMENT_GET_IFACE (document);
        iface->end_find (document);
 }
+
+void
+ev_document_found (EvDocument         *document,
+                  const EvFindResult *results,
+                  int                 n_results,
+                  double              percent_complete)
+{
+       g_signal_emit_by_name (document,
+                              "found",
+                              results, n_results, percent_complete);
+}
+                                   
index 8d58f0c501d9d10345169ca1aae16a4047d5562a..4cf4601fc0cac639a83eec7cd2288e881ae7a126 100644 (file)
@@ -80,7 +80,9 @@ struct _EvDocumentIface
         /* Signals */
 
         /* "found" emitted at least 1 time (possibly with n_results == 0)
-         * for any call to begin_find.
+         * for any call to begin_find; also emitted with NULL,0 when
+        * you end_find. Calling begin_find twice without calling end_find
+        * is considered OK.
          */
         void         (* found)          (EvDocument         *document,
                                          const EvFindResult *results,
@@ -117,6 +119,12 @@ void     ev_document_begin_find    (EvDocument   *document,
                                     gboolean      case_sensitive);
 void     ev_document_end_find      (EvDocument   *document);
 
+void     ev_document_found         (EvDocument         *document,
+                                   const EvFindResult *results,
+                                   int                 n_results,
+                                   double              percent_complete);
+                                   
+
 G_END_DECLS
 
 #endif
index a25f663030b57926fa6dc02978b9b8c52100d1d1..be15d7caf2e8c04e4de310ca957f8cd8d9b856c5 100644 (file)
@@ -1,3 +1,4 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; c-indent-level: 8 -*- */
 /* pdfdocument.h: Implementation of EvDocument for PDF
  * Copyright (C) 2004, Red Hat, Inc.
  *
@@ -271,6 +272,88 @@ pdf_document_render (EvDocument  *document,
                                           draw.width, draw.height);
 }
 
+void
+pdf_document_begin_find (EvDocument   *document,
+                         const char   *search_string,
+                         gboolean      case_sensitive)
+{
+        /* FIXME make this incremental (idle handler) and multi-page */
+        /* Right now it's fully synchronous plus only does the current page */
+        
+        PdfDocument *pdf_document = PDF_DOCUMENT (document);
+        gunichar *ucs4;
+        glong ucs4_len;
+        int xMin, yMin, xMax, yMax;
+        GArray *results;
+        EvFindResult result;
+
+        /* FIXME case_sensitive (right now XPDF
+         * code is always case insensitive for ASCII
+         * and case sensitive for all other languaages)
+         */
+        
+        g_assert (sizeof (gunichar) == sizeof (Unicode));
+        ucs4 = g_utf8_to_ucs4_fast (search_string, -1,
+                                    &ucs4_len);
+
+        results = g_array_new (FALSE,
+                               FALSE,
+                               sizeof (EvFindResult));
+
+        if (pdf_document->out->findText (ucs4, ucs4_len,
+                                         gTrue, gTrue, // startAtTop, stopAtBottom
+                                         gFalse, gFalse, // startAtLast, stopAtLast
+                                         &xMin, &yMin, &xMax, &yMax)) {
+
+                result.page_num = pdf_document->page;
+
+                result.highlight_area.x = xMin;
+                result.highlight_area.y = yMin;
+                result.highlight_area.width = xMax - xMin;
+                result.highlight_area.height = yMax - yMin;
+
+                g_array_append_val (results, result);
+        
+                /* Now find further results */
+
+                while (pdf_document->out->findText (ucs4, ucs4_len,
+                                                    gFalse, gTrue,
+                                                    gTrue, gFalse,
+                                                    &xMin, &yMin, &xMax, &yMax)) {
+                        
+                        result.page_num = pdf_document->page;
+                        
+                        result.highlight_area.x = xMin;
+                        result.highlight_area.y = yMin;
+                        result.highlight_area.width = xMax - xMin;
+                        result.highlight_area.height = yMax - yMin;
+                        
+                        g_array_append_val (results, result);
+                }
+        }
+
+        ev_document_found (document,
+                           (EvFindResult*) results->data,
+                           results->len,
+                           1.0);
+
+        g_array_free (results, TRUE);
+}
+
+void
+pdf_document_end_find (EvDocument   *document)
+{
+        PdfDocument *pdf_document = PDF_DOCUMENT (document);
+
+        /* FIXME this will do something once begin_find queues
+         * an incremental find
+         */
+
+        // this should probably be shared among EvDocument
+        // implementations somehow?
+        ev_document_found (document, NULL, 0, 1.0);
+}
+
 static void
 pdf_document_finalize (GObject *object)
 {
@@ -306,6 +389,8 @@ pdf_document_document_iface_init (EvDocumentIface *iface)
        iface->set_page_offset = pdf_document_set_page_offset;
        iface->get_page_size = pdf_document_get_page_size;
        iface->render = pdf_document_render;
+        iface->begin_find = pdf_document_begin_find;
+        iface->end_find = pdf_document_end_find;
 }
 
 static void
index 7aaa59aba9a611ab083baa466a81e181a439a03b..a928ed3033e22a485304fb02a2ddfb750510f7d0 100644 (file)
@@ -1,3 +1,4 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; c-indent-level: 8 -*- */
 /* this file is part of evince, a gnome document viewer
  *
  *  Copyright (C) 2004 Red Hat, Inc
@@ -38,6 +39,8 @@ struct _EvView {
 
        GtkAdjustment *hadjustment;
        GtkAdjustment *vadjustment;
+
+        GArray *find_results;
 };
 
 struct _EvViewClass {
@@ -135,6 +138,9 @@ ev_view_finalize (GObject *object)
 
        ev_view_set_scroll_adjustments (view, NULL, NULL);
 
+        g_array_free (view->find_results, TRUE);
+        view->find_results = NULL;
+        
        G_OBJECT_CLASS (ev_view_parent_class)->finalize (object);
 }
 
@@ -285,11 +291,35 @@ expose_bin_window (GtkWidget      *widget,
                   GdkEventExpose *event)
 {
        EvView *view = EV_VIEW (widget);
+        int i;
+        const EvFindResult *results;
        
        if (view->document)
                ev_document_render (view->document,
                                    event->area.x, event->area.y,
                                    event->area.width, event->area.height);
+
+        results = (EvFindResult*) view->find_results->data;
+        i = 0;
+        while (i < view->find_results->len) {
+#if 0
+                g_printerr ("highlighting result %d at %d,%d %dx%d\n",
+                            i,
+                            results[i].highlight_area.x,
+                            results[i].highlight_area.y,
+                            results[i].highlight_area.width,
+                            results[i].highlight_area.height);
+#endif                       
+                // if (results[i].page_num == current_page) FIXME
+                gdk_draw_rectangle (view->bin_window,
+                                    widget->style->base_gc[GTK_STATE_SELECTED],
+                                    FALSE,
+                                    results[i].highlight_area.x,
+                                    results[i].highlight_area.y,
+                                    results[i].highlight_area.width,
+                                    results[i].highlight_area.height);
+                ++i;
+        }
 }
 
 static gboolean
@@ -304,7 +334,6 @@ ev_view_expose_event (GtkWidget      *widget,
                return GTK_WIDGET_CLASS (ev_view_parent_class)->expose_event (widget, event);
 
        return FALSE;
-  
 }
 
 static gboolean
@@ -430,6 +459,29 @@ ev_view_init (EvView *view)
        static const GdkColor white = { 0, 0xffff, 0xffff, 0xffff };
        
        gtk_widget_modify_bg (GTK_WIDGET (view), GTK_STATE_NORMAL, &white);
+
+        view->find_results = g_array_new (FALSE,
+                                          FALSE,
+                                          sizeof (EvFindResult));
+}
+
+
+static void
+found_results_callback (EvDocument         *document,
+                        const EvFindResult *results,
+                        int                 n_results,
+                        double              percent_complete,
+                        void               *data)
+{
+  EvView *view = EV_VIEW (data);
+  
+  g_array_set_size (view->find_results, 0);
+
+  if (n_results > 0)
+          g_array_append_vals (view->find_results,
+                               results, n_results);
+  
+  gtk_widget_queue_draw (GTK_WIDGET (view));
 }
 
 /*** Public API ***/       
@@ -449,13 +501,23 @@ ev_view_set_document (EvView     *view,
        if (document != view->document) {
                int old_page = ev_view_get_page (view);
                
-               if (view->document)
+               if (view->document) {
                        g_object_unref (view->document);
+                        g_signal_handlers_disconnect_by_func (view->document,
+                                                              found_results_callback,
+                                                              view);
+                        g_array_set_size (view->find_results, 0);
+                }
 
                view->document = document;
 
-               if (view->document)
+               if (view->document) {
                        g_object_ref (view->document);
+                        g_signal_connect (view->document,
+                                          "found",
+                                          G_CALLBACK (found_results_callback),
+                                          view);
+                }
 
                if (GTK_WIDGET_REALIZED (view))
                        ev_document_set_target (view->document, view->bin_window);
index ec21ae9060254ecdb7df4667e344b8723f0c9b50..df7bf255e90d20082f0b437480a52628d2f20e5f 100644 (file)
@@ -593,8 +593,18 @@ find_bar_search_changed_cb (EggFindBar *find_bar,
        visible = GTK_WIDGET_VISIBLE (find_bar);
        search_string = egg_find_bar_get_search_string (find_bar);
        
-       /* FIXME */
+#if 0
        g_printerr ("search for '%s'\n", search_string ? search_string : "(nil)");
+#endif
+
+       /* We don't require begin/end find calls to be matched up, it's really
+        * start_find and cancel_any_find_that_may_not_be_finished
+        */
+       if (visible && search_string) {
+               ev_document_begin_find (ev_window->priv->document, search_string, case_sensitive);
+       } else {
+               ev_document_end_find (ev_window->priv->document);
+       }
 }
 
 static void