+
+static void
+go_to_link (EvView *view, EvLink *link)
+{
+ EvLinkType type;
+ const char *uri;
+ int page;
+
+ type = ev_link_get_link_type (link);
+
+ switch (type) {
+ case EV_LINK_TYPE_TITLE:
+ break;
+ case EV_LINK_TYPE_PAGE:
+ page = ev_link_get_page (link);
+ ev_page_cache_set_current_page (view->page_cache, page);
+ break;
+ case EV_LINK_TYPE_EXTERNAL_URI:
+ uri = ev_link_get_uri (link);
+ gnome_vfs_url_show (uri);
+ break;
+ }
+}
+
+void
+ev_view_go_to_link (EvView *view, EvLink *link)
+{
+ go_to_link (view, link);
+}
+
+static void
+ev_view_zoom (EvView *view,
+ double factor,
+ gboolean relative)
+{
+ double scale;
+
+ if (relative)
+ scale = view->scale * factor;
+ else
+ scale = factor;
+
+ scale = CLAMP (scale, MIN_SCALE, MAX_SCALE);
+
+ view->scale = scale;
+ gtk_widget_queue_resize (GTK_WIDGET (view));
+}
+
+void
+ev_view_zoom_in (EvView *view)
+{
+ view->width = view->height = -1;
+ ev_view_zoom (view, ZOOM_IN_FACTOR, TRUE);
+}
+
+void
+ev_view_zoom_out (EvView *view)
+{
+ view->width = view->height = -1;
+ ev_view_zoom (view, ZOOM_OUT_FACTOR, TRUE);
+}
+
+static double
+size_to_zoom_factor (EvView *view, int width, int height)
+{
+ int doc_width, doc_height;
+ double scale, scale_w, scale_h;
+ GtkBorder border;
+
+ doc_width = doc_height = 0;
+ scale = scale_w = scale_h = 1.0;
+ ev_page_cache_get_size (view->page_cache,
+ view->current_page,
+ view->scale,
+ &doc_width,
+ &doc_height);
+
+ /* FIXME: The border size isn't constant. Ugh. Still, if we have extra
+ * space, we just cut it from the border */
+ ev_document_misc_get_page_border_size (doc_width, doc_height, &border);
+
+ if (doc_width == 0 && doc_height == 0) {
+ return 0;
+ }
+
+ if (width >= 0) {
+ int target_width;
+
+ target_width = width - (view->spacing * 2 + border.left + border.right);
+ scale = scale_w = (double)target_width * view->scale / doc_width;
+ }
+
+ if (height >= 0) {
+ int target_height;
+
+ target_height = height - (view->spacing * 2 + border.top + border.bottom);
+ scale = scale_h = (double)target_height * view->scale / doc_height;
+ }
+
+ if (width >= 0 && height >= 0) {
+ scale = (scale_w < scale_h) ? scale_w : scale_h;
+ }
+
+ return scale;
+}
+
+void
+ev_view_set_size (EvView *view,
+ int width,
+ int height)
+{
+ double factor;
+
+ if (!view->document)
+ return;
+
+ if (view->width != width ||
+ view->height != height) {
+ view->width = width;
+ view->height = height;
+ factor = size_to_zoom_factor (view, width, height);
+ ev_view_zoom (view, factor, FALSE);
+ gtk_widget_queue_resize (GTK_WIDGET (view));
+ }
+}
+
+const char *
+ev_view_get_status (EvView *view)
+{
+ g_return_val_if_fail (EV_IS_VIEW (view), NULL);
+
+ return view->status;
+}
+
+const char *
+ev_view_get_find_status (EvView *view)
+{
+ g_return_val_if_fail (EV_IS_VIEW (view), NULL);
+
+ return view->find_status;
+}
+
+void
+ev_view_find_next (EvView *view)
+{
+ EvPageCache *page_cache;
+ int n_results, n_pages;
+ EvDocumentFind *find = EV_DOCUMENT_FIND (view->document);
+
+ page_cache = ev_document_get_page_cache (view->document);
+ g_mutex_lock (EV_DOC_MUTEX);
+ n_results = ev_document_find_get_n_results (find);
+ g_mutex_unlock (EV_DOC_MUTEX);
+
+ n_pages = ev_page_cache_get_n_pages (page_cache);
+
+ 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 = 1;
+ }
+
+ jump_to_find_page (view);
+ } else {
+ jump_to_find_result (view);
+ gtk_widget_queue_draw (GTK_WIDGET (view));
+ }
+}
+
+void
+ev_view_find_previous (EvView *view)
+{
+ int n_results, n_pages;
+ EvDocumentFind *find = EV_DOCUMENT_FIND (view->document);
+ EvPageCache *page_cache;
+
+ page_cache = ev_document_get_page_cache (view->document);
+
+ g_mutex_lock (EV_DOC_MUTEX);
+ n_results = ev_document_find_get_n_results (find);
+ g_mutex_unlock (EV_DOC_MUTEX);
+
+ n_pages = ev_page_cache_get_n_pages (page_cache);
+
+ view->find_result--;
+
+ if (view->find_result < 0) {
+ view->find_result = 0;
+ view->find_page--;
+
+ if (view->find_page < 1) {
+ view->find_page = n_pages;
+ }
+
+ jump_to_find_page (view);
+ } else {
+ jump_to_find_result (view);
+ gtk_widget_queue_draw (GTK_WIDGET (view));
+ }
+}
+void
+ev_view_hide_cursor (EvView *view)
+{
+ ev_view_set_cursor (view, EV_VIEW_CURSOR_HIDDEN);
+}
+
+void
+ev_view_show_cursor (EvView *view)
+{
+ ev_view_set_cursor (view, EV_VIEW_CURSOR_LINK);
+}