]> www.fi.muni.cz Git - evince.git/blobdiff - shell/ev-view.c
Updated Lithuanian translation.
[evince.git] / shell / ev-view.c
index 6a17aa8591f2370ce6d59e4edec459c06bfd1d5d..ed55a110b78c8a8dd6c6ceee11dee081b5a094b9 100644 (file)
@@ -32,7 +32,6 @@
 #include "ev-view.h"
 #include "ev-view-private.h"
 #include "ev-utils.h"
-#include "ev-selection.h"
 #include "ev-document-links.h"
 #include "ev-document-images.h"
 #include "ev-document-find.h"
@@ -42,7 +41,9 @@
 #include "ev-job-queue.h"
 #include "ev-page-cache.h"
 #include "ev-pixbuf-cache.h"
+#if !GTK_CHECK_VERSION (2, 11, 7)
 #include "ev-tooltip.h"
+#endif
 #include "ev-application.h"
 
 #define EV_VIEW_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), EV_TYPE_VIEW, EvViewClass))
@@ -217,6 +218,7 @@ static void       highlight_find_results                     (EvView
                                                              int                 page);
 static void       draw_one_page                              (EvView             *view,
                                                              gint                page,
+                                                             cairo_t            *cr,
                                                              GdkRectangle       *page_area,
                                                              GtkBorder          *border,
                                                              GdkRectangle       *expose_area,
@@ -312,6 +314,7 @@ static void       jump_to_find_page                          (EvView
 
 /*** Selection ***/
 static void       compute_selections                         (EvView             *view,
+                                                             EvSelectionStyle    style,
                                                              GdkPoint           *start,
                                                              GdkPoint           *stop);
 static void       clear_selection                            (EvView             *view);
@@ -486,7 +489,7 @@ view_update_range_and_current_page (EvView *view)
                                }
 
                                view->end_page = i;
-                       } else if (found) {
+                       } else if (found && view->current_page <= view->end_page) {
                                break;
                        }
                }
@@ -1454,8 +1457,10 @@ tip_from_link (EvView *view, EvLink *link)
                case EV_LINK_ACTION_TYPE_GOTO_DEST:
                        page_label = ev_view_page_label_from_dest (view,
                                                                   ev_link_action_get_dest (action));
-                       msg = g_strdup_printf (_("Go to page %s"), page_label);
-                       g_free (page_label);
+                       if (page_label) {
+                               msg = g_strdup_printf (_("Go to page %s"), page_label);
+                               g_free (page_label);
+                       }
                        break;
                case EV_LINK_ACTION_TYPE_GOTO_REMOTE:
                        if (title) {
@@ -1465,7 +1470,6 @@ tip_from_link (EvView *view, EvLink *link)
                                msg = g_strdup_printf (_("Go to file ā€œ%sā€"),
                                                       ev_link_action_get_filename (action));
                        }
-                       
                        break;
                case EV_LINK_ACTION_TYPE_EXTERNAL_URI:
                        msg = g_strdup (ev_link_action_get_uri (action));
@@ -1494,9 +1498,16 @@ ev_view_handle_cursor_over_xy (EvView *view, gint x, gint y)
 
        if (view->cursor == EV_VIEW_CURSOR_HIDDEN)
                return;
+
+       if (view->drag_info.in_drag) {
+               if (view->cursor != EV_VIEW_CURSOR_DRAG)
+                       ev_view_set_cursor (view, EV_VIEW_CURSOR_DRAG);
+               return;
+       }
        
        link = ev_view_get_link_at_location (view, x, y);
-
+       
+#if !GTK_CHECK_VERSION (2, 11, 7)
        if (view->link_tooltip == NULL) {
                view->link_tooltip = ev_tooltip_new (GTK_WIDGET (view));
        }
@@ -1505,8 +1516,12 @@ ev_view_handle_cursor_over_xy (EvView *view, gint x, gint y)
                view->hovered_link = link;
                ev_tooltip_deactivate (EV_TOOLTIP (view->link_tooltip));
        }
+#endif
 
         if (link) {
+#if GTK_CHECK_VERSION (2, 11, 7)
+               g_object_set (view, "has-tooltip", TRUE, NULL);
+#else
                char *msg = tip_from_link (view, link);
 
                if (msg && g_utf8_validate (msg, -1, NULL)) {
@@ -1517,7 +1532,7 @@ ev_view_handle_cursor_over_xy (EvView *view, gint x, gint y)
                        ev_tooltip_activate (tooltip);
                }
                g_free (msg);
-
+#endif
                ev_view_set_cursor (view, EV_VIEW_CURSOR_LINK);
        } else if ((field = ev_view_get_form_field_at_location (view, x, y))) {
                if (field->is_read_only) {
@@ -2434,8 +2449,9 @@ static gboolean
 ev_view_expose_event (GtkWidget      *widget,
                      GdkEventExpose *event)
 {
-       EvView *view = EV_VIEW (widget);
-       int i;
+       EvView  *view = EV_VIEW (widget);
+       cairo_t *cr;
+       gint     i;
 
        if (view->presentation) {
                switch (view->presentation_state) {
@@ -2469,6 +2485,8 @@ ev_view_expose_event (GtkWidget      *widget,
        if (view->document == NULL)
                return FALSE;
 
+       cr = gdk_cairo_create (view->layout.bin_window);
+       
        for (i = view->start_page; i <= view->end_page; i++) {
                GdkRectangle page_area;
                GtkBorder border;
@@ -2480,12 +2498,14 @@ ev_view_expose_event (GtkWidget      *widget,
                page_area.x -= view->scroll_x;
                page_area.y -= view->scroll_y;
 
-               draw_one_page (view, i, &page_area, &border, &(event->area), &page_ready);
+               draw_one_page (view, i, cr, &page_area, &border, &(event->area), &page_ready);
 
-               if (page_ready && EV_IS_DOCUMENT_FIND (view->document))
+               if (page_ready && EV_IS_DOCUMENT_FIND (view->document) && view->highlight_find_results)
                        highlight_find_results (view, i);
        }
 
+       cairo_destroy (cr);
+
        if (GTK_WIDGET_CLASS (ev_view_parent_class)->expose_event)
                (* GTK_WIDGET_CLASS (ev_view_parent_class)->expose_event) (widget, event);
 
@@ -2526,6 +2546,86 @@ ev_view_popup_menu (GtkWidget *widget)
        return ev_view_do_popup_menu (EV_VIEW (widget), x, y);
 }
 
+#if GTK_CHECK_VERSION (2, 11, 7)
+static void
+get_link_area (EvView       *view,
+              gint          x,
+              gint          y,
+              EvLink       *link,
+              GdkRectangle *area)
+{
+       EvRectangle  ev_rect;
+       GList       *link_mapping;
+       gint         page;
+       gint         x_offset = 0, y_offset = 0;
+
+       x += view->scroll_x;
+       y += view->scroll_y;
+       
+       find_page_at_location (view, x, y, &page, &x_offset, &y_offset);
+       
+       link_mapping = ev_pixbuf_cache_get_link_mapping (view->pixbuf_cache, page);
+       ev_link_mapping_get_area (link_mapping, link, &ev_rect);
+
+       doc_rect_to_view_rect (view, page, &ev_rect, area);
+       area->y -= view->scroll_y ;
+}
+
+static gboolean
+ev_view_query_tooltip (GtkWidget         *widget,
+                      gint               x,
+                      gint               y,
+                      gboolean           keyboard_tip,
+                      GtkTooltip        *tooltip)
+{
+       EvView *view = EV_VIEW (widget);
+       EvLink *link;
+       gchar  *text;
+
+       link = ev_view_get_link_at_location (view, x, y);
+       if (!link)
+               return FALSE;
+
+       text = tip_from_link (view, link);
+       if (text && g_utf8_validate (text, -1, NULL)) {
+               GdkRectangle link_area;
+
+               get_link_area (view, x, y, link, &link_area);
+               gtk_tooltip_set_text (tooltip, text);
+               gtk_tooltip_set_tip_area (tooltip, &link_area);
+       }
+       g_free (text);
+
+       return TRUE;
+}
+#endif /* GTK_CHECK_VERSION (2, 11, 7) */
+
+static void
+start_selection_for_event (EvView         *view,
+                          GdkEventButton *event)
+{
+       EvSelectionStyle style;
+
+       clear_selection (view);
+       
+       view->selection_info.start.x = event->x + view->scroll_x;
+       view->selection_info.start.y = event->y + view->scroll_y;
+
+       switch (event->type) {
+               case GDK_2BUTTON_PRESS:
+                       style = EV_SELECTION_STYLE_WORD;
+                       break;
+               case GDK_3BUTTON_PRESS:
+                       style = EV_SELECTION_STYLE_LINE;
+                       break;
+               default:
+                       style = EV_SELECTION_STYLE_GLYPH;
+                       break;
+       }
+
+       view->selection_info.style = style;
+}
+
 static gboolean
 ev_view_button_press_event (GtkWidget      *widget,
                            GdkEventButton *event)
@@ -2547,19 +2647,21 @@ ev_view_button_press_event (GtkWidget      *widget,
                        EvImage *image;
                        EvFormField *field;
 
-                       if (view->selection_info.selections) {
-                               if (location_in_selected_text (view,
+                       if (EV_IS_SELECTION (view->document) && view->selection_info.selections) {
+                               if (event->type == GDK_3BUTTON_PRESS) {
+                                       start_selection_for_event (view, event);
+                               } else if (location_in_selected_text (view,
                                                               event->x + view->scroll_x,
                                                               event->y + view->scroll_y)) {
                                        view->selection_info.in_drag = TRUE;
                                } else {
-                                       clear_selection (view);
-                                       
-                                       view->selection_info.start.x = event->x + view->scroll_x;
-                                       view->selection_info.start.y = event->y + view->scroll_y;
+                                       start_selection_for_event (view, event);
                                }
-                               
+
                                gtk_widget_queue_draw (widget);
+                       } else if ((field = ev_view_get_form_field_at_location (view, event->x, event->y))) {
+                               ev_view_remove_all (view);
+                               ev_view_handle_form_field (view, field, event->x, event->y);
                        } else if (!location_in_text (view, event->x + view->scroll_x, event->y + view->scroll_y) &&
                                   (image = ev_view_get_image_at_location (view, event->x, event->y))) {
                                if (view->image_dnd_info.image)
@@ -2569,13 +2671,11 @@ ev_view_button_press_event (GtkWidget      *widget,
 
                                view->image_dnd_info.start.x = event->x + view->scroll_x;
                                view->image_dnd_info.start.y = event->y + view->scroll_y;
-                       } else if ((field = ev_view_get_form_field_at_location (view, event->x, event->y))) {
-                               ev_view_remove_all (view);
-                               ev_view_handle_form_field (view, field, event->x, event->y);
                        } else {
                                ev_view_remove_all (view);
-                               view->selection_info.start.x = event->x + view->scroll_x;
-                               view->selection_info.start.y = event->y + view->scroll_y;
+                               
+                               if (EV_IS_SELECTION (view->document))
+                                       start_selection_for_event (view, event);
                        }
                }                       
                        return TRUE;
@@ -2622,16 +2722,14 @@ ev_view_drag_data_get (GtkWidget        *widget,
 
        switch (info) {
                case TARGET_DND_TEXT:
-                       if (view->selection_info.selections &&
-                           ev_document_can_get_text (view->document)) {
+                       if (EV_IS_SELECTION (view->document) &&
+                           view->selection_info.selections) {
                                gchar *text;
 
                                text = get_selected_text (view);
-                               
                                gtk_selection_data_set_text (selection_data,
                                                             text,
                                                             strlen (text));
-                               
                                g_free (text);
                        }
                        break;
@@ -2712,7 +2810,10 @@ ev_view_drag_data_received (GtkWidget          *widget,
 static gboolean
 selection_update_idle_cb (EvView *view)
 {
-       compute_selections (view, &view->selection_info.start, &view->motion);
+       compute_selections (view,
+                           view->selection_info.style,
+                           &view->selection_info.start,
+                           &view->motion);
        view->selection_update_id = 0;
        return FALSE;
 }
@@ -2886,21 +2987,20 @@ ev_view_button_release_event (GtkWidget      *widget,
                              GdkEventButton *event)
 {
        EvView *view = EV_VIEW (widget);
-       EvLink *link;
+       EvLink *link = NULL;
+
+       view->drag_info.in_drag = FALSE;
+       view->image_dnd_info.in_drag = FALSE;
 
        if (view->pressed_button == 2) {
-               ev_view_set_cursor (view, EV_VIEW_CURSOR_NORMAL);
+               ev_view_handle_cursor_over_xy (view, event->x, event->y);
        }
 
        if (view->document && view->pressed_button != 3) {
                link = ev_view_get_link_at_location (view, event->x, event->y);
-       } else {
-               link = NULL;
        }
 
        view->pressed_button = -1;
-       view->drag_info.in_drag = FALSE;
-       view->image_dnd_info.in_drag = FALSE;
 
        if (view->selection_scroll_id) {
            g_source_remove (view->selection_scroll_id);
@@ -2911,6 +3011,14 @@ ev_view_button_release_event (GtkWidget      *widget,
            view->selection_update_id = 0;
        }
 
+       if (!view->selection_info.in_selection &&
+           view->selection_info.style != EV_SELECTION_STYLE_GLYPH) {
+               compute_selections (view,
+                                   view->selection_info.style,
+                                   &(view->selection_info.start),
+                                   &(view->selection_info.start));
+       }
+
        if (view->selection_info.selections) {
                ev_view_update_primary_selection (view);
                
@@ -3254,16 +3362,17 @@ static gboolean
 ev_view_leave_notify_event (GtkWidget *widget, GdkEventCrossing   *event)
 {
        EvView *view = EV_VIEW (widget);
-    
-       if (view->cursor == EV_VIEW_CURSOR_LINK ||
-           view->cursor == EV_VIEW_CURSOR_IBEAM)
+
+       if (view->cursor != EV_VIEW_CURSOR_NORMAL)
                ev_view_set_cursor (view, EV_VIEW_CURSOR_NORMAL);
 
+#if !GTK_CHECK_VERSION (2, 11, 7)
        if (view->link_tooltip) {
                view->hovered_link = NULL;
                ev_tooltip_deactivate (EV_TOOLTIP (view->link_tooltip));
        }
-
+#endif
+       
        return FALSE;
 }
 
@@ -3435,6 +3544,7 @@ draw_loading_text (EvView       *view,
 static void
 draw_one_page (EvView       *view,
               gint          page,
+              cairo_t      *cr,
               GdkRectangle *page_area,
               GtkBorder    *border,
               GdkRectangle *expose_area,
@@ -3473,7 +3583,6 @@ draw_one_page (EvView       *view,
                cairo_surface_t *page_surface = NULL;
                gint             selection_width, selection_height;
                cairo_surface_t *selection_surface = NULL;
-               cairo_t         *cr = NULL;
 
                page_surface = ev_pixbuf_cache_get_surface (view->pixbuf_cache, page);
 
@@ -3491,16 +3600,10 @@ draw_one_page (EvView       *view,
                                        view->scale,
                                        &width, &height);
 
-               cr = gdk_cairo_create (view->layout.bin_window);
-               
-               cairo_save (cr);
-               
                page_width = cairo_image_surface_get_width (page_surface);
                page_height = cairo_image_surface_get_height (page_surface);
-               
-               cairo_rectangle (cr, overlap.x, overlap.y, overlap.width, overlap.height);
-               cairo_clip (cr);
-               
+
+               cairo_save (cr);
                cairo_translate (cr, overlap.x, overlap.y);
                
                if (width != page_width || height != page_height) {
@@ -3514,10 +3617,8 @@ draw_one_page (EvView       *view,
                cairo_surface_set_device_offset (page_surface,
                                                 overlap.x - real_page_area.x,
                                                 overlap.y - real_page_area.y);
-
                cairo_set_source_surface (cr, page_surface, 0, 0);
                cairo_paint (cr);
-
                cairo_restore (cr);
                
                /* Get the selection pixbuf iff we have something to draw */
@@ -3531,16 +3632,13 @@ draw_one_page (EvView       *view,
                }
 
                if (!selection_surface) {
-                       cairo_destroy (cr);
                        return;
                }
 
                selection_width = cairo_image_surface_get_width (selection_surface);
                selection_height = cairo_image_surface_get_height (selection_surface);
 
-               cairo_rectangle (cr, overlap.x, overlap.y, overlap.width, overlap.height);
-               cairo_clip (cr);
-               
+               cairo_save (cr);
                cairo_translate (cr, overlap.x, overlap.y);
 
                if (width != selection_width || height != selection_height) {
@@ -3554,10 +3652,9 @@ draw_one_page (EvView       *view,
                cairo_surface_set_device_offset (selection_surface,
                                                 overlap.x - real_page_area.x,
                                                 overlap.y - real_page_area.y);
-
                cairo_set_source_surface (cr, selection_surface, 0, 0);
                cairo_paint (cr);
-               cairo_destroy (cr);
+               cairo_restore (cr);
        }
 }
 
@@ -3594,11 +3691,12 @@ ev_view_destroy (GtkObject *object)
                view->pixbuf_cache = NULL;
        }
 
+#if !GTK_CHECK_VERSION (2, 11, 7)
        if (view->link_tooltip) {
                gtk_widget_destroy (view->link_tooltip);
                view->link_tooltip = NULL;
        }
-
+#endif
        if (view->goto_window) {
                gtk_widget_destroy (view->goto_window);
                view->goto_window = NULL;
@@ -3767,6 +3865,9 @@ ev_view_class_init (EvViewClass *class)
        widget_class->drag_motion = ev_view_drag_motion;
        widget_class->drag_data_received = ev_view_drag_data_received;
        widget_class->popup_menu = ev_view_popup_menu;
+#if GTK_CHECK_VERSION (2, 11, 7)
+       widget_class->query_tooltip = ev_view_query_tooltip;
+#endif
 
        gtk_object_class->destroy = ev_view_destroy;
 
@@ -3900,6 +4001,15 @@ ev_view_class_init (EvViewClass *class)
        add_scroll_binding_keypad (binding_set, GDK_Down,  0, EV_SCROLL_STEP_FORWARD,  FALSE);
        add_scroll_binding_keypad (binding_set, GDK_Up,    GDK_MOD1_MASK, EV_SCROLL_STEP_DOWN, FALSE);
        add_scroll_binding_keypad (binding_set, GDK_Down,  GDK_MOD1_MASK, EV_SCROLL_STEP_UP,  FALSE);
+       gtk_binding_entry_add_signal (binding_set, GDK_H, 0, "binding_activated", 2, EV_TYPE_SCROLL_TYPE,
+                                     EV_SCROLL_STEP_BACKWARD, G_TYPE_BOOLEAN, TRUE);
+       gtk_binding_entry_add_signal (binding_set, GDK_J, 0, "binding_activated", 2, EV_TYPE_SCROLL_TYPE,
+                                     EV_SCROLL_STEP_FORWARD, G_TYPE_BOOLEAN, FALSE);
+       gtk_binding_entry_add_signal (binding_set, GDK_K, 0, "binding_activated", 2, EV_TYPE_SCROLL_TYPE,
+                                     EV_SCROLL_STEP_BACKWARD, G_TYPE_BOOLEAN, FALSE);
+       gtk_binding_entry_add_signal (binding_set, GDK_L, 0, "binding_activated", 2, EV_TYPE_SCROLL_TYPE,
+                                     EV_SCROLL_STEP_FORWARD, G_TYPE_BOOLEAN, TRUE);
+       
 }
 
 static void
@@ -3925,6 +4035,7 @@ ev_view_init (EvView *view)
        view->sizing_mode = EV_SIZING_FIT_WIDTH;
        view->pending_scroll = SCROLL_TO_KEEP_POSITION;
        view->jump_to_find_result = TRUE;
+       view->highlight_find_results = FALSE;
 
        gtk_layout_set_hadjustment (GTK_LAYOUT (view), NULL);
        gtk_layout_set_vadjustment (GTK_LAYOUT (view), NULL);
@@ -4342,10 +4453,19 @@ ev_view_presentation_transition_start (EvView *view)
 
        duration = ev_document_transition_get_page_duration (EV_DOCUMENT_TRANSITION (view->document),
                                                             view->current_page);
-       if (duration > 0)
-               view->trans_timeout_id = g_timeout_add (duration * 1000,
-                                                       (GSourceFunc) transition_next_page,
-                                                       view);
+       if (duration > 0) {
+#if GLIB_CHECK_VERSION (2, 13, 0)
+               view->trans_timeout_id =
+                       g_timeout_add_seconds (duration,
+                                              (GSourceFunc) transition_next_page,
+                                              view);
+#else
+               view->trans_timeout_id =
+                       g_timeout_add (duration * 1000,
+                                      (GSourceFunc) transition_next_page,
+                                      view);
+#endif
+       }
 }
 
 void
@@ -4685,13 +4805,14 @@ ev_view_zoom_for_size_single_page (EvView *view,
        ev_view_set_zoom (view, scale, FALSE);
 }
 
-void
+static void
 ev_view_set_zoom_for_size (EvView *view,
                           int     width,
                           int     height,
                           int     vsb_width,
                           int     hsb_height)
 {
+       g_return_if_fail (EV_IS_VIEW (view));
        g_return_if_fail (view->sizing_mode == EV_SIZING_FIT_WIDTH ||
                          view->sizing_mode == EV_SIZING_BEST_FIT);
        g_return_if_fail (width >= 0);
@@ -4916,6 +5037,12 @@ void ev_view_search_changed (EvView *view)
        view->jump_to_find_result = TRUE;
 }
 
+void ev_view_set_highlight_search (EvView *view, gboolean value)
+{
+       view->highlight_find_results = value;
+       gtk_widget_queue_draw (GTK_WIDGET (view));
+}
+
 /*** Selections ***/
 
 /* compute_new_selection_rect/text calculates the area currently selected by
@@ -4973,9 +5100,10 @@ gdk_rectangle_point_in (GdkRectangle *rectangle,
 }
 
 static GList *
-compute_new_selection_text (EvView   *view,
-                           GdkPoint *start,
-                           GdkPoint *stop)
+compute_new_selection_text (EvView          *view,
+                           EvSelectionStyle style,
+                           GdkPoint        *start,
+                           GdkPoint        *stop)
 {
        int n_pages, i, first, last;
        GList *list = NULL;
@@ -5030,6 +5158,7 @@ compute_new_selection_text (EvView   *view,
 
                selection = g_new0 (EvViewSelection, 1);
                selection->page = i;
+               selection->style = style;
                selection->rect.x1 = selection->rect.y1 = 0;
                selection->rect.x2 = width;
                selection->rect.y2 = height;
@@ -5187,16 +5316,17 @@ merge_selection_region (EvView *view,
 }
 
 static void
-compute_selections (EvView   *view,
-                   GdkPoint *start,
-                   GdkPoint *stop)
+compute_selections (EvView          *view,
+                   EvSelectionStyle style,
+                   GdkPoint        *start,
+                   GdkPoint        *stop)
 {
        GList *list;
 
        if (view->selection_mode == EV_VIEW_SELECTION_RECTANGLE)
                list = compute_new_selection_rect (view, start, stop);
        else
-               list = compute_new_selection_text (view, start, stop);
+               list = compute_new_selection_text (view, style, start, stop);
        merge_selection_region (view, list);
 }
 
@@ -5221,10 +5351,10 @@ clear_selection (EvView *view)
        g_object_notify (G_OBJECT (view), "has-selection");
 }
 
-
 void
 ev_view_select_all (EvView *view)
 {
+       GList *selections = NULL;
        int n_pages, i;
 
        /* Disable selection on rotated pages for the 0.4.0 series */
@@ -5232,7 +5362,7 @@ ev_view_select_all (EvView *view)
                return;
 
        clear_selection (view);
-
+       
        n_pages = ev_page_cache_get_n_pages (view->page_cache);
        for (i = 0; i < n_pages; i++) {
                int width, height;
@@ -5245,15 +5375,15 @@ ev_view_select_all (EvView *view)
 
                selection = g_new0 (EvViewSelection, 1);
                selection->page = i;
+               selection->style = EV_SELECTION_STYLE_GLYPH;
                selection->rect.x1 = selection->rect.y1 = 0;
                selection->rect.x2 = width;
                selection->rect.y2 = height;
 
-               view->selection_info.selections = g_list_append (view->selection_info.selections, selection);
+               selections = g_list_append (selections, selection);
        }
 
-       ev_pixbuf_cache_set_selection_list (view->pixbuf_cache, view->selection_info.selections);
-       g_object_notify (G_OBJECT (view), "has-selection");
+       merge_selection_region (view, selections);
        gtk_widget_queue_draw (GTK_WIDGET (view));
 }
 
@@ -5264,29 +5394,35 @@ ev_view_get_has_selection (EvView *view)
 }
 
 static char *
-get_selected_text (EvView *ev_view)
+get_selected_text (EvView *view)
 {
        GString *text;
        GList *l;
        gchar *normalized_text;
+       EvRenderContext *rc;
 
        text = g_string_new (NULL);
+       rc = ev_render_context_new (view->rotation, 1, view->scale);
 
        ev_document_doc_mutex_lock ();
 
-       for (l = ev_view->selection_info.selections; l != NULL; l = l->next) {
+       for (l = view->selection_info.selections; l != NULL; l = l->next) {
                EvViewSelection *selection = (EvViewSelection *)l->data;
-               char *tmp;
+               gchar *tmp;
+
+               ev_render_context_set_page (rc, selection->page);
+               tmp = ev_selection_get_selected_text (EV_SELECTION (view->document),
+                                                     rc, selection->style,
+                                                     &(selection->rect));
 
-               tmp = ev_document_get_text (ev_view->document,
-                                           selection->page,
-                                           &selection->rect);
                g_string_append (text, tmp);
                g_free (tmp);
        }
 
        ev_document_doc_mutex_unlock ();
 
+       g_object_unref (rc);
+       
        normalized_text = g_utf8_normalize (text->str, text->len, G_NORMALIZE_NFKC);
        g_string_free (text, TRUE);
        return normalized_text;
@@ -5298,9 +5434,8 @@ ev_view_copy (EvView *ev_view)
        GtkClipboard *clipboard;
        char *text;
 
-       if (!ev_document_can_get_text (ev_view->document)) {
+       if (!EV_IS_SELECTION (ev_view->document))
                return;
-       }
 
        text = get_selected_text (ev_view);
        clipboard = gtk_widget_get_clipboard (GTK_WIDGET (ev_view),
@@ -5318,9 +5453,8 @@ ev_view_primary_get_cb (GtkClipboard     *clipboard,
        EvView *ev_view = EV_VIEW (data);
        char *text;
 
-       if (!ev_document_can_get_text (ev_view->document)) {
+       if (!EV_IS_SELECTION (ev_view->document))
                return;
-       }
 
        text = get_selected_text (ev_view);
        if (text) {
@@ -5564,3 +5698,37 @@ ev_scroll_type_get_type (void)
   }
   return etype;
 }
+
+void
+ev_view_update_view_size (EvView *view, GtkScrolledWindow * scrolled_window)
+{
+       int width, height;
+       GtkRequisition vsb_requisition;
+       GtkRequisition hsb_requisition;
+       int scrollbar_spacing;
+       
+       /* Calculate the width available for the content */ 
+       width  = GTK_WIDGET (scrolled_window)->allocation.width;
+       height = GTK_WIDGET (scrolled_window)->allocation.height;
+
+       if (gtk_scrolled_window_get_shadow_type (scrolled_window) == GTK_SHADOW_IN 
+           && view) {
+               width -=  2 * GTK_WIDGET(view)->style->xthickness;
+               height -= 2 * GTK_WIDGET(view)->style->ythickness;
+       }
+
+       gtk_widget_size_request (scrolled_window->vscrollbar, &vsb_requisition);
+       gtk_widget_size_request (scrolled_window->hscrollbar, &hsb_requisition);
+       gtk_widget_style_get (GTK_WIDGET (scrolled_window), 
+                             "scrollbar_spacing", 
+                             &scrollbar_spacing, 
+                             NULL);
+       
+       if (EV_IS_VIEW(view)) {
+               ev_view_set_zoom_for_size (EV_VIEW (view),
+                                          MAX (1, width),
+                                          MAX (1, height),
+                                          vsb_requisition.width + scrollbar_spacing,
+                                          hsb_requisition.height + scrollbar_spacing);
+       }
+}