From 0f347181c81c0d831af9494c984ac3831390cbc8 Mon Sep 17 00:00:00 2001 From: Antia Puentes Date: Fri, 19 Jul 2013 14:43:18 +0200 Subject: 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 origin commit: https://git.gnome.org/browse/evince/commit/?h=gnome-3-10&id=a178d26 --- libview/ev-view-accessible.c | 90 ++++++++++++++++++++++++++++++++++++++------ libview/ev-view-private.h | 5 ++- libview/ev-view.c | 29 ++++++++++---- 3 files changed, 105 insertions(+), 19 deletions(-) (limited to 'libview') diff --git a/libview/ev-view-accessible.c b/libview/ev-view-accessible.c index 81fcc797..7e62f70d 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 dfe777ff..178733a7 100644 --- a/libview/ev-view-private.h +++ b/libview/ev-view-private.h @@ -288,7 +288,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); void _ev_view_set_focused_element (EvView *view, EvMapping *element_mapping, gint page); diff --git a/libview/ev-view.c b/libview/ev-view.c index 9a81ce46..2e277cff 100644 --- a/libview/ev-view.c +++ b/libview/ev-view.c @@ -4233,11 +4233,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; @@ -4249,7 +4249,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) { @@ -4305,11 +4305,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; -- cgit v1.2.1