X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?a=blobdiff_plain;ds=inline;f=shell%2Fev-view.c;h=815f69d99ddd76437be1bb185203039b12506c24;hb=cca6f560c79ff1a30b23c08b9918a77876b69d13;hp=9c01ca6eb0b686ed1b8cf9608521389d5f04d1f3;hpb=d3b9665412c1368abbe96453010efec923160de5;p=evince.git diff --git a/shell/ev-view.c b/shell/ev-view.c index 9c01ca6e..815f69d9 100644 --- a/shell/ev-view.c +++ b/shell/ev-view.c @@ -42,6 +42,7 @@ #define EV_IS_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EV_TYPE_VIEW)) #define EV_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EV_TYPE_VIEW, EvViewClass)) + enum { PROP_0, PROP_STATUS, @@ -52,6 +53,7 @@ enum { PROP_PRESENTATION, PROP_SIZING_MODE, PROP_ZOOM, + PROP_ROTATION, }; enum { @@ -86,6 +88,11 @@ typedef enum { EV_VIEW_CURSOR_DRAG } EvViewCursor; +typedef enum { + EV_VIEW_FIND_NEXT, + EV_VIEW_FIND_PREV +} EvViewFindDirection; + #define ZOOM_IN_FACTOR 1.2 #define ZOOM_OUT_FACTOR (1.0/ZOOM_IN_FACTOR) @@ -230,8 +237,6 @@ static void find_page_at_location (EvView gint *page, gint *x_offset, gint *y_offset); -static void ev_view_queue_draw_page (EvView *view, - gint page); /*** Hyperrefs ***/ static EvLink* get_link_at_location (EvView *view, @@ -360,7 +365,8 @@ static void ev_view_set_find_status (EvView const char *message); /*** Find ***/ static void jump_to_find_result (EvView *view); -static void jump_to_find_page (EvView *view); +static void jump_to_find_page (EvView *view, + EvViewFindDirection direction); /*** Selection ***/ static void compute_selections (EvView *view, @@ -483,6 +489,9 @@ view_set_adjustment_values (EvView *view, static void view_update_range_and_current_page (EvView *view) { + if (view->pending_scroll != SCROLL_TO_KEEP_POSITION) + return; + /* Presentation trumps all other modes */ if (view->presentation) { view->start_page = view->current_page; @@ -813,8 +822,8 @@ get_page_extents (EvView *view, gint max_width; gint x, y; - ev_page_cache_get_max_width (view->page_cache, view->scale, - view->rotation, &max_width); + ev_page_cache_get_max_width (view->page_cache, view->rotation, + view->scale, &max_width); max_width = max_width + border->left + border->right; /* Get the location of the bounding box */ if (view->dual_page) { @@ -997,14 +1006,6 @@ find_page_at_location (EvView *view, *page = -1; } -static void -ev_view_queue_draw_page (EvView *view, - gint page) -{ - /* FIXME: write */ - gtk_widget_queue_draw (GTK_WIDGET (view)); -} - static gboolean location_in_text (EvView *view, gdouble x, @@ -1465,15 +1466,20 @@ ev_view_motion_notify_event (GtkWidget *widget, if (!view->document) return FALSE; - if (view->pressed_button == 1) { + /* For the Evince 0.4.x release, we limit selection to un-rotated + * documents only. + */ + if (view->pressed_button == 1 && + view->rotation == 0) { view->selection_info.in_selection = TRUE; view->motion_x = event->x + view->scroll_x; view->motion_y = event->y + view->scroll_y; /* Queue an idle to handle the motion. We do this because - * handling any selection events in the motion is probably going - * to be slower than new motion events reach us. This means that */ - + * handling any selection events in the motion could be slower + * than new motion events reach us. We always put it in the + * idle to make sure we catch up and don't visibly lag the + * mouse. */ if (! view->selection_update_id) view->selection_update_id = g_idle_add ((GSourceFunc)selection_update_idle_cb, view); @@ -1514,7 +1520,11 @@ ev_view_motion_notify_event (GtkWidget *widget, return TRUE; } - } else if (view->pressed_button <= 0) { + /* For the Evince 0.4.x release, we limit links to un-rotated documents + * only. + */ + } else if (view->pressed_button <= 0 && + view->rotation == 0) { EvLink *link; link = get_link_at_location (view, event->x + view->scroll_x, event->y + view->scroll_y); @@ -1685,14 +1695,58 @@ highlight_find_results (EvView *view, int page) alpha = 0x20; } - ev_document_find_get_result (find, page, - i, &rectangle); + ev_document_find_get_result (find, page, i, &rectangle); doc_rect_to_view_rect (view, page, &rectangle, &view_rectangle); draw_rubberband (GTK_WIDGET (view), GTK_WIDGET(view)->window, &view_rectangle, alpha); } } +static void +draw_loading_text (EvView *view, + GdkRectangle *page_area, + GdkRectangle *expose_area) +{ + PangoLayout *layout; + PangoFontDescription *font_desc; + PangoRectangle logical_rect; + double real_scale; + int target_width; + + const char *loading_text = _("Loading..."); + + layout = gtk_widget_create_pango_layout (GTK_WIDGET (view), loading_text); + + font_desc = pango_font_description_new (); + + + /* We set the font to be 10 points, get the size, and scale appropriately */ + pango_font_description_set_size (font_desc, 10 * PANGO_SCALE); + pango_layout_set_font_description (layout, font_desc); + pango_layout_get_pixel_extents (layout, NULL, &logical_rect); + + /* Make sure we fit the middle of the page */ + target_width = MAX (page_area->width / 2, 1); + real_scale = ((double)target_width / (double) logical_rect.width) * (PANGO_SCALE * 10); + pango_font_description_set_size (font_desc, (int)real_scale); + pango_layout_set_font_description (layout, font_desc); + pango_layout_get_pixel_extents (layout, NULL, &logical_rect); + + gtk_paint_layout (GTK_WIDGET (view)->style, + GTK_WIDGET (view)->window, + GTK_WIDGET_STATE (view), + FALSE, + page_area, + GTK_WIDGET (view), + NULL, + page_area->x + (target_width/2), + page_area->y + (page_area->height - logical_rect.height) / 2, + layout); + + pango_font_description_free (font_desc); + g_object_unref (layout); +} + static void draw_one_page (EvView *view, gint page, @@ -1776,6 +1830,10 @@ draw_one_page (EvView *view, GDK_RGB_DITHER_NORMAL, 0, 0); g_object_unref (scaled_image); + } else { + draw_loading_text (view, + &real_page_area, + expose_area); } if (scaled_selection) { @@ -1856,6 +1914,9 @@ ev_view_set_property (GObject *object, case PROP_ZOOM: ev_view_set_zoom (view, g_value_get_double (value), FALSE); break; + case PROP_ROTATION: + ev_view_set_rotation (view, g_value_get_int (value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } @@ -1895,6 +1956,9 @@ ev_view_get_property (GObject *object, case PROP_ZOOM: g_value_set_double (value, view->scale); break; + case PROP_ROTATION: + g_value_set_int (value, view->rotation); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); } @@ -2023,6 +2087,15 @@ ev_view_class_init (EvViewClass *class) MAX_SCALE, 1.0, G_PARAM_READWRITE)); + g_object_class_install_property (object_class, + PROP_ROTATION, + g_param_spec_double ("rotation", + "Rotation", + "Rotation", + 0, + 360, + 0, + G_PARAM_READWRITE)); binding_set = gtk_binding_set_by_class (class); @@ -2059,7 +2132,7 @@ ev_view_init (EvView *view) static void find_changed_cb (EvDocument *document, int page, EvView *view) { - jump_to_find_page (view); + jump_to_find_page (view, EV_VIEW_FIND_NEXT); jump_to_find_result (view); update_find_status_message (view); @@ -2154,7 +2227,6 @@ clear_caches (EvView *view) } if (view->page_cache) { - g_object_unref (view->page_cache); view->page_cache = NULL; } } @@ -2399,15 +2471,6 @@ ev_view_zoom_out (EvView *view) ev_view_set_zoom (view, ZOOM_OUT_FACTOR, TRUE); } -static void -ev_view_set_rotation (EvView *view, int rotation) -{ - view->rotation = rotation; - - ev_pixbuf_cache_clear (view->pixbuf_cache); - gtk_widget_queue_resize (GTK_WIDGET (view)); -} - void ev_view_rotate_right (EvView *view) { @@ -2432,6 +2495,28 @@ ev_view_rotate_left (EvView *view) ev_view_set_rotation (view, rotation); } +void +ev_view_set_rotation (EvView *view, int rotation) +{ + view->rotation = rotation; + + if (view->pixbuf_cache) { + ev_pixbuf_cache_clear (view->pixbuf_cache); + gtk_widget_queue_resize (GTK_WIDGET (view)); + } + + if (rotation != 0) + clear_selection (view); + + g_object_notify (G_OBJECT (view), "rotation"); +} + +int +ev_view_get_rotation (EvView *view) +{ + return view->rotation; +} + static double zoom_for_size_fit_width (int doc_width, int doc_height, @@ -2762,7 +2847,7 @@ jump_to_find_result (EvView *view) n_results = ev_document_find_get_n_results (find, page); - if (n_results > view->find_result) { + if (n_results > 0 && view->find_result < n_results) { ev_document_find_get_result (find, page, view->find_result, &rect); @@ -2772,7 +2857,7 @@ jump_to_find_result (EvView *view) } static void -jump_to_find_page (EvView *view) +jump_to_find_page (EvView *view, EvViewFindDirection direction) { int n_pages, i; @@ -2781,12 +2866,19 @@ jump_to_find_page (EvView *view) for (i = 0; i < n_pages; i++) { int has_results; int page; + + if (direction == EV_VIEW_FIND_NEXT) + page = view->find_page + i; + else + page = view->find_page - i; + - page = i + view->find_page; if (page >= n_pages) { page = page - n_pages; } - + if (page < 0) + page = page + n_pages; + has_results = ev_document_find_page_has_results (EV_DOCUMENT_FIND (view->document), page); if (has_results == -1) { @@ -2794,7 +2886,6 @@ jump_to_find_page (EvView *view) break; } else if (has_results == 1) { ev_page_cache_set_current_page (view->page_cache, page); - jump_to_find_result (view); break; } } @@ -2827,14 +2918,15 @@ ev_view_find_next (EvView *view) view->find_result++; if (view->find_result >= n_results) { + view->find_result = 0; view->find_page++; - if (view->find_page >= n_pages) { view->find_page = 0; } - jump_to_find_page (view); + jump_to_find_page (view, EV_VIEW_FIND_NEXT); + jump_to_find_result (view); } else { jump_to_find_result (view); gtk_widget_queue_draw (GTK_WIDGET (view)); @@ -2857,14 +2949,15 @@ ev_view_find_previous (EvView *view) view->find_result--; if (view->find_result < 0) { - view->find_result = 0; - view->find_page--; + view->find_page--; if (view->find_page < 0) { view->find_page = n_pages - 1; } - jump_to_find_page (view); + jump_to_find_page (view, EV_VIEW_FIND_PREV); + view->find_result = ev_document_find_get_n_results (find, view->current_page) - 1; + jump_to_find_result (view); } else { jump_to_find_result (view); gtk_widget_queue_draw (GTK_WIDGET (view)); @@ -2936,6 +3029,7 @@ compute_new_selection_text (EvView *view, GList *list = NULL; EvViewSelection *selection; gint width, height; + int start_page, end_page; g_assert (view->selection_mode == EV_VIEW_SELECTION_TEXT); @@ -2945,7 +3039,18 @@ compute_new_selection_text (EvView *view, * affects. */ first = n_pages; last = 0; - for (i = 0; i < n_pages; i++) { + if (view->continuous) { + start_page = 0; + end_page = n_pages; + } else if (view->dual_page) { + start_page = view->start_page; + end_page = view->end_page + 1; + } else { + start_page = view->current_page; + end_page = view->current_page + 1; + } + + for (i = start_page; i < end_page; i++) { GdkRectangle page_area; GtkBorder border; @@ -3161,6 +3266,10 @@ ev_view_select_all (EvView *view) { int n_pages, i; + /* Disable selection on rotated pages for the 0.4.0 series */ + if (view->rotation != 0) + return; + clear_selection (view); n_pages = ev_page_cache_get_n_pages (view->page_cache);