X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?a=blobdiff_plain;ds=sidebyside;f=shell%2Fev-view.c;h=2edcd858cc9345566704aee3eed53eee2618ce94;hb=d24883d57ff3806d9c2002e8f800e9d69762c335;hp=b22b1f52545f2f4c65eb165720f58071ca0f6ef9;hpb=9a86f70f0cb42c4262e78430fd36f93baaac41e0;p=evince.git diff --git a/shell/ev-view.c b/shell/ev-view.c index b22b1f52..2edcd858 100644 --- a/shell/ev-view.c +++ b/shell/ev-view.c @@ -37,6 +37,7 @@ #include "ev-job-queue.h" #include "ev-page-cache.h" #include "ev-pixbuf-cache.h" +#include "ev-tooltip.h" #define EV_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EV_TYPE_VIEW, EvViewClass)) #define EV_IS_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EV_TYPE_VIEW)) @@ -53,6 +54,7 @@ enum { PROP_PRESENTATION, PROP_SIZING_MODE, PROP_ZOOM, + PROP_ROTATION, }; enum { @@ -147,6 +149,7 @@ struct _EvView { int pressed_button; EvViewCursor cursor; + GtkWidget *link_tooltip; EvPageCache *page_cache; EvPixbufCache *pixbuf_cache; @@ -236,8 +239,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, @@ -245,7 +246,7 @@ static EvLink* get_link_at_location (EvView gdouble y); static void go_to_link (EvView *view, EvLink *link); -static char* status_message_from_link (EvView *view, +static char* tip_from_link (EvView *view, EvLink *link); /*** GtkWidget implementation ***/ @@ -1007,14 +1008,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, @@ -1085,7 +1078,7 @@ go_to_link (EvView *view, EvLink *link) } static char * -status_message_from_link (EvView *view, EvLink *link) +tip_from_link (EvView *view, EvLink *link) { EvLinkType type; char *msg = NULL; @@ -1475,15 +1468,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); @@ -1524,17 +1522,31 @@ 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); + + if (!link && view->link_tooltip) { + ev_tooltip_deactivate (EV_TOOLTIP (view->link_tooltip)); + } + if (link) { - char *msg; + char *msg = tip_from_link (view, link); - msg = status_message_from_link (view, link); - ev_view_set_status (view, msg); - ev_view_set_cursor (view, EV_VIEW_CURSOR_LINK); + if (view->link_tooltip == NULL) { + view->link_tooltip = ev_tooltip_new (GTK_WIDGET (view)); + } + ev_tooltip_set_position (EV_TOOLTIP (view->link_tooltip), event->x, event->y); + ev_tooltip_set_text (EV_TOOLTIP (view->link_tooltip), msg); + ev_tooltip_activate (EV_TOOLTIP (view->link_tooltip)); g_free (msg); + + ev_view_set_cursor (view, EV_VIEW_CURSOR_LINK); } else if (location_in_text (view, event->x + view->scroll_x, event->y + view->scroll_y)) { ev_view_set_cursor (view, EV_VIEW_CURSOR_IBEAM); } else { @@ -1695,14 +1707,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, @@ -1786,6 +1842,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) { @@ -1833,6 +1893,11 @@ ev_view_destroy (GtkObject *object) g_object_unref (view->pixbuf_cache); view->pixbuf_cache = NULL; } + if (view->link_tooltip) { + gtk_widget_destroy (view->link_tooltip); + view->link_tooltip = NULL; + } + ev_view_set_scroll_adjustments (view, NULL, NULL); GTK_OBJECT_CLASS (ev_view_parent_class)->destroy (object); @@ -1866,6 +1931,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); } @@ -1905,6 +1973,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); } @@ -2033,6 +2104,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); @@ -2164,7 +2244,6 @@ clear_caches (EvView *view) } if (view->page_cache) { - g_object_unref (view->page_cache); view->page_cache = NULL; } } @@ -2409,15 +2488,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) { @@ -2442,6 +2512,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, @@ -2954,6 +3046,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); @@ -2963,7 +3056,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; @@ -3179,6 +3283,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);