Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/shell
diff options
context:
space:
mode:
authorJonathan Blandford <jrb@redhat.com>2005-02-02 13:22:53 (GMT)
committer Jonathan Blandford <jrb@src.gnome.org>2005-02-02 13:22:53 (GMT)
commitbebd9ceae1ec88ddee03bda8c7572c9cb06f6b77 (patch)
tree473a80dc33f128ab0c24e3322002d2066f0fe293 /shell
parente6bb7c7e25b848008409db982bbac260fa97f73c (diff)
New file with some random thoughts.
Wed Feb 2 21:13:11 2005 Jonathan Blandford <jrb@redhat.com> * NOTES: New file with some random thoughts. * TODO: Update. * backend/ev-document-misc.c: (ev_document_misc_get_page_border_size): New function to canonicalize shadow drawing sizes. Possibly goofy. * shell/ev-view.c: (ev_view_size_request), (set_document_page), (ev_view_best_fit), (ev_view_fit_width): * pdf/xpdf/pdf-document.cc: * pixbuf/pixbuf-document.c: (pixbuf_document_get_page_size): * ps/ps-document.c: (ps_document_get_page_size): * backend/ev-document-misc.h: * backend/ev-document.c: (ev_document_get_page_size): * backend/ev-document.h: get_page_size now takes a page number parameter. Made all the backends/frontends honor it. * data/evince-ui.xml: Added a multiple-page mode. Uncomment to see. Doesn't work yet. * shell/Makefile.am: * shell/ev-page-view.[ch]: New multi-page view. Really rough. Doesn't do anything yet. * shell/ev-sidebar-thumbnails.c: (ev_sidebar_thumbnails_set_document): [1..n_pages] instead of [0..n_pages-1] * shell/ev-window.c: (update_action_sensitivity), (ev_window_setup_document), (ev_window_set_page_mode), (ev_window_page_mode_cb), (ev_window_init): Clean up the view-swapping code a bit so we can have multiple views on a document. Add the multi-page view, though it can't be turned on yet.
Diffstat (limited to 'shell')
-rw-r--r--shell/Makefile.am2
-rw-r--r--shell/ev-page-view.c678
-rw-r--r--shell/ev-page-view.h63
-rw-r--r--shell/ev-sidebar-thumbnails.c6
-rw-r--r--shell/ev-view.c7
-rw-r--r--shell/ev-window.c64
6 files changed, 812 insertions, 8 deletions
diff --git a/shell/Makefile.am b/shell/Makefile.am
index b43c25f..ad53afe 100644
--- a/shell/Makefile.am
+++ b/shell/Makefile.am
@@ -25,6 +25,8 @@ evince_SOURCES= \
ev-marshal.h \
ev-page-action.c \
ev-page-action.h \
+ ev-page-view.c \
+ ev-page-view.h \
ev-password.h \
ev-password.c \
ev-password-view.h \
diff --git a/shell/ev-page-view.c b/shell/ev-page-view.c
new file mode 100644
index 0000000..050e3cc
--- /dev/null
+++ b/shell/ev-page-view.c
@@ -0,0 +1,678 @@
+/*
+ * Copyright (C) 2005 Jonathan Blandford
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include "ev-page-view.h"
+#include "ev-marshal.h"
+#include "ev-document-misc.h"
+#include <gtk/gtk.h>
+
+/* We keep a cached array of all the page sizes. The info is accessed via
+ * page_sizes [page - 1], as pages start at 1 */
+typedef struct _EvPageViewInfo
+{
+ gint width;
+ gint height;
+} EvPageViewInfo;
+
+struct _EvPageViewPrivate
+{
+ gint width, height;
+ gint page_spacing;
+
+ GdkWindow *bin_window;
+ EvDocument *document;
+ EvPageViewInfo *page_sizes;
+
+ GtkAdjustment *hadjustment;
+ GtkAdjustment *vadjustment;
+
+ gdouble scale;
+
+ /* Page information*/
+ gint n_pages;
+ gint max_page_width;
+
+ /* these two are only set if uniform_page_size is set */
+ gint uniform_page_width;
+ gint uniform_page_height;
+ guint uniform_page_size : 1;
+};
+
+
+static void ev_page_view_init (EvPageView *page_view);
+static void ev_page_view_class_init (EvPageViewClass *klass);
+static void ev_page_view_set_scroll_adjustments (EvPageView *page_view,
+ GtkAdjustment *hadjustment,
+ GtkAdjustment *vadjustment);
+static void ev_page_view_size_request (GtkWidget *widget,
+ GtkRequisition *requisition);
+static void ev_page_view_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation);
+static gboolean ev_page_view_expose (GtkWidget *widget,
+ GdkEventExpose *expose);
+static void ev_page_view_realize (GtkWidget *widget);
+static void ev_page_view_unrealize (GtkWidget *widget);
+static void ev_page_view_map (GtkWidget *widget);
+static void ev_page_view_load (EvPageView *page_view);
+static void ev_page_view_adjustment_changed (GtkAdjustment *adjustment,
+ EvPageView *page_view);
+static void ev_page_view_update_size (EvPageView *page_view);
+
+
+G_DEFINE_TYPE (EvPageView, ev_page_view, GTK_TYPE_WIDGET)
+
+#define EV_PAGE_VIEW_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EV_TYPE_PAGE_VIEW, EvPageViewPrivate))
+
+static void
+ev_page_view_init (EvPageView *page_view)
+{
+ page_view->priv = EV_PAGE_VIEW_GET_PRIVATE (page_view);
+
+ page_view->priv->width = 1;
+ page_view->priv->height = 1;
+ page_view->priv->page_spacing = 10;
+ page_view->priv->scale = 1.0;
+
+ /* Make some stuff up */
+ page_view->priv->n_pages = 0;
+ page_view->priv->uniform_page_width = -1;
+ page_view->priv->uniform_page_height = -1;
+ page_view->priv->uniform_page_size = FALSE;
+}
+
+static void
+ev_page_view_class_init (EvPageViewClass *klass)
+{
+ GObjectClass *o_class;
+ GtkWidgetClass *widget_class;
+
+ o_class = (GObjectClass *) klass;
+ widget_class = (GtkWidgetClass *) klass;
+ klass->set_scroll_adjustments = ev_page_view_set_scroll_adjustments;
+
+ g_type_class_add_private (klass, sizeof (EvPageViewPrivate));
+ widget_class->size_request = ev_page_view_size_request;
+ widget_class->size_allocate = ev_page_view_size_allocate;
+ widget_class->expose_event = ev_page_view_expose;
+ widget_class->realize = ev_page_view_realize;
+ widget_class->unrealize = ev_page_view_unrealize;
+ widget_class->map = ev_page_view_map;
+
+ widget_class->set_scroll_adjustments_signal =
+ g_signal_new ("set_scroll_adjustments",
+ G_TYPE_FROM_CLASS (o_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (EvPageViewClass, set_scroll_adjustments),
+ NULL, NULL,
+ ev_marshal_VOID__OBJECT_OBJECT,
+ G_TYPE_NONE, 2,
+ GTK_TYPE_ADJUSTMENT,
+ GTK_TYPE_ADJUSTMENT);
+
+
+}
+
+
+static void
+ev_page_view_set_scroll_adjustments (EvPageView *page_view,
+ GtkAdjustment *hadjustment,
+ GtkAdjustment *vadjustment)
+{
+ gboolean need_adjust = FALSE;
+
+ if (hadjustment)
+ g_return_if_fail (GTK_IS_ADJUSTMENT (hadjustment));
+ else
+ hadjustment = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
+ if (vadjustment)
+ g_return_if_fail (GTK_IS_ADJUSTMENT (vadjustment));
+ else
+ vadjustment = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
+
+ if (page_view->priv->hadjustment && (page_view->priv->hadjustment != hadjustment))
+ {
+ g_signal_handlers_disconnect_matched (page_view->priv->hadjustment, G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, NULL, page_view);
+ g_object_unref (page_view->priv->hadjustment);
+ }
+
+ if (page_view->priv->vadjustment && (page_view->priv->vadjustment != vadjustment))
+ {
+ g_signal_handlers_disconnect_matched (page_view->priv->vadjustment, G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, NULL, page_view);
+ g_object_unref (page_view->priv->vadjustment);
+ }
+
+ if (page_view->priv->hadjustment != hadjustment)
+ {
+ page_view->priv->hadjustment = hadjustment;
+ g_object_ref (page_view->priv->hadjustment);
+ gtk_object_sink (GTK_OBJECT (page_view->priv->hadjustment));
+
+ g_signal_connect (page_view->priv->hadjustment, "value_changed",
+ G_CALLBACK (ev_page_view_adjustment_changed),
+ page_view);
+ need_adjust = TRUE;
+ }
+
+ if (page_view->priv->vadjustment != vadjustment)
+ {
+ page_view->priv->vadjustment = vadjustment;
+ g_object_ref (page_view->priv->vadjustment);
+ gtk_object_sink (GTK_OBJECT (page_view->priv->vadjustment));
+
+ g_signal_connect (page_view->priv->vadjustment, "value_changed",
+ G_CALLBACK (ev_page_view_adjustment_changed),
+ page_view);
+ need_adjust = TRUE;
+ }
+
+ if (need_adjust)
+ ev_page_view_adjustment_changed (NULL, page_view);
+}
+
+static void
+ev_page_view_update_size (EvPageView *page_view)
+{
+ gint left_border;
+ gint right_border;
+ gint top_border;
+ gint bottom_border;
+ gint width, height;
+
+ g_assert (page_view->priv->scale > 0.0);
+
+ if (page_view->priv->uniform_page_size) {
+ width = (int) (page_view->priv->uniform_page_width *
+ page_view->priv->scale);
+ height = (int) (page_view->priv->uniform_page_height *
+ page_view->priv->scale);
+
+ ev_document_misc_get_page_border_size (width, height,
+ & left_border, & right_border,
+ & top_border, & bottom_border);
+
+ page_view->priv->width = width
+ + page_view->priv->page_spacing * 2
+ + left_border
+ + right_border;
+ page_view->priv->height =
+ ((height
+ + page_view->priv->page_spacing
+ + top_border
+ + bottom_border)
+ * page_view->priv->n_pages) +
+ page_view->priv->page_spacing;
+ } else {
+ int i;
+
+ page_view->priv->width = 0;
+ page_view->priv->height = page_view->priv->page_spacing;
+
+ for (i = 0; i < page_view->priv->n_pages; i++) {
+ width = page_view->priv->page_sizes[i].width *
+ page_view->priv->scale;
+ height = page_view->priv->page_sizes[i].height *
+ page_view->priv->scale;
+
+ ev_document_misc_get_page_border_size (width, height,
+ & left_border, & right_border,
+ & top_border, & bottom_border);
+
+ width = width
+ + page_view->priv->page_spacing * 2
+ + left_border
+ + right_border;
+ height = height
+ + page_view->priv->page_spacing
+ + top_border
+ + bottom_border;
+
+ page_view->priv->width = MAX (width, page_view->priv->width);
+ page_view->priv->height += height;
+ }
+ }
+
+}
+
+static void
+ev_page_view_size_request (GtkWidget *widget,
+ GtkRequisition *requisition)
+{
+ EvPageView *page_view;
+
+ page_view = EV_PAGE_VIEW (widget);
+
+ ev_page_view_update_size (page_view);
+
+ requisition->width = page_view->priv->width;
+ requisition->height = page_view->priv->height;
+}
+
+static void
+ev_page_view_paint_one_page (EvPageView *page_view,
+ GdkRectangle *area,
+ gint left_border,
+ gint right_border,
+ gint top_border,
+ gint bottom_border)
+{
+ GtkWidget *widget;
+
+ widget = GTK_WIDGET (page_view);
+
+ g_print ("paint one page (%d,%d) %dx%d\n",
+ area->x, area->y,
+ area->width,
+ area->height);
+ gdk_draw_rectangle (page_view->priv->bin_window,
+ widget->style->black_gc,
+ TRUE,
+ area->x,
+ area->y,
+ area->width,
+ area->height);
+ gdk_draw_rectangle (page_view->priv->bin_window,
+ widget->style->white_gc,
+ TRUE,
+ area->x + left_border,
+ area->y + top_border,
+ area->width - (left_border + right_border),
+ area->height - (top_border + bottom_border));
+ gdk_draw_rectangle (page_view->priv->bin_window,
+ widget->style->mid_gc[widget->state],
+ TRUE,
+ area->x,
+ area->y + area->height - (bottom_border - top_border),
+ bottom_border - top_border,
+ bottom_border - top_border);
+ gdk_draw_rectangle (page_view->priv->bin_window,
+ widget->style->mid_gc[widget->state],
+ TRUE,
+ area->x + area->width - (right_border - left_border),
+ area->y,
+ right_border - left_border,
+ right_border - left_border);
+}
+
+static void
+ev_page_view_expose_uniform (GtkWidget *widget,
+ GdkEventExpose *expose)
+{
+ EvPageView *page_view;
+ gint left_border;
+ gint right_border;
+ gint top_border;
+ gint bottom_border;
+ int x_offset = 0;
+ GdkRectangle rectangle;
+ gint width, height;
+ int i;
+
+ page_view = EV_PAGE_VIEW (widget);
+
+ width = (int) (page_view->priv->uniform_page_width *
+ page_view->priv->scale);
+ height = (int) (page_view->priv->uniform_page_height *
+ page_view->priv->scale);
+
+ if (widget->allocation.width > page_view->priv->width)
+ x_offset = (widget->allocation.width - page_view->priv->width)/2;
+
+ ev_document_misc_get_page_border_size (width, height,
+ & left_border,
+ & right_border,
+ & top_border,
+ & bottom_border);
+
+ rectangle.x = page_view->priv->page_spacing + x_offset;
+ rectangle.y = page_view->priv->page_spacing;
+ rectangle.width = width
+ + left_border
+ + right_border;
+ rectangle.height = height
+ + top_border
+ + bottom_border;
+ for (i = 0; i < page_view->priv->n_pages; i++) {
+ GdkRectangle unused;
+
+ if (gdk_rectangle_intersect (&rectangle,
+ &expose->area,
+ &unused))
+ ev_page_view_paint_one_page (page_view,
+ & rectangle,
+ left_border, right_border,
+ top_border, bottom_border);
+ rectangle.y += rectangle.height
+ + page_view->priv->page_spacing;
+
+ }
+}
+
+static void
+ev_page_view_expose_pages (GtkWidget *widget,
+ GdkEventExpose *expose)
+{
+ EvPageView *page_view;
+ gint left_border;
+ gint right_border;
+ gint top_border;
+ gint bottom_border;
+ int x_offset = 0;
+ GdkRectangle rectangle;
+ gint width, height;
+ int i;
+
+ page_view = EV_PAGE_VIEW (widget);
+
+ width = (int) (page_view->priv->uniform_page_width *
+ page_view->priv->scale);
+ height = (int) (page_view->priv->uniform_page_height *
+ page_view->priv->scale);
+
+ if (widget->allocation.width > page_view->priv->width)
+ x_offset = (widget->allocation.width - page_view->priv->width)/2;
+
+ ev_document_misc_get_page_border_size (width, height,
+ & left_border,
+ & right_border,
+ & top_border,
+ & bottom_border);
+
+ rectangle.x = page_view->priv->page_spacing + x_offset;
+ rectangle.y = page_view->priv->page_spacing;
+ rectangle.width = width
+ + left_border
+ + right_border;
+ rectangle.height = height
+ + top_border
+ + bottom_border;
+ for (i = 0; i < page_view->priv->n_pages; i++) {
+ GdkRectangle unused;
+
+ if (gdk_rectangle_intersect (&rectangle,
+ &expose->area,
+ &unused))
+ ev_page_view_paint_one_page (page_view,
+ & rectangle,
+ left_border, right_border,
+ top_border, bottom_border);
+ rectangle.y += rectangle.height
+ + page_view->priv->page_spacing;
+
+ }
+}
+
+static gboolean
+ev_page_view_expose (GtkWidget *widget,
+ GdkEventExpose *expose)
+{
+ EvPageView *page_view;
+
+ page_view = EV_PAGE_VIEW (widget);
+
+ if (expose->window != page_view->priv->bin_window)
+ return FALSE;
+
+ if (page_view->priv->uniform_page_size) {
+ ev_page_view_expose_uniform (widget, expose);
+ } else {
+ ev_page_view_expose_pages (widget, expose);
+ }
+
+ return TRUE;
+}
+
+static void
+ev_page_view_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation)
+{
+ EvPageView *page_view;
+
+ widget->allocation = *allocation;
+
+ page_view = EV_PAGE_VIEW (widget);
+
+ if (GTK_WIDGET_REALIZED (widget))
+ {
+ gdk_window_move_resize (widget->window,
+ allocation->x, allocation->y,
+ allocation->width, allocation->height);
+ gdk_window_resize (page_view->priv->bin_window,
+ MAX (page_view->priv->width, allocation->width),
+ MAX (page_view->priv->height, allocation->height));
+ }
+
+ page_view->priv->hadjustment->page_size = allocation->width;
+ page_view->priv->hadjustment->page_increment = allocation->width * 0.9;
+ page_view->priv->hadjustment->step_increment = allocation->width * 0.1;
+ page_view->priv->hadjustment->lower = 0;
+ page_view->priv->hadjustment->upper = MAX (allocation->width, page_view->priv->width);
+ gtk_adjustment_changed (page_view->priv->hadjustment);
+
+ page_view->priv->vadjustment->page_size = allocation->height;
+ page_view->priv->vadjustment->page_increment = allocation->height * 0.9;
+ page_view->priv->vadjustment->step_increment = allocation->width * 0.1;
+ page_view->priv->vadjustment->lower = 0;
+ page_view->priv->vadjustment->upper = MAX (allocation->height, page_view->priv->height);
+ gtk_adjustment_changed (page_view->priv->vadjustment);
+}
+
+static void
+ev_page_view_adjustment_changed (GtkAdjustment *adjustment,
+ EvPageView *page_view)
+{
+ if (GTK_WIDGET_REALIZED (page_view)) {
+ gdk_window_move (page_view->priv->bin_window,
+ - page_view->priv->hadjustment->value,
+ - page_view->priv->vadjustment->value);
+
+ gdk_window_process_updates (page_view->priv->bin_window, TRUE);
+ }
+}
+
+static void
+ev_page_view_realize_document (EvPageView *page_view)
+{
+ if (page_view->priv->document == NULL)
+ return;
+
+ ev_document_set_target (page_view->priv->document,
+ page_view->priv->bin_window);
+ ev_page_view_load (page_view);
+ gtk_widget_queue_resize (GTK_WIDGET (page_view));
+}
+
+
+static void
+ev_page_view_realize (GtkWidget *widget)
+{
+ EvPageView *page_view;
+ GdkWindowAttr attributes;
+ gint attributes_mask;
+
+ g_return_if_fail (EV_IS_PAGE_VIEW (widget));
+
+ page_view = EV_PAGE_VIEW (widget);
+ GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
+
+ /* Make the main, clipping window */
+ attributes.window_type = GDK_WINDOW_CHILD;
+ attributes.x = widget->allocation.x;
+ attributes.y = widget->allocation.y;
+ attributes.width = widget->allocation.width;
+ attributes.height = widget->allocation.height;
+ attributes.wclass = GDK_INPUT_OUTPUT;
+ attributes.visual = gtk_widget_get_visual (widget);
+ attributes.colormap = gtk_widget_get_colormap (widget);
+ attributes.event_mask = GDK_VISIBILITY_NOTIFY_MASK;
+
+ attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
+
+ widget->window = gdk_window_new (gtk_widget_get_parent_window (widget),
+ &attributes, attributes_mask);
+ gdk_window_set_user_data (widget->window, widget);
+
+ /* Make the window for the page view */
+ attributes.x = 0;
+ attributes.y = 0;
+ attributes.width = MAX (page_view->priv->width, widget->allocation.width);
+ attributes.height = MAX (page_view->priv->height, widget->allocation.height);
+ attributes.event_mask = (GDK_EXPOSURE_MASK |
+ GDK_SCROLL_MASK |
+ GDK_POINTER_MOTION_MASK |
+ GDK_BUTTON_PRESS_MASK |
+ GDK_BUTTON_RELEASE_MASK |
+ GDK_KEY_PRESS_MASK |
+ GDK_KEY_RELEASE_MASK) |
+ gtk_widget_get_events (widget);
+
+ page_view->priv->bin_window = gdk_window_new (widget->window,
+ &attributes, attributes_mask);
+ gdk_window_set_user_data (page_view->priv->bin_window, widget);
+
+ widget->style = gtk_style_attach (widget->style, widget->window);
+ gdk_window_set_background (page_view->priv->bin_window, &widget->style->mid[widget->state]);
+ gdk_window_set_background (widget->window, &widget->style->mid[widget->state]);
+
+ ev_page_view_realize_document (page_view);
+}
+
+
+static void
+ev_page_view_unrealize (GtkWidget *widget)
+{
+ EvPageView *page_view;
+
+ page_view = EV_PAGE_VIEW (widget);
+
+ gdk_window_set_user_data (page_view->priv->bin_window, NULL);
+ gdk_window_destroy (page_view->priv->bin_window);
+ page_view->priv->bin_window = NULL;
+
+ /* GtkWidget::unrealize destroys children and widget->window */
+ if (GTK_WIDGET_CLASS (ev_page_view_parent_class)->unrealize)
+ (* GTK_WIDGET_CLASS (ev_page_view_parent_class)->unrealize) (widget);
+}
+
+static void
+ev_page_view_map (GtkWidget *widget)
+{
+ EvPageView *page_view;
+
+ page_view = EV_PAGE_VIEW (widget);
+
+ GTK_WIDGET_SET_FLAGS (widget, GTK_MAPPED);
+
+ gdk_window_show (page_view->priv->bin_window);
+ gdk_window_show (widget->window);
+}
+
+static void
+ev_page_view_load (EvPageView *page_view)
+{
+ int i;
+ gboolean uniform_page_size = TRUE;
+ int width = 0, height = 0;
+
+ page_view->priv->n_pages =
+ ev_document_get_n_pages (page_view->priv->document);
+
+ for (i = 1; i <= page_view->priv->n_pages; i++) {
+ EvPageViewInfo *info;
+ gint page_width = 0;
+ gint page_height = 0;
+
+ ev_document_set_scale (page_view->priv->document, page_view->priv->scale);
+ ev_document_get_page_size (page_view->priv->document,
+ i,
+ &page_width, &page_height);
+
+ if (i == 1) {
+ width = page_width;
+ height = page_height;
+ } else if (width != page_width || height != page_height) {
+ /* It's a different page size. Backfill the array. */
+ int j;
+
+ uniform_page_size = FALSE;
+
+ page_view->priv->page_sizes =
+ g_new0 (EvPageViewInfo, page_view->priv->n_pages);
+
+ for (j = 1; j < i; j++) {
+
+ info = &(page_view->priv->page_sizes[j - 1]);
+ info->width = width;
+ info->height = height;
+ }
+ }
+
+ if (! uniform_page_size) {
+ info = &(page_view->priv->page_sizes[i - 1]);
+
+ info->width = page_width;
+ info->height = page_height;
+ }
+ }
+
+ page_view->priv->uniform_page_size = uniform_page_size;
+
+ if (uniform_page_size) {
+ page_view->priv->uniform_page_width = width;
+ page_view->priv->uniform_page_height = height;
+ }
+
+ ev_page_view_update_size (page_view);
+
+ gtk_widget_queue_resize (GTK_WIDGET (page_view));
+}
+
+/* Public functions */
+GtkWidget *
+ev_page_view_new (void)
+{
+ return g_object_new (EV_TYPE_PAGE_VIEW, NULL);
+}
+
+void
+ev_page_view_set_document (EvPageView *page_view,
+ EvDocument *document)
+{
+ g_return_if_fail (EV_IS_PAGE_VIEW (page_view));
+
+ if (document != page_view->priv->document) {
+ if (page_view->priv->document) {
+ g_object_unref (page_view->priv->document);
+ }
+
+ page_view->priv->document = document;
+
+ if (page_view->priv->document) {
+ g_object_ref (page_view->priv->document);
+ }
+
+ if (GTK_WIDGET_REALIZED (page_view)) {
+ ev_page_view_realize_document (page_view);
+ }
+ }
+
+}
+
diff --git a/shell/ev-page-view.h b/shell/ev-page-view.h
new file mode 100644
index 0000000..24b1930
--- /dev/null
+++ b/shell/ev-page-view.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2004 Jonathan Blandforde
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef EV_PAGE_VIEW_H
+#define EV_PAGE_VIEW_H
+
+#include <gtk/gtk.h>
+#include "ev-document.h"
+
+G_BEGIN_DECLS
+
+#define EV_TYPE_PAGE_VIEW (ev_page_view_get_type ())
+#define EV_PAGE_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EV_TYPE_PAGE_VIEW, EvPageView))
+#define EV_PAGE_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EV_TYPE_PAGE_VIEW, EvPageViewClass))
+#define EV_IS_PAGE_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EV_TYPE_PAGE_VIEW))
+#define EV_IS_PAGE_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), EV_TYPE_PAGE_VIEW))
+#define EV_PAGE_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), EV_TYPE_PAGE_VIEW, EvPageViewClass))
+
+typedef struct _EvPageView EvPageView;
+typedef struct _EvPageViewPrivate EvPageViewPrivate;
+typedef struct _EvPageViewClass EvPageViewClass;
+
+struct _EvPageView
+{
+ GtkWidget parent;
+
+ /*< private >*/
+ EvPageViewPrivate *priv;
+};
+
+struct _EvPageViewClass
+{
+ GtkWidgetClass parent_class;
+
+ void (* set_scroll_adjustments) (EvPageView *page_view,
+ GtkAdjustment *hadjustment,
+ GtkAdjustment *vadjustment);
+};
+
+GType ev_page_view_get_type (void);
+GtkWidget *ev_page_view_new (void);
+void ev_page_view_set_document (EvPageView *page_view,
+ EvDocument *document);
+
+
+G_END_DECLS
+
+#endif
diff --git a/shell/ev-sidebar-thumbnails.c b/shell/ev-sidebar-thumbnails.c
index 4d54d11..2d71539 100644
--- a/shell/ev-sidebar-thumbnails.c
+++ b/shell/ev-sidebar-thumbnails.c
@@ -352,11 +352,11 @@ ev_sidebar_thumbnails_set_document (EvSidebarThumbnails *sidebar_thumbnails,
/* We get the dimensions of the first doc so that we can make a blank
* icon. */
ev_document_thumbnails_get_dimensions (EV_DOCUMENT_THUMBNAILS (priv->document),
- 0, THUMBNAIL_WIDTH, &width, &height);
+ 1, THUMBNAIL_WIDTH, &width, &height);
loading_icon = ev_document_misc_get_thumbnail_frame (width, height, NULL);
- for (i = 0; i < n_pages; i++) {
- page = g_strdup_printf ("<i>%d</i>", i + 1);
+ for (i = 1; i <= n_pages; i++) {
+ page = g_strdup_printf ("<i>%d</i>", i);
gtk_list_store_append (priv->list_store, &iter);
gtk_list_store_set (priv->list_store, &iter,
COLUMN_PAGE_STRING, page,
diff --git a/shell/ev-view.c b/shell/ev-view.c
index 291b3c5..a5fc7ce 100644
--- a/shell/ev-view.c
+++ b/shell/ev-view.c
@@ -209,6 +209,7 @@ ev_view_size_request (GtkWidget *widget,
if (GTK_WIDGET_REALIZED (widget)) {
if (view->document) {
ev_document_get_page_size (view->document,
+ -1,
&requisition->width,
&requisition->height);
} else {
@@ -950,6 +951,7 @@ set_document_page (EvView *view, int page)
int old_width, old_height;
ev_document_get_page_size (view->document,
+ -1,
&old_width, &old_height);
if (old_page != page) {
@@ -964,6 +966,7 @@ set_document_page (EvView *view, int page)
view->has_selection = FALSE;
ev_document_get_page_size (view->document,
+ -1,
&width, &height);
if (width != old_width || height != old_height)
gtk_widget_queue_resize (GTK_WIDGET (view));
@@ -1216,7 +1219,7 @@ ev_view_best_fit (EvView *view)
int width, height;
width = height = 0;
- ev_document_get_page_size (view->document, &width, &height);
+ ev_document_get_page_size (view->document, -1, &width, &height);
scale = 1.0;
if (width != 0 && height != 0) {
@@ -1238,7 +1241,7 @@ ev_view_fit_width (EvView *view)
int width;
width = 0;
- ev_document_get_page_size (view->document, &width, NULL);
+ ev_document_get_page_size (view->document, -1, &width, NULL);
scale = 1.0;
if (width != 0)
diff --git a/shell/ev-window.c b/shell/ev-window.c
index 9eadc55..01c4f8a 100644
--- a/shell/ev-window.c
+++ b/shell/ev-window.c
@@ -34,6 +34,7 @@
#include "ev-sidebar-links.h"
#include "ev-sidebar-thumbnails.h"
#include "ev-view.h"
+#include "ev-page-view.h"
#include "ev-password.h"
#include "ev-password-view.h"
#include "ev-print-job.h"
@@ -70,6 +71,7 @@ struct _EvWindowPrivate {
GtkWidget *find_bar;
GtkWidget *scrolled_window;
GtkWidget *view;
+ GtkWidget *page_view;
GtkWidget *password_view;
GtkActionGroup *action_group;
GtkUIManager *ui_manager;
@@ -81,6 +83,7 @@ struct _EvWindowPrivate {
EvDocument *document;
+ EvWindowPageMode page_mode;
/* These members are used temporarily when in PAGE_MODE_PASSWORD */
EvDocument *password_document;
GtkWidget *password_dialog;
@@ -119,9 +122,11 @@ static void
update_action_sensitivity (EvWindow *ev_window)
{
EvDocument *document;
+ EvWindowPageMode page_mode;
EvView *view;
document = ev_window->priv->document;
+ page_mode = ev_window->priv->page_mode;
view = EV_VIEW (ev_window->priv->view);
@@ -160,12 +165,20 @@ update_action_sensitivity (EvWindow *ev_window)
set_action_sensitive (ev_window, "GoFirstPage", page > 1);
set_action_sensitive (ev_window, "GoLastPage", page < n_pages);
} else {
- set_action_sensitive (ev_window, "GoFirstPage", FALSE);
+ set_action_sensitive (ev_window, "GoFirstPage", FALSE);
set_action_sensitive (ev_window, "GoPageUp", FALSE);
set_action_sensitive (ev_window, "GoPageDown", FALSE);
set_action_sensitive (ev_window, "GoLastPage", FALSE);
}
+ /* Page View radio group */
+ if (document) {
+ set_action_sensitive (ev_window, "SinglePage", page_mode != PAGE_MODE_PASSWORD);
+ set_action_sensitive (ev_window, "ContinuousPage", page_mode != PAGE_MODE_PASSWORD);
+ } else {
+ set_action_sensitive (ev_window, "SinglePage", FALSE);
+ set_action_sensitive (ev_window, "ContinuousPage", FALSE);
+ }
/* Help menu */
/* "HelpContents": always sensitive */
/* "HelpAbout": always sensitive */
@@ -313,6 +326,7 @@ ev_window_setup_document (EvWindow *ev_window)
{
EvDocument *document;
EvView *view = EV_VIEW (ev_window->priv->view);
+ EvPageView *page_view = EV_PAGE_VIEW (ev_window->priv->page_view);
EvSidebar *sidebar = EV_SIDEBAR (ev_window->priv->sidebar);
document = ev_window->priv->document;
@@ -326,8 +340,9 @@ ev_window_setup_document (EvWindow *ev_window)
ev_sidebar_set_document (sidebar, document);
ev_view_set_document (view, document);
+ ev_page_view_set_document (page_view, document);
- update_window_title (ev_window->priv->document, NULL, ev_window);
+ update_window_title (document, NULL, ev_window);
update_total_pages (ev_window);
update_action_sensitivity (ev_window);
}
@@ -991,6 +1006,11 @@ ev_window_set_page_mode (EvWindow *window,
GtkWidget *child = NULL;
GtkWidget *real_child;
+ if (window->priv->page_mode == page_mode)
+ return;
+
+ window->priv->page_mode = page_mode;
+
switch (page_mode) {
case PAGE_MODE_SINGLE_PAGE:
child = window->priv->view;
@@ -998,10 +1018,13 @@ ev_window_set_page_mode (EvWindow *window,
case PAGE_MODE_PASSWORD:
child = window->priv->password_view;
break;
+ case PAGE_MODE_CONTINUOUS_PAGE:
+ child = window->priv->page_view;
+ break;
default:
- g_warning ("page_mode not implemented yet\n");
g_assert_not_reached ();
}
+
real_child = gtk_bin_get_child (GTK_BIN (window->priv->scrolled_window));
if (child != real_child) {
gtk_container_remove (GTK_CONTAINER (window->priv->scrolled_window),
@@ -1009,6 +1032,7 @@ ev_window_set_page_mode (EvWindow *window,
gtk_container_add (GTK_CONTAINER (window->priv->scrolled_window),
child);
}
+ update_action_sensitivity (window);
}
static void
@@ -1313,6 +1337,21 @@ find_bar_close_cb (EggFindBar *find_bar,
}
static void
+ev_window_page_mode_cb (GtkRadioAction *action,
+ GtkRadioAction *activated_action,
+ EvWindow *window)
+{
+ int mode;
+
+ mode = gtk_radio_action_get_current_value (action);
+
+ g_assert (mode == PAGE_MODE_CONTINUOUS_PAGE ||
+ mode == PAGE_MODE_SINGLE_PAGE);
+
+ ev_window_set_page_mode (window, (EvWindowPageMode) mode);
+}
+
+static void
find_bar_search_changed_cb (EggFindBar *find_bar,
GParamSpec *param,
EvWindow *ev_window)
@@ -1489,6 +1528,15 @@ static GtkToggleActionEntry toggle_entries[] = {
G_CALLBACK (ev_window_cmd_view_fullscreen) },
};
+static GtkRadioActionEntry page_view_entries[] = {
+ { "SinglePage", GTK_STOCK_DND, N_("Single"), NULL,
+ N_("Show the document one page at a time"),
+ PAGE_MODE_SINGLE_PAGE },
+ { "ContinuousPage", GTK_STOCK_DND_MULTIPLE, N_("Multi"), NULL,
+ N_("Show the full document at once"),
+ PAGE_MODE_CONTINUOUS_PAGE }
+};
+
static void
goto_page_cb (GtkAction *action, int page_number, EvWindow *ev_window)
{
@@ -1540,6 +1588,7 @@ ev_window_init (EvWindow *ev_window)
ev_window->priv = EV_WINDOW_GET_PRIVATE (ev_window);
+ ev_window->priv->page_mode = PAGE_MODE_SINGLE_PAGE;
update_window_title (NULL, NULL, ev_window);
ev_window->priv->main_box = gtk_vbox_new (FALSE, 0);
@@ -1554,6 +1603,11 @@ ev_window_init (EvWindow *ev_window)
gtk_action_group_add_toggle_actions (action_group, toggle_entries,
G_N_ELEMENTS (toggle_entries),
ev_window);
+ gtk_action_group_add_radio_actions (action_group, page_view_entries,
+ G_N_ELEMENTS (page_view_entries),
+ ev_window->priv->page_mode,
+ G_CALLBACK (ev_window_page_mode_cb),
+ ev_window);
set_short_labels (action_group);
register_custom_actions (ev_window, action_group);
@@ -1625,15 +1679,19 @@ ev_window_init (EvWindow *ev_window)
ev_window->priv->scrolled_window);
ev_window->priv->view = ev_view_new ();
+ ev_window->priv->page_view = ev_page_view_new ();
ev_window->priv->password_view = ev_password_view_new ();
g_signal_connect_swapped (ev_window->priv->password_view,
"unlock",
G_CALLBACK (ev_window_popup_password_dialog),
ev_window);
gtk_widget_show (ev_window->priv->view);
+ gtk_widget_show (ev_window->priv->page_view);
gtk_widget_show (ev_window->priv->password_view);
+
/* We own a ref on these widgets, as we can swap them in and out */
g_object_ref (ev_window->priv->view);
+ g_object_ref (ev_window->priv->page_view);
g_object_ref (ev_window->priv->password_view);
gtk_container_add (GTK_CONTAINER (ev_window->priv->scrolled_window),