]> www.fi.muni.cz Git - evince.git/blobdiff - libview/ev-view.c
[Bug 603857] Typo in EV_RENDER_CONTEXT
[evince.git] / libview / ev-view.c
index effbd362e0eb44af5f2b979df543e8a4379540ca..8a5ac5f85ebf21e5f428f33f84e205143a141475 100644 (file)
@@ -480,6 +480,37 @@ ev_view_get_height_to_page (EvView *view,
                *dual_height = (gint)(dh * view->scale + 0.5);
 }
 
+static gint
+ev_view_get_scrollbar_size (EvView        *view,
+                           GtkOrientation orientation)
+{
+       GtkWidget *widget = GTK_WIDGET (view);
+       GtkWidget *sb;
+       GtkWidget *swindow = gtk_widget_get_parent (GTK_WIDGET (view));
+       GtkRequisition req;
+       gint spacing;
+
+       if (!GTK_IS_SCROLLED_WINDOW (swindow))
+               return 0;
+
+       if (orientation == GTK_ORIENTATION_VERTICAL) {
+               if (widget->allocation.height >= widget->requisition.height)
+                       sb = gtk_scrolled_window_get_vscrollbar (GTK_SCROLLED_WINDOW (swindow));
+               else
+                       return 0;
+       } else {
+               if (widget->allocation.width >= widget->requisition.width)
+                       sb = gtk_scrolled_window_get_hscrollbar (GTK_SCROLLED_WINDOW (swindow));
+               else
+                       return 0;
+       }
+
+       gtk_widget_style_get (swindow, "scrollbar_spacing", &spacing, NULL);
+       gtk_widget_size_request (sb, &req);
+
+       return (orientation == GTK_ORIENTATION_VERTICAL ? req.width : req.height) + spacing;
+}
+
 static void
 scroll_to_point (EvView        *view,
                 gdouble        x,
@@ -622,13 +653,13 @@ view_update_range_and_current_page (EvView *view)
                gboolean found = FALSE;
                gint area_max = -1, area;
                gint best_current_page = -1;
-               int i;
+               int i, j = 0;
 
                if (!(view->vadjustment && view->hadjustment))
                        return;
 
                current_area.x = view->hadjustment->value;
-               current_area.width = view->hadjustment->upper;
+               current_area.width = view->hadjustment->page_size;
                current_area.y = view->vadjustment->value;
                current_area.height = view->vadjustment->page_size;
 
@@ -651,7 +682,15 @@ view_update_range_and_current_page (EvView *view)
                                }
 
                                view->end_page = i;
+                               j = 0;
                        } else if (found && view->current_page <= view->end_page) {
+                               if (view->dual_page && j < 1) {
+                                       /* In dual mode  we stop searching
+                                        * after two consecutive non-visible pages.
+                                        */
+                                       j++;
+                                       continue;
+                               }
                                break;
                        }
                }
@@ -2745,25 +2784,28 @@ static void
 ev_view_size_request_continuous_dual_page (EvView         *view,
                                           GtkRequisition *requisition)
 {
-       int max_width;
        gint n_pages;
-       GtkBorder border;
-
-       ev_view_get_max_page_size (view, &max_width, NULL);
-       compute_border (view, max_width, max_width, &border);
 
        n_pages = ev_document_get_n_pages (view->document) + 1;
-
-       requisition->width = (max_width + border.left + border.right) * 2 + (view->spacing * 3);
        get_page_y_offset (view, n_pages, &requisition->height);
 
-       if (view->sizing_mode == EV_SIZING_FIT_WIDTH) {
-               requisition->width = 1;
-       } else if (view->sizing_mode == EV_SIZING_BEST_FIT) {
-               requisition->width = 1;
-               /* FIXME: This could actually be set on one page docs or docs
-                * with a strange aspect ratio. */
-               /* requisition->height = 1;*/
+       switch (view->sizing_mode) {
+               case EV_SIZING_FIT_WIDTH:
+               case EV_SIZING_BEST_FIT:
+                       requisition->width = 1;
+
+                       break;
+               case EV_SIZING_FREE: {
+                       gint max_width;
+                       GtkBorder border;
+
+                       ev_view_get_max_page_size (view, &max_width, NULL);
+                       compute_border (view, max_width, max_width, &border);
+                       requisition->width = (max_width + border.left + border.right) * 2 + (view->spacing * 3);
+               }
+                       break;
+               default:
+                       g_assert_not_reached ();
        }
 }
 
@@ -2771,24 +2813,28 @@ static void
 ev_view_size_request_continuous (EvView         *view,
                                 GtkRequisition *requisition)
 {
-       int max_width;
-       int n_pages;
-       GtkBorder border;
+       gint n_pages;
 
-       ev_view_get_max_page_size (view, &max_width, NULL);
        n_pages = ev_document_get_n_pages (view->document);
-       compute_border (view, max_width, max_width, &border);
-
-       requisition->width = max_width + (view->spacing * 2) + border.left + border.right;
        get_page_y_offset (view, n_pages, &requisition->height);
 
-       if (view->sizing_mode == EV_SIZING_FIT_WIDTH) {
-               requisition->width = 1;
-       } else if (view->sizing_mode == EV_SIZING_BEST_FIT) {
-               requisition->width = 1;
-               /* FIXME: This could actually be set on one page docs or docs
-                * with a strange aspect ratio. */
-               /* requisition->height = 1;*/
+       switch (view->sizing_mode) {
+               case EV_SIZING_FIT_WIDTH:
+               case EV_SIZING_BEST_FIT:
+                       requisition->width = 1;
+
+                       break;
+               case EV_SIZING_FREE: {
+                       gint max_width;
+                       GtkBorder border;
+
+                       ev_view_get_max_page_size (view, &max_width, NULL);
+                       compute_border (view, max_width, max_width, &border);
+                       requisition->width = max_width + (view->spacing * 2) + border.left + border.right;
+               }
+                       break;
+               default:
+                       g_assert_not_reached ();
        }
 }
 
@@ -2799,6 +2845,13 @@ ev_view_size_request_dual_page (EvView         *view,
        GtkBorder border;
        gint width, height;
 
+       if (view->sizing_mode == EV_SIZING_BEST_FIT) {
+               requisition->width = 1;
+               requisition->height = 1;
+
+               return;
+       }
+
        /* Find the largest of the two. */
        ev_view_get_page_size (view,
                               view->current_page,
@@ -2815,17 +2868,9 @@ ev_view_size_request_dual_page (EvView         *view,
        }
        compute_border (view, width, height, &border);
 
-       requisition->width = ((width + border.left + border.right) * 2) +
-               (view->spacing * 3);
-       requisition->height = (height + border.top + border.bottom) +
-               (view->spacing * 2);
-
-       if (view->sizing_mode == EV_SIZING_FIT_WIDTH) {
-               requisition->width = 1;
-       } else if (view->sizing_mode == EV_SIZING_BEST_FIT) {
-               requisition->width = 1;
-               requisition->height = 1;
-       }
+       requisition->width = view->sizing_mode == EV_SIZING_FIT_WIDTH ? 1 :
+               ((width + border.left + border.right) * 2) + (view->spacing * 3);
+       requisition->height = (height + border.top + border.bottom) + (view->spacing * 2);
 }
 
 static void
@@ -2835,19 +2880,19 @@ ev_view_size_request_single_page (EvView         *view,
        GtkBorder border;
        gint width, height;
 
+       if (view->sizing_mode == EV_SIZING_BEST_FIT) {
+               requisition->width = 1;
+               requisition->height = 1;
+
+               return;
+       }
+
        ev_view_get_page_size (view, view->current_page, &width, &height);
        compute_border (view, width, height, &border);
 
-       requisition->width = width + border.left + border.right + (2 * view->spacing);
+       requisition->width = view->sizing_mode == EV_SIZING_FIT_WIDTH ? 1 :
+               width + border.left + border.right + (2 * view->spacing);
        requisition->height = height + border.top + border.bottom + (2 * view->spacing);
-
-       if (view->sizing_mode == EV_SIZING_FIT_WIDTH) {
-               requisition->width = 1;
-               requisition->height = height + border.top + border.bottom + (2 * view->spacing);
-       } else if (view->sizing_mode == EV_SIZING_BEST_FIT) {
-               requisition->width = 1;
-               requisition->height = 1;
-       }
 }
 
 static void
@@ -3008,8 +3053,7 @@ ev_view_scroll_event (GtkWidget *widget, GdkEventScroll *event)
        state = event->state & gtk_accelerator_get_default_mod_mask ();
 
        if (state == GDK_CONTROL_MASK && view->presentation == FALSE) {
-               ev_view_set_sizing_mode (view, EV_SIZING_FREE);
-
+               ev_document_model_set_sizing_mode (view->model, EV_SIZING_FREE);
                if (event->direction == GDK_SCROLL_UP ||
                    event->direction == GDK_SCROLL_LEFT) {
                        if (ev_view_can_zoom_in (view)) {
@@ -3209,8 +3253,9 @@ ev_view_do_popup_menu (EvView *view,
                       gdouble x,
                       gdouble y)
 {
-       EvLink  *link;
-       EvImage *image;
+       EvLink       *link;
+       EvImage      *image;
+       EvAnnotation *annot;
 
        image = ev_view_get_image_at_location (view, x, y);
        if (image) {
@@ -3224,6 +3269,12 @@ ev_view_do_popup_menu (EvView *view,
                return TRUE;
        }
 
+       annot = ev_view_get_annotation_at_location (view, x, y);
+       if (annot) {
+               g_signal_emit (view, signals[SIGNAL_POPUP_MENU], 0, annot);
+               return TRUE;
+       }
+
        g_signal_emit (view, signals[SIGNAL_POPUP_MENU], 0, NULL);
 
        return TRUE;
@@ -5052,8 +5103,12 @@ ev_view_new (void)
 static void
 setup_caches (EvView *view)
 {
+       gboolean inverted_colors;
+
        view->height_to_page_cache = ev_view_get_height_to_page_cache (view);
        view->pixbuf_cache = ev_pixbuf_cache_new (GTK_WIDGET (view), view->document);
+       inverted_colors = ev_document_model_get_inverted_colors (view->model);
+       ev_pixbuf_cache_set_inverted_colors (view->pixbuf_cache, inverted_colors);
        g_signal_connect (view->pixbuf_cache, "job-finished", G_CALLBACK (job_finished_cb), view);
 }
 
@@ -5157,6 +5212,8 @@ ev_view_document_changed_cb (EvDocumentModel *model,
        view->loading = FALSE;
 
        if (document != view->document) {
+               gint current_page;
+
                clear_caches (view);
 
                if (view->document) {
@@ -5171,9 +5228,13 @@ ev_view_document_changed_cb (EvDocumentModel *model,
                        setup_caches (view);
                 }
 
-               ev_view_change_page (view,
-                                    ev_document_model_get_page (model),
-                                    TRUE);
+               current_page = ev_document_model_get_page (model);
+               if (view->current_page != current_page) {
+                       ev_view_change_page (view, current_page, TRUE);
+               } else {
+                       view->pending_scroll = SCROLL_TO_KEEP_POSITION;
+                       gtk_widget_queue_resize (GTK_WIDGET (view));
+               }
        }
 }
 
@@ -5199,6 +5260,20 @@ ev_view_rotation_changed_cb (EvDocumentModel *model,
                clear_selection (view);
 }
 
+static void
+ev_view_inverted_colors_changed_cb (EvDocumentModel *model,
+                                   GParamSpec      *pspec,
+                                   EvView          *view)
+{
+       if (view->pixbuf_cache) {
+               gboolean inverted_colors;
+
+               inverted_colors = ev_document_model_get_inverted_colors (model);
+               ev_pixbuf_cache_set_inverted_colors (view->pixbuf_cache, inverted_colors);
+               gtk_widget_queue_draw (GTK_WIDGET (view));
+       }
+}
+
 static void
 ev_view_sizing_mode_changed_cb (EvDocumentModel *model,
                                GParamSpec      *pspec,
@@ -5231,7 +5306,8 @@ ev_view_scale_changed_cb (EvDocumentModel *model,
        ev_view_set_zoom (view, scale);
 
        view->pending_resize = TRUE;
-       gtk_widget_queue_resize (GTK_WIDGET (view));
+       if (view->sizing_mode == EV_SIZING_FREE)
+               gtk_widget_queue_resize (GTK_WIDGET (view));
 }
 
 static void
@@ -5298,6 +5374,9 @@ ev_view_set_model (EvView          *view,
        g_signal_connect (view->model, "notify::rotation",
                          G_CALLBACK (ev_view_rotation_changed_cb),
                          view);
+       g_signal_connect (view->model, "notify::inverted-colors",
+                         G_CALLBACK (ev_view_inverted_colors_changed_cb),
+                         view);
        g_signal_connect (view->model, "notify::sizing-mode",
                          G_CALLBACK (ev_view_sizing_mode_changed_cb),
                          view);
@@ -5431,7 +5510,7 @@ ev_view_set_presentation (EvView   *view,
        if (presentation) {
                view->sizing_mode_saved = view->sizing_mode;
                view->scale_saved = view->scale;
-               ev_view_set_sizing_mode (view, EV_SIZING_BEST_FIT);
+               ev_document_model_set_sizing_mode (view->model, EV_SIZING_BEST_FIT);
        } else {
                ev_document_model_set_sizing_mode (view->model, view->sizing_mode_saved);
                ev_document_model_set_scale (view->model, view->scale_saved);
@@ -5585,14 +5664,7 @@ zoom_for_size_fit_width (gdouble doc_width,
                         int     target_width,
                         int     target_height)
 {
-       double scale;
-
-       scale = (double)target_width / doc_width;
-
-       if (doc_height * scale > target_height)
-               scale = (double)target_width / doc_width;
-
-       return scale;
+       return (double)target_width / doc_width;
 }
 
 static double
@@ -5601,14 +5673,7 @@ zoom_for_size_fit_height (gdouble doc_width,
                          int     target_width,
                          int     target_height)
 {
-       double scale;
-
-       scale = (double)target_height / doc_height;
-
-       if (doc_width * scale > target_width)
-               scale = (double)target_height / doc_height;
-
-       return scale;
+       return (double)target_height / doc_height;
 }
 
 static double
@@ -5623,11 +5688,6 @@ zoom_for_size_best_fit (gdouble doc_width,
        w_scale = (double)target_width / doc_width;
        h_scale = (double)target_height / doc_height;
 
-       if (doc_height * w_scale > target_height)
-               w_scale = (double)target_width / doc_width;
-       if (doc_width * h_scale > target_width)
-               h_scale = (double)target_height / doc_height;
-
        return MIN (w_scale, h_scale);
 }
 
@@ -5669,9 +5729,12 @@ ev_view_zoom_for_size_continuous_and_dual_page (EvView *view,
        width -= (2 * (border.left + border.right) + 3 * view->spacing);
        height -= (border.top + border.bottom + 2 * view->spacing - 1);
 
-       if (view->sizing_mode == EV_SIZING_FIT_WIDTH)
-               scale = zoom_for_size_fit_width (doc_width, doc_height, width, height);
-       else if (view->sizing_mode == EV_SIZING_BEST_FIT)
+       if (view->sizing_mode == EV_SIZING_FIT_WIDTH) {
+               gint sb_size;
+
+               sb_size = ev_view_get_scrollbar_size (view, GTK_ORIENTATION_VERTICAL);
+               scale = zoom_for_size_fit_width (doc_width, doc_height, width - sb_size, height);
+       } else if (view->sizing_mode == EV_SIZING_BEST_FIT)
                scale = zoom_for_size_best_fit (doc_width, doc_height, width, height);
        else
                g_assert_not_reached ();
@@ -5702,9 +5765,12 @@ ev_view_zoom_for_size_continuous (EvView *view,
        width -= (border.left + border.right + 2 * view->spacing);
        height -= (border.top + border.bottom + 2 * view->spacing - 1);
 
-       if (view->sizing_mode == EV_SIZING_FIT_WIDTH)
-               scale = zoom_for_size_fit_width (doc_width, doc_height, width, height);
-       else if (view->sizing_mode == EV_SIZING_BEST_FIT)
+       if (view->sizing_mode == EV_SIZING_FIT_WIDTH) {
+               gint sb_size;
+
+               sb_size = ev_view_get_scrollbar_size (view, GTK_ORIENTATION_VERTICAL);
+               scale = zoom_for_size_fit_width (doc_width, doc_height, width - sb_size, height);
+       } else if (view->sizing_mode == EV_SIZING_BEST_FIT)
                scale = zoom_for_size_best_fit (doc_width, doc_height, width, height);
        else
                g_assert_not_reached ();
@@ -5741,9 +5807,12 @@ ev_view_zoom_for_size_dual_page (EvView *view,
        width -= ((border.left + border.right)* 2 + 3 * view->spacing);
        height -= (border.top + border.bottom + 2 * view->spacing);
 
-       if (view->sizing_mode == EV_SIZING_FIT_WIDTH)
-               scale = zoom_for_size_fit_width (doc_width, doc_height, width, height);
-       else if (view->sizing_mode == EV_SIZING_BEST_FIT)
+       if (view->sizing_mode == EV_SIZING_FIT_WIDTH) {
+               gint sb_size;
+
+               sb_size = ev_view_get_scrollbar_size (view, GTK_ORIENTATION_VERTICAL);
+               scale = zoom_for_size_fit_width (doc_width, doc_height, width - sb_size, height);
+       } else if (view->sizing_mode == EV_SIZING_BEST_FIT)
                scale = zoom_for_size_best_fit (doc_width, doc_height, width, height);
        else
                g_assert_not_reached ();
@@ -5768,9 +5837,12 @@ ev_view_zoom_for_size_single_page (EvView *view,
        width -= (border.left + border.right + 2 * view->spacing);
        height -= (border.top + border.bottom + 2 * view->spacing);
 
-       if (view->sizing_mode == EV_SIZING_FIT_WIDTH)
-               scale = zoom_for_size_fit_width (doc_width, doc_height, width, height);
-       else if (view->sizing_mode == EV_SIZING_BEST_FIT)
+       if (view->sizing_mode == EV_SIZING_FIT_WIDTH) {
+               gint sb_size;
+
+               sb_size = ev_view_get_scrollbar_size (view, GTK_ORIENTATION_VERTICAL);
+               scale = zoom_for_size_fit_width (doc_width, doc_height, width - sb_size, height);
+       } else if (view->sizing_mode == EV_SIZING_BEST_FIT)
                scale = zoom_for_size_best_fit (doc_width, doc_height, width, height);
        else
                g_assert_not_reached ();