]> www.fi.muni.cz Git - evince.git/blobdiff - shell/ev-view.c
Redo rotation (again). prepare for 0.4.0
[evince.git] / shell / ev-view.c
index fe07f1dd9728611b440855c3b61a79d7cfbe3f4a..a59b64abcc940ac6ab911562a024fa942e783e2a 100644 (file)
@@ -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;
@@ -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,8 +1695,7 @@ 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);
@@ -1856,6 +1865,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 +1907,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 +2038,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 +2083,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);
 
@@ -2399,15 +2423,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 +2447,25 @@ 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));
+       }
+       
+       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 +2796,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 +2806,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 +2815,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 +2835,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 +2867,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 +2898,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 +2978,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 +2988,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;