[evince] libview: Rework ev_view_accessible_get_selection



commit a178d268f2c388726a440a87852097482ddf04b0
Author: Antia Puentes <apuentes igalia com>
Date:   Fri Jul 19 14:43:18 2013 +0200

    libview: Rework ev_view_accessible_get_selection
    
    Actually return the text and offset range of the selected text in the
    current page.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=704335

 libview/ev-view-accessible.c |   90 ++++++++++++++++++++++++++++++++++++-----
 libview/ev-view-private.h    |    4 ++
 libview/ev-view.c            |   29 ++++++++++---
 3 files changed, 105 insertions(+), 18 deletions(-)
---
diff --git a/libview/ev-view-accessible.c b/libview/ev-view-accessible.c
index 45f725e..bf9cbc8 100644
--- a/libview/ev-view-accessible.c
+++ b/libview/ev-view-accessible.c
@@ -626,6 +626,42 @@ ev_view_accessible_get_n_selections (AtkText *text)
        return 1;
 }
 
+static gboolean
+get_selection_bounds (EvView          *view,
+                     EvViewSelection *selection,
+                     gint            *start_offset,
+                     gint            *end_offset)
+{
+       cairo_rectangle_int_t rect;
+       gint start, end;
+
+       if (!selection->covered_region || cairo_region_is_empty (selection->covered_region))
+               return FALSE;
+
+       cairo_region_get_rectangle (selection->covered_region, 0, &rect);
+       start = _ev_view_get_caret_cursor_offset_at_doc_point (view,
+                                                              selection->page,
+                                                              rect.x / view->scale,
+                                                              (rect.y + (rect.height / 2)) / view->scale);
+       if (start == -1)
+               return FALSE;
+
+       cairo_region_get_rectangle (selection->covered_region,
+                                   cairo_region_num_rectangles (selection->covered_region) - 1,
+                                   &rect);
+       end = _ev_view_get_caret_cursor_offset_at_doc_point (view,
+                                                            selection->page,
+                                                            (rect.x + rect.width) / view->scale,
+                                                            (rect.y + (rect.height / 2)) / view->scale);
+       if (end == -1)
+               return FALSE;
+
+       *start_offset = start;
+       *end_offset = end;
+
+       return TRUE;
+}
+
 static gchar *
 ev_view_accessible_get_selection (AtkText *text,
                                  gint     selection_num,
@@ -633,9 +669,13 @@ ev_view_accessible_get_selection (AtkText *text,
                                  gint    *end_pos)
 {
        GtkWidget *widget;
-       GtkTextBuffer *buffer;
-       GtkTextIter start, end;
-       gchar *retval = NULL;
+       EvView    *view;
+       gchar *selected_text = NULL;
+       gchar *normalized_text = NULL;
+       GList *l;
+
+       *start_pos = -1;
+       *end_pos = -1;
 
        widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (text));
        if (widget == NULL)
@@ -645,18 +685,46 @@ ev_view_accessible_get_selection (AtkText *text,
        if (selection_num != 0)
                return NULL;
 
-       buffer = ev_view_accessible_get_text_buffer (EV_VIEW_ACCESSIBLE (text), EV_VIEW (widget));
-       if (!buffer)
+       view = EV_VIEW (widget);
+       if (!EV_IS_SELECTION (view->document) || !view->selection_info.selections)
                return NULL;
 
-       gtk_text_buffer_get_selection_bounds (buffer, &start, &end);
-       *start_pos = gtk_text_iter_get_offset (&start);
-       *end_pos = gtk_text_iter_get_offset (&end);
 
-       if (*start_pos != *end_pos)
-               retval = gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
+       for (l = view->selection_info.selections; l != NULL; l = l->next) {
+               EvViewSelection *selection = (EvViewSelection *)l->data;
+               gint start, end;
 
-       return retval;
+               if (selection->page != view->current_page)
+                       continue;
+
+               if (get_selection_bounds (view, selection, &start, &end) && start != end) {
+                       EvPage *page;
+
+                       page = ev_document_get_page (view->document, selection->page);
+
+                       ev_document_doc_mutex_lock ();
+                       selected_text = ev_selection_get_selected_text (EV_SELECTION (view->document),
+                                                                       page,
+                                                                       selection->style,
+                                                                       &(selection->rect));
+
+                       ev_document_doc_mutex_unlock ();
+
+                       g_object_unref (page);
+
+                       *start_pos = start;
+                       *end_pos = end;
+               }
+
+               break;
+       }
+
+       if (selected_text) {
+               normalized_text = g_utf8_normalize (selected_text, -1, G_NORMALIZE_NFKC);
+               g_free (selected_text);
+       }
+
+       return normalized_text;
 }
 
 static gboolean
diff --git a/libview/ev-view-private.h b/libview/ev-view-private.h
index fb492e8..f27058b 100644
--- a/libview/ev-view-private.h
+++ b/libview/ev-view-private.h
@@ -270,6 +270,10 @@ void _ev_view_transform_doc_rect_to_view_rect (EvView       *view,
 void _ev_view_get_selection_colors (EvView  *view,
                                    GdkRGBA *bg_color,
                                    GdkRGBA *fg_color);
+gint _ev_view_get_caret_cursor_offset_at_doc_point (EvView *view,
+                                                   gint    page,
+                                                   gdouble doc_x,
+                                                   gdouble doc_y);
 
 #endif  /* __EV_VIEW_PRIVATE_H__ */
 
diff --git a/libview/ev-view.c b/libview/ev-view.c
index 970e0d3..5f1ece6 100644
--- a/libview/ev-view.c
+++ b/libview/ev-view.c
@@ -4210,11 +4210,11 @@ start_selection_for_event (EvView         *view,
                            &(view->selection_info.start));
 }
 
-static gboolean
-position_caret_cursor_at_doc_point (EvView *view,
-                                   gint    page,
-                                   gdouble doc_x,
-                                   gdouble doc_y)
+gint
+_ev_view_get_caret_cursor_offset_at_doc_point (EvView *view,
+                                              gint    page,
+                                              gdouble doc_x,
+                                              gdouble doc_y)
 {
        EvRectangle *areas = NULL;
        guint        n_areas = 0;
@@ -4226,7 +4226,7 @@ position_caret_cursor_at_doc_point (EvView *view,
 
        ev_page_cache_get_text_layout (view->page_cache, page, &areas, &n_areas);
        if (!areas)
-               return FALSE;
+               return -1;
 
        i = 0;
        while (i < n_areas && offset == -1) {
@@ -4282,11 +4282,26 @@ position_caret_cursor_at_doc_point (EvView *view,
        }
 
        if (last_line_offset == -1)
-               return FALSE;
+               return -1;
 
        if (offset == -1)
                offset = last_line_offset;
 
+       return offset;
+}
+
+static gboolean
+position_caret_cursor_at_doc_point (EvView *view,
+                                   gint    page,
+                                   gdouble doc_x,
+                                   gdouble doc_y)
+{
+       gint offset;
+
+       offset = _ev_view_get_caret_cursor_offset_at_doc_point (view, page, doc_x, doc_y);
+       if (offset == -1)
+               return FALSE;
+
        if (view->cursor_offset != offset || view->cursor_page != page) {
                view->cursor_offset = offset;
                view->cursor_page = page;


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