1
0
mirror of https://gitlab.gnome.org/GNOME/evince synced 2024-07-02 15:48:59 +00:00

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.
This commit is contained in:
Jonathan Blandford 2005-02-02 13:22:53 +00:00 committed by Jonathan Blandford
parent e6bb7c7e25
commit bebd9ceae1
17 changed files with 966 additions and 20 deletions

View File

@ -1,3 +1,41 @@
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.
2005-02-01 Marco Pesenti Gritti <marco@gnome.org>
* shell/ev-application.c: (ev_application_open):

30
NOTES Normal file
View File

@ -0,0 +1,30 @@
SOME RANDOM COMMENTS:
=====================
* We assume that all documents can be broken down into a linear
collection of pages.
* If a document type doesn't break down in such a way (like web pages)
then it's probably not a good fit for this application.
* Each page has a natural page size in pixels. This is generally
ignored in favor of a scale-to-fit mode, but is occasionally
important for backends like the image backend.
* Each page is not necessarily the same size.
* We refer to pages by page number. This number ranges from 1 to
document->n_pages. A page index of -1 means the current set page,
and a page index of 0 is not used.
--
Thoughts on threading:
* The primary thing we are trying to do is minimize switching pages, as
doing so is slow for backends. Additionally, some operations on the
backend are slow, leaving poor interactivity. This
--

18
TODO
View File

@ -6,7 +6,13 @@ Improve Find system
Display location of results in thumbnails?
Only display thumbnails of pages found?
Implement multi-page view for continuous page scrolling
Move to three page views:
* Single page (prolly default for some backends)
* Continuous scrolling
* Side-by-side continuous scrolling
Sidebar improvements for ps/pixbuf, or PDF files without a TOC.
Improve look of combobox Thumbnails/Index
@ -16,6 +22,16 @@ Document Properties Dialog for document meta-data
Provide Desktop icon Thumbnailer for Documents
Make an object that handles the page count.
Move to having three sizing types:
* Free zooming
* constrain to width
* constrain to height
* also, maybe add a 1-1 button. Possibly dubious, though.
------- TODONE ------- (move finished TODO items here)
Create a TODO list

View File

@ -1,6 +1,7 @@
#include "ev-document-misc.h"
#include <string.h>
#include <gtk/gtk.h>
/* Returns a new GdkPixbuf that is suitable for placing in the thumbnail view.
* It is four pixels wider and taller than the source. If source_pixbuf is not
@ -62,3 +63,31 @@ ev_document_misc_get_thumbnail_frame (int width,
return retval;
}
void
ev_document_misc_get_page_border_size (gint page_width,
gint page_height,
gint *left_border,
gint *right_border,
gint *top_border,
gint *bottom_border)
{
g_assert (left_border);
g_assert (right_border);
g_assert (top_border);
g_assert (bottom_border);
*left_border = 1;
*top_border = 1;
if (page_width < 100) {
*right_border = 2;
*bottom_border = 2;
} else if (page_width < 500) {
*right_border = 3;
*left_border = 3;
} else {
*right_border = 4;
*bottom_border = 4;
}
}

View File

@ -32,6 +32,13 @@ GdkPixbuf *ev_document_misc_get_thumbnail_frame (int width,
int height,
GdkPixbuf *source_pixbuf);
void ev_document_misc_get_page_border_size (gint page_width,
gint page_height,
gint *left_border,
gint *right_border,
gint *top_border,
gint *bottom_border);
G_END_DECLS
#endif /* EV_DOCUMENT_MISC_H */

View File

@ -164,11 +164,12 @@ ev_document_set_page_offset (EvDocument *document,
void
ev_document_get_page_size (EvDocument *document,
int page,
int *width,
int *height)
{
EvDocumentIface *iface = EV_DOCUMENT_GET_IFACE (document);
iface->get_page_size (document, width, height);
iface->get_page_size (document, page, width, height);
}
char *

View File

@ -74,6 +74,7 @@ struct _EvDocumentIface
int x,
int y);
void (* get_page_size) (EvDocument *document,
int page,
int *width,
int *height);
char * (* get_text) (EvDocument *document,
@ -112,6 +113,7 @@ void ev_document_set_page_offset (EvDocument *document,
int x,
int y);
void ev_document_get_page_size (EvDocument *document,
int page,
int *width,
int *height);
char *ev_document_get_text (EvDocument *document,

View File

@ -56,5 +56,10 @@
<toolitem action="ViewZoomOut"/>
<toolitem action="ViewBestFit"/>
<toolitem action="ViewPageWidth"/>
<!--
<separator/>
<toolitem action="SinglePage"/>
<toolitem action="ContinuousPage"/>
-->
</toolbar>
</ui>

View File

@ -350,21 +350,32 @@ pdf_document_set_page_offset (EvDocument *document,
static void
pdf_document_get_page_size (EvDocument *document,
int page,
int *width,
int *height)
{
PdfDocument *pdf_document = PDF_DOCUMENT (document);
Page *the_page;
if (document_validate_page (pdf_document)) {
/* set some default values */
if (width)
*width = 1;
if (height)
*height = 1;
if (page == -1 && document_validate_page (pdf_document)) {
if (width)
*width = pdf_document->out->getBitmapWidth();
if (height)
*height = pdf_document->out->getBitmapHeight();
} else {
if (width)
*width = 1;
if (height)
*height = 1;
return;
}
the_page = pdf_document->doc->getCatalog ()->getPage (page);
if (the_page) {
*width = (int) the_page->getWidth ();
*height = (int) the_page->getHeight ();
}
}
@ -1244,8 +1255,7 @@ pdf_document_thumbnails_get_dimensions (EvDocumentThumbnails *document_thumbnail
Thumb *thumb = NULL;
gdouble page_ratio;
/* getPage seems to want page + 1 for some reason; */
the_page = pdf_document->doc->getCatalog ()->getPage (page + 1);
the_page = pdf_document->doc->getCatalog ()->getPage (page);
the_page->getThumb (&the_thumb);
if (!(the_thumb.isNull () || the_thumb.isNone())) {

View File

@ -137,6 +137,7 @@ pixbuf_document_set_page_offset (EvDocument *document,
static void
pixbuf_document_get_page_size (EvDocument *document,
int page,
int *width,
int *height)
{

View File

@ -1784,9 +1784,12 @@ ps_document_set_page_offset (EvDocument *document,
static void
ps_document_get_page_size (EvDocument *document,
int *width,
int *height)
int page,
int *width,
int *height)
{
/* Post script documents never vary in size */
PSDocument *gs = PS_DOCUMENT (document);
if (width) {

View File

@ -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 \

678
shell/ev-page-view.c Normal file
View File

@ -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);
}
}
}

63
shell/ev-page-view.h Normal file
View File

@ -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

View File

@ -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,

View File

@ -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)

View File

@ -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
@ -1312,6 +1336,21 @@ find_bar_close_cb (EggFindBar *find_bar,
ev_window_update_fullscreen_popup (ev_window);
}
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,
@ -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),