X-Git-Url: https://www.fi.muni.cz/~kas/git//home/kas/public_html/git/?a=blobdiff_plain;f=shell%2Fev-view.c;h=15bd41244edcf10215eae5d720374955b0372632;hb=85c366bda9f25b1249ba8333604eb3e757bc6edf;hp=612ffc5cf2f7995b913b60214d6b9c3c7115b115;hpb=064a924a0f06b6cca264bfdef530311da2bac1c8;p=evince.git diff --git a/shell/ev-view.c b/shell/ev-view.c index 612ffc5c..15bd4124 100644 --- a/shell/ev-view.c +++ b/shell/ev-view.c @@ -60,6 +60,7 @@ enum { enum { SIGNAL_BINDING_ACTIVATED, SIGNAL_ZOOM_INVALID, + SIGNAL_EXTERNAL_LINK, N_SIGNALS, }; @@ -188,6 +189,8 @@ struct _EvViewClass { GtkScrollType scroll, gboolean horizontal); void (*zoom_invalid) (EvView *view); + void (*external_link) (EvView *view, + EvLink *link); }; /*** Scrolling ***/ @@ -327,6 +330,11 @@ static double zoom_for_size_fit_width (int doc_width, int target_width, int target_height, int vsb_width); +static double zoom_for_size_fit_height (int doc_width, + int doc_height, + int target_width, + int target_height, + int vsb_height); static double zoom_for_size_best_fit (int doc_width, int doc_height, int target_width, @@ -1072,6 +1080,18 @@ location_in_text (EvView *view, return FALSE; } +static int +ev_view_get_width (EvView *view) +{ + return GTK_WIDGET (view)->allocation.width; +} + +static int +ev_view_get_height (EvView *view) +{ + return GTK_WIDGET (view)->allocation.height; +} + /*** Hyperref ***/ static EvLink * get_link_at_location (EvView *view, @@ -1096,24 +1116,98 @@ get_link_at_location (EvView *view, } static void -goto_fith_link (EvView *view, EvLink *link) +goto_fitr_link (EvView *view, EvLink *link) { GdkPoint view_point; EvPoint doc_point; - int height, page; + int doc_width, doc_height, page; + double zoom; page = ev_link_get_page (link); - ev_page_cache_get_size (view->page_cache, page, 0, 1.0, NULL, &height); + ev_page_cache_get_size (view->page_cache, page, 0, 1.0, &doc_width, &doc_height); + + doc_point.x = ev_link_get_left (link); + doc_point.y = ev_link_get_top (link); + doc_point_to_view_point (view, page, &doc_point, &view_point); + + zoom = zoom_for_size_best_fit (ev_link_get_right (link) - ev_link_get_left (link), + ev_link_get_top (link) - ev_link_get_bottom (link), + ev_view_get_width (view), + ev_view_get_height (view), 0, 0); + + ev_view_set_sizing_mode (view, EV_SIZING_FREE); + ev_view_set_zoom (view, zoom, FALSE); + ev_page_cache_set_current_page (view->page_cache, page); + gtk_adjustment_set_value (view->hadjustment, view_point.x); +} + +static void +goto_fitv_link (EvView *view, EvLink *link) +{ + GdkPoint view_point; + EvPoint doc_point; + int doc_width, doc_height, page; + double zoom; - ev_view_set_sizing_mode (view, EV_SIZING_BEST_FIT); + page = ev_link_get_page (link); + ev_page_cache_get_size (view->page_cache, page, 0, 1.0, &doc_width, &doc_height); + + doc_point.x = ev_link_get_left (link); + doc_point.y = 0; + doc_point_to_view_point (view, page, &doc_point, &view_point); + + zoom = zoom_for_size_fit_height (doc_width - doc_point.x , doc_height, + ev_view_get_width (view), + ev_view_get_height (view), 0); + + ev_view_set_sizing_mode (view, EV_SIZING_FREE); + ev_view_set_zoom (view, zoom, FALSE); + ev_page_cache_set_current_page (view->page_cache, page); + gtk_adjustment_set_value (view->hadjustment, view_point.x); +} + +static void +goto_fith_link (EvView *view, EvLink *link) +{ + GdkPoint view_point; + EvPoint doc_point; + int doc_width, doc_height, page; + double zoom; + + page = ev_link_get_page (link); + ev_page_cache_get_size (view->page_cache, page, 0, 1.0, &doc_width, &doc_height); doc_point.x = 0; - doc_point.y = height - ev_link_get_top (link); + doc_point.y = doc_height - ev_link_get_top (link); doc_point_to_view_point (view, page, &doc_point, &view_point); + zoom = zoom_for_size_fit_width (doc_width, ev_link_get_top (link), + ev_view_get_width (view), + ev_view_get_height (view), 0); + + ev_view_set_sizing_mode (view, EV_SIZING_FREE); + ev_view_set_zoom (view, zoom, FALSE); gtk_adjustment_set_value (view->vadjustment, view_point.y); } +static void +goto_fit_link (EvView *view, EvLink *link) +{ + double zoom; + int doc_width, doc_height; + int page; + + page = ev_link_get_page (link); + ev_page_cache_get_size (view->page_cache, page, 0, 1.0, &doc_width, &doc_height); + + zoom = zoom_for_size_best_fit (doc_width, doc_height, ev_view_get_width (view), + ev_view_get_height (view), 0, 0); + + ev_view_set_sizing_mode (view, EV_SIZING_FREE); + ev_view_set_zoom (view, zoom, FALSE); + ev_page_cache_set_current_page (view->page_cache, page); +} + static void goto_xyz_link (EvView *view, EvLink *link) { @@ -1143,7 +1237,6 @@ void ev_view_goto_link (EvView *view, EvLink *link) { EvLinkType type; - const char *uri; int page; type = ev_link_get_link_type (link); @@ -1156,19 +1249,23 @@ ev_view_goto_link (EvView *view, EvLink *link) ev_page_cache_set_current_page (view->page_cache, page); break; case EV_LINK_TYPE_PAGE_FIT: - page = ev_link_get_page (link); - ev_page_cache_set_current_page (view->page_cache, page); - ev_view_set_sizing_mode (view, EV_SIZING_BEST_FIT); + goto_fit_link (view, link); break; case EV_LINK_TYPE_PAGE_FITH: goto_fith_link (view, link); break; + case EV_LINK_TYPE_PAGE_FITV: + goto_fitv_link (view, link); + break; + case EV_LINK_TYPE_PAGE_FITR: + goto_fitr_link (view, link); + break; case EV_LINK_TYPE_PAGE_XYZ: goto_xyz_link (view, link); break; case EV_LINK_TYPE_EXTERNAL_URI: - uri = ev_link_get_uri (link); - gnome_vfs_url_show (uri); + case EV_LINK_TYPE_LAUNCH: + g_signal_emit (view, signals[SIGNAL_EXTERNAL_LINK], 0, link); break; } } @@ -1396,7 +1493,7 @@ ev_view_size_allocate (GtkWidget *widget, EvView *view = EV_VIEW (widget); if (view->sizing_mode == EV_SIZING_FIT_WIDTH || - view->sizing_mode == EV_SIZING_BEST_FIT) { + view->sizing_mode == EV_SIZING_BEST_FIT) { g_signal_emit (view, signals[SIGNAL_ZOOM_INVALID], 0); @@ -2193,6 +2290,14 @@ ev_view_class_init (EvViewClass *class) NULL, NULL, ev_marshal_VOID__VOID, G_TYPE_NONE, 0, G_TYPE_NONE); + signals[SIGNAL_EXTERNAL_LINK] = g_signal_new ("external-link", + G_TYPE_FROM_CLASS (object_class), + G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, + G_STRUCT_OFFSET (EvViewClass, external_link), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, + G_TYPE_OBJECT); g_object_class_install_property (object_class, PROP_STATUS, @@ -2704,6 +2809,23 @@ zoom_for_size_fit_width (int doc_width, return scale; } +static double +zoom_for_size_fit_height (int doc_width, + int doc_height, + int target_width, + int target_height, + int vsb_height) +{ + double scale; + + scale = (double)target_height / doc_height; + + if (doc_width * scale > target_width) + scale = (double) (target_height - vsb_height) / doc_height; + + return scale; +} + static double zoom_for_size_best_fit (int doc_width, int doc_height,