diff options
Diffstat (limited to 'libview')
-rw-r--r-- | libview/Makefile.am | 4 | ||||
-rw-r--r-- | libview/ev-document-model.c | 416 | ||||
-rw-r--r-- | libview/ev-document-model.h | 75 | ||||
-rw-r--r-- | libview/ev-page-cache.c | 168 | ||||
-rw-r--r-- | libview/ev-page-cache.h | 51 | ||||
-rw-r--r-- | libview/ev-pixbuf-cache.c | 25 | ||||
-rw-r--r-- | libview/ev-view-private.h | 7 | ||||
-rw-r--r-- | libview/ev-view.c | 301 | ||||
-rw-r--r-- | libview/ev-view.h | 16 |
9 files changed, 673 insertions, 390 deletions
diff --git a/libview/Makefile.am b/libview/Makefile.am index d9e4c08..1964eee 100644 --- a/libview/Makefile.am +++ b/libview/Makefile.am @@ -10,9 +10,9 @@ NOINST_H_FILES = \ ev-view-private.h INST_H_FILES = \ + ev-document-model.h \ ev-jobs.h \ ev-job-scheduler.h \ - ev-page-cache.h \ ev-stock-icons.h \ ev-view.h \ ev-view-type-builtins.h @@ -22,9 +22,9 @@ header_DATA = $(INST_H_FILES) libevview_la_SOURCES = \ ev-annotation-window.c \ + ev-document-model.c \ ev-jobs.c \ ev-job-scheduler.c \ - ev-page-cache.c \ ev-pixbuf-cache.c \ ev-stock-icons.c \ ev-timeline.c \ diff --git a/libview/ev-document-model.c b/libview/ev-document-model.c new file mode 100644 index 0000000..a850e84 --- /dev/null +++ b/libview/ev-document-model.c @@ -0,0 +1,416 @@ +/* this file is part of evince, a gnome document viewer + * + * Copyright (C) 2009 Carlos Garcia Campos + * Copyright (C) 2005 Red Hat, Inc + * + * Evince 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 of the License, or + * (at your option) any later version. + * + * Evince 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-document-model.h" +#include "ev-view-type-builtins.h" +#include "ev-view-marshal.h" + +struct _EvDocumentModel +{ + GObject base; + + EvDocument *document; + gint n_pages; + + gint page; + gint rotation; + gdouble scale; + EvSizingMode sizing_mode; + + gdouble max_scale; + gdouble min_scale; +}; + +struct _EvDocumentModelClass +{ + GObjectClass base_class; + + /* Signals */ + void (* page_changed) (EvDocumentModel *model, + gint old_page, + gint new_page); +}; + +enum { + PROP_0, + PROP_DOCUMENT, + PROP_PAGE, + PROP_ROTATION, + PROP_SCALE, + PROP_SIZING_MODE +}; + +enum +{ + PAGE_CHANGED, + N_SIGNALS +}; + +static guint signals[N_SIGNALS] = { 0 }; + +G_DEFINE_TYPE (EvDocumentModel, ev_document_model, G_TYPE_OBJECT) + +static void +ev_document_model_finalize (GObject *object) +{ + EvDocumentModel *model = EV_DOCUMENT_MODEL (object); + + if (model->document) { + g_object_unref (model->document); + model->document = NULL; + } + + G_OBJECT_CLASS (ev_document_model_parent_class)->finalize (object); +} + +static void +ev_document_model_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + EvDocumentModel *model = EV_DOCUMENT_MODEL (object); + + switch (prop_id) { + case PROP_DOCUMENT: + ev_document_model_set_document (model, (EvDocument *)g_value_get_object (value)); + break; + case PROP_PAGE: + ev_document_model_set_page (model, g_value_get_int (value)); + break; + case PROP_ROTATION: + ev_document_model_set_rotation (model, g_value_get_int (value)); + break; + case PROP_SCALE: + ev_document_model_set_scale (model, g_value_get_double (value)); + break; + case PROP_SIZING_MODE: + ev_document_model_set_sizing_mode (model, g_value_get_enum (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +ev_document_model_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + EvDocumentModel *model = EV_DOCUMENT_MODEL (object); + + switch (prop_id) { + case PROP_DOCUMENT: + g_value_set_object (value, model->document); + break; + case PROP_PAGE: + g_value_set_int (value, model->page); + break; + case PROP_ROTATION: + g_value_set_int (value, model->rotation); + break; + case PROP_SCALE: + g_value_set_double (value, model->scale); + break; + case PROP_SIZING_MODE: + g_value_set_enum (value, model->sizing_mode); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static void +ev_document_model_class_init (EvDocumentModelClass *klass) +{ + GObjectClass *g_object_class = G_OBJECT_CLASS (klass); + + g_object_class->get_property = ev_document_model_get_property; + g_object_class->set_property = ev_document_model_set_property; + g_object_class->finalize = ev_document_model_finalize; + + /* Properties */ + g_object_class_install_property (g_object_class, + PROP_DOCUMENT, + g_param_spec_object ("document", + "Document", + "The current document", + EV_TYPE_DOCUMENT, + G_PARAM_READWRITE)); + g_object_class_install_property (g_object_class, + PROP_PAGE, + g_param_spec_int ("page", + "Page", + "Current page", + -1, G_MAXINT, -1, + G_PARAM_READWRITE)); + g_object_class_install_property (g_object_class, + PROP_ROTATION, + g_param_spec_int ("rotation", + "Rotation", + "Current rotation angle", + 0, 360, 0, + G_PARAM_READWRITE)); + g_object_class_install_property (g_object_class, + PROP_SCALE, + g_param_spec_double ("scale", + "Scale", + "Current scale factor", + 0., G_MAXDOUBLE, 1., + G_PARAM_READWRITE)); + g_object_class_install_property (g_object_class, + PROP_SIZING_MODE, + g_param_spec_enum ("sizing-mode", + "Sizing Mode", + "Current sizing mode", + EV_TYPE_SIZING_MODE, + EV_SIZING_FIT_WIDTH, + G_PARAM_READWRITE)); + + /* Signals */ + signals [PAGE_CHANGED] = + g_signal_new ("page-changed", + EV_TYPE_DOCUMENT_MODEL, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (EvDocumentModelClass, page_changed), + NULL, NULL, + ev_view_marshal_VOID__INT_INT, + G_TYPE_NONE, 2, + G_TYPE_INT, G_TYPE_INT); +} + +static void +ev_document_model_init (EvDocumentModel *model) +{ + model->page = -1; + model->scale = 1.; + model->sizing_mode = EV_SIZING_FIT_WIDTH; + model->min_scale = 0.; + model->max_scale = G_MAXDOUBLE; +} + +EvDocumentModel * +ev_document_model_new (void) +{ + return g_object_new (EV_TYPE_DOCUMENT_MODEL, NULL); +} + +EvDocumentModel * +ev_document_model_new_with_document (EvDocument *document) +{ + g_return_val_if_fail (EV_IS_DOCUMENT (document), NULL); + + return g_object_new (EV_TYPE_DOCUMENT_MODEL, "document", document, NULL); +} + +void +ev_document_model_set_document (EvDocumentModel *model, + EvDocument *document) +{ + g_return_if_fail (EV_IS_DOCUMENT_MODEL (model)); + g_return_if_fail (EV_IS_DOCUMENT (document)); + + if (document == model->document) + return; + + if (model->document) + g_object_unref (model->document); + model->document = g_object_ref (document); + + model->n_pages = ev_document_get_n_pages (document); + ev_document_model_set_page (model, CLAMP (model->page, 0, + model->n_pages - 1)); + + g_object_notify (G_OBJECT (model), "document"); +} + +EvDocument * +ev_document_model_get_document (EvDocumentModel *model) +{ + g_return_val_if_fail (EV_IS_DOCUMENT_MODEL (model), NULL); + + return model->document; +} + +void +ev_document_model_set_page (EvDocumentModel *model, + gint page) +{ + gint old_page; + + g_return_if_fail (EV_IS_DOCUMENT_MODEL (model)); + + if (model->page == page) + return; + if (page < 0 || (model->document && page >= model->n_pages)) + return; + + old_page = model->page; + model->page = page; + g_signal_emit (model, signals[PAGE_CHANGED], 0, old_page, page); + + g_object_notify (G_OBJECT (model), "page"); +} + +void +ev_document_model_set_page_by_label (EvDocumentModel *model, + const gchar *page_label) +{ + gint page; + + g_return_if_fail (EV_IS_DOCUMENT_MODEL (model)); + g_return_if_fail (model->document != NULL); + + if (ev_document_find_page_by_label (model->document, page_label, &page)) + ev_document_model_set_page (model, page); +} + +gint +ev_document_model_get_page (EvDocumentModel *model) +{ + g_return_val_if_fail (EV_IS_DOCUMENT_MODEL (model), -1); + + return model->page; +} + +void +ev_document_model_set_scale (EvDocumentModel *model, + gdouble scale) +{ + g_return_if_fail (EV_IS_DOCUMENT_MODEL (model)); + + scale = CLAMP (scale, + model->sizing_mode == EV_SIZING_FREE ? + model->min_scale : 0, model->max_scale); + + if (scale == model->scale) + return; + + model->scale = scale; + + g_object_notify (G_OBJECT (model), "scale"); +} + +gdouble +ev_document_model_get_scale (EvDocumentModel *model) +{ + g_return_val_if_fail (EV_IS_DOCUMENT_MODEL (model), 1.0); + + return model->scale; +} + +void +ev_document_model_set_max_scale (EvDocumentModel *model, + gdouble max_scale) +{ + g_return_if_fail (EV_IS_DOCUMENT_MODEL (model)); + + if (max_scale == model->max_scale) + return; + + model->max_scale = max_scale; + + if (model->scale > max_scale) + ev_document_model_set_scale (model, max_scale); +} + +gdouble +ev_document_model_get_max_scale (EvDocumentModel *model) +{ + g_return_val_if_fail (EV_IS_DOCUMENT_MODEL (model), 1.0); + + return model->max_scale; +} + +void +ev_document_model_set_min_scale (EvDocumentModel *model, + gdouble min_scale) +{ + g_return_if_fail (EV_IS_DOCUMENT_MODEL (model)); + + if (min_scale == model->min_scale) + return; + + model->min_scale = min_scale; + + if (model->scale < min_scale) + ev_document_model_set_scale (model, min_scale); +} + +gdouble +ev_document_model_get_min_scale (EvDocumentModel *model) +{ + g_return_val_if_fail (EV_IS_DOCUMENT_MODEL (model), 0.); + + return model->min_scale; +} + +void +ev_document_model_set_sizing_mode (EvDocumentModel *model, + EvSizingMode mode) +{ + g_return_if_fail (EV_IS_DOCUMENT_MODEL (model)); + + if (mode == model->sizing_mode) + return; + + model->sizing_mode = mode; + + g_object_notify (G_OBJECT (model), "sizing-mode"); +} + +EvSizingMode +ev_document_model_get_sizing_mode (EvDocumentModel *model) +{ + g_return_val_if_fail (EV_IS_DOCUMENT_MODEL (model), EV_SIZING_FIT_WIDTH); + + return model->sizing_mode; +} + +void +ev_document_model_set_rotation (EvDocumentModel *model, + gint rotation) +{ + g_return_if_fail (EV_IS_DOCUMENT_MODEL (model)); + + if (rotation >= 360) + rotation -= 360; + else if (rotation < 0) + rotation += 360; + + if (rotation == model->rotation) + return; + + model->rotation = rotation; + + g_object_notify (G_OBJECT (model), "rotation"); +} + +gint +ev_document_model_get_rotation (EvDocumentModel *model) +{ + g_return_val_if_fail (EV_IS_DOCUMENT_MODEL (model), 0); + + return model->rotation; +} + diff --git a/libview/ev-document-model.h b/libview/ev-document-model.h new file mode 100644 index 0000000..14c960a --- /dev/null +++ b/libview/ev-document-model.h @@ -0,0 +1,75 @@ +/* this file is part of evince, a gnome document viewer + * + * Copyright (C) 2009 Carlos Garcia Campos + * + * Evince 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 of the License, or + * (at your option) any later version. + * + * Evince 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. + */ + +#if !defined (__EV_EVINCE_VIEW_H_INSIDE__) && !defined (EVINCE_COMPILATION) +#error "Only <evince-view.h> can be included directly." +#endif + +#ifndef __EV_DOCUMENT_MODEL_H__ +#define __EV_DOCUMENT_MODEL_H__ + +#include <glib-object.h> +#include <evince-document.h> + +G_BEGIN_DECLS + +#define EV_TYPE_DOCUMENT_MODEL (ev_document_model_get_type ()) +#define EV_DOCUMENT_MODEL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EV_TYPE_DOCUMENT_MODEL, EvDocumentModel)) +#define EV_IS_DOCUMENT_MODEL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EV_TYPE_DOCUMENT_MODEL)) + +typedef enum { + EV_SIZING_BEST_FIT, + EV_SIZING_FIT_WIDTH, + EV_SIZING_FREE, +} EvSizingMode; + +typedef struct _EvDocumentModel EvDocumentModel; +typedef struct _EvDocumentModelClass EvDocumentModelClass; + +GType ev_document_model_get_type (void) G_GNUC_CONST; +EvDocumentModel *ev_document_model_new (void); +EvDocumentModel *ev_document_model_new_with_document (EvDocument *document); + +void ev_document_model_set_document (EvDocumentModel *model, + EvDocument *document); +EvDocument *ev_document_model_get_document (EvDocumentModel *model); +void ev_document_model_set_page (EvDocumentModel *model, + gint page); +void ev_document_model_set_page_by_label (EvDocumentModel *model, + const gchar *page_label); +gint ev_document_model_get_page (EvDocumentModel *model); +void ev_document_model_set_scale (EvDocumentModel *model, + gdouble scale); +gdouble ev_document_model_get_scale (EvDocumentModel *model); +void ev_document_model_set_max_scale (EvDocumentModel *model, + gdouble max_scale); +gdouble ev_document_model_get_max_scale (EvDocumentModel *model); +void ev_document_model_set_min_scale (EvDocumentModel *model, + gdouble min_scale); +gdouble ev_document_model_get_min_scale (EvDocumentModel *model); +void ev_document_model_set_sizing_mode (EvDocumentModel *model, + EvSizingMode mode); +EvSizingMode ev_document_model_get_sizing_mode (EvDocumentModel *model); +void ev_document_model_set_rotation (EvDocumentModel *model, + gint rotation); +gint ev_document_model_get_rotation (EvDocumentModel *model); + +G_END_DECLS + +#endif /* __EV_DOCUMENT_MODEL_H__ */ diff --git a/libview/ev-page-cache.c b/libview/ev-page-cache.c deleted file mode 100644 index 8fba8c6..0000000 --- a/libview/ev-page-cache.c +++ /dev/null @@ -1,168 +0,0 @@ -#include <config.h> -#include "ev-page-cache.h" -#include "ev-document-thumbnails.h" -#include "ev-page.h" -#include <stdlib.h> -#include <string.h> - -struct _EvPageCache -{ - GObject parent; - - EvDocument *document; - - gint current_page; - - gboolean dual_even_left; - - int rotation; -}; - -struct _EvPageCacheClass -{ - GObjectClass parent_class; - - void (* page_changed) (EvPageCache *page_cache, gint page); - void (* history_changed) (EvPageCache *page_cache, gint page); -}; - -enum -{ - PAGE_CHANGED, - HISTORY_CHANGED, - N_SIGNALS, -}; - -static guint signals[N_SIGNALS] = {0, }; - -static void ev_page_cache_init (EvPageCache *page_cache); -static void ev_page_cache_class_init (EvPageCacheClass *page_cache); -static void ev_page_cache_finalize (GObject *object); - -G_DEFINE_TYPE (EvPageCache, ev_page_cache, G_TYPE_OBJECT) - -static void -ev_page_cache_init (EvPageCache *page_cache) -{ - page_cache->current_page = -1; -} - -static void -ev_page_cache_class_init (EvPageCacheClass *class) -{ - GObjectClass *object_class; - - object_class = G_OBJECT_CLASS (class); - - object_class->finalize = ev_page_cache_finalize; - - signals [PAGE_CHANGED] = - g_signal_new ("page-changed", - EV_TYPE_PAGE_CACHE, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EvPageCacheClass, page_changed), - NULL, NULL, - g_cclosure_marshal_VOID__INT, - G_TYPE_NONE, 1, - G_TYPE_INT); - - signals [HISTORY_CHANGED] = - g_signal_new ("history-changed", - EV_TYPE_PAGE_CACHE, - G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (EvPageCacheClass, history_changed), - NULL, NULL, - g_cclosure_marshal_VOID__INT, - G_TYPE_NONE, 1, - G_TYPE_INT); - -} - -static void -ev_page_cache_finalize (GObject *object) -{ - EvPageCache *page_cache = EV_PAGE_CACHE (object); - - page_cache->document = NULL; - - G_OBJECT_CLASS (ev_page_cache_parent_class)->finalize (object); -} - -static EvPageCache * -ev_page_cache_new (EvDocument *document) -{ - EvPageCache *page_cache; - - page_cache = (EvPageCache *) g_object_new (EV_TYPE_PAGE_CACHE, NULL); - page_cache->document = document; - - if (ev_document_get_n_pages (page_cache->document) > 0) - ev_page_cache_set_current_page (page_cache, 0); - - return page_cache; -} - -gint -ev_page_cache_get_current_page (EvPageCache *page_cache) -{ - g_return_val_if_fail (EV_IS_PAGE_CACHE (page_cache), 0); - - return page_cache->current_page; -} - -void -ev_page_cache_set_current_page (EvPageCache *page_cache, - int page) -{ - g_return_if_fail (EV_IS_PAGE_CACHE (page_cache)); - - if (page == page_cache->current_page) - return; - - page_cache->current_page = page; - g_signal_emit (page_cache, signals[PAGE_CHANGED], 0, page); -} - -void -ev_page_cache_set_current_page_history (EvPageCache *page_cache, - int page) -{ - if (abs (page - page_cache->current_page) > 1) - g_signal_emit (page_cache, signals [HISTORY_CHANGED], 0, page); - - ev_page_cache_set_current_page (page_cache, page); -} - -gboolean -ev_page_cache_set_page_label (EvPageCache *page_cache, - const gchar *page_label) -{ - gint page; - - g_return_val_if_fail (EV_IS_PAGE_CACHE (page_cache), FALSE); - - if (ev_document_find_page_by_label (page_cache->document, page_label, &page)) { - ev_page_cache_set_current_page (page_cache, page); - return TRUE; - } - - return FALSE; -} - -#define PAGE_CACHE_STRING "ev-page-cache" - -EvPageCache * -ev_page_cache_get (EvDocument *document) -{ - EvPageCache *page_cache; - - g_return_val_if_fail (EV_IS_DOCUMENT (document), NULL); - - page_cache = g_object_get_data (G_OBJECT (document), PAGE_CACHE_STRING); - if (page_cache == NULL) { - page_cache = ev_page_cache_new (document); - g_object_set_data_full (G_OBJECT (document), PAGE_CACHE_STRING, page_cache, g_object_unref); - } - - return page_cache; -} diff --git a/libview/ev-page-cache.h b/libview/ev-page-cache.h deleted file mode 100644 index 82e2791..0000000 --- a/libview/ev-page-cache.h +++ /dev/null @@ -1,51 +0,0 @@ -/* this file is part of evince, a gnome document viewer - * - * Copyright (C) 2005 Red Hat, Inc - * - * Evince 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 of the License, or - * (at your option) any later version. - * - * Evince 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. - */ - -#if !defined (__EV_EVINCE_VIEW_H_INSIDE__) && !defined (EVINCE_COMPILATION) -#error "Only <evince-view.h> can be included directly." -#endif - -#ifndef __EV_PAGE_CACHE_H__ -#define __EV_PAGE_CACHE_H__ - -#include <gtk/gtk.h> - -#include <evince-document.h> - -G_BEGIN_DECLS -#define EV_TYPE_PAGE_CACHE (ev_page_cache_get_type ()) -#define EV_PAGE_CACHE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EV_TYPE_PAGE_CACHE, EvPageCache)) -#define EV_IS_PAGE_CACHE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EV_TYPE_PAGE_CACHE)) - -GType ev_page_cache_get_type (void) G_GNUC_CONST; - -/* Navigation */ -gint ev_page_cache_get_current_page (EvPageCache *page_cache); -void ev_page_cache_set_current_page (EvPageCache *page_cache, - int page); -void ev_page_cache_set_current_page_history (EvPageCache *page_cache, - int page); -gboolean ev_page_cache_set_page_label (EvPageCache *page_cache, - const gchar *page_label); - -EvPageCache *ev_page_cache_get (EvDocument *document); - -G_END_DECLS - -#endif /* __EV_PAGE_CACHE_H__ */ diff --git a/libview/ev-pixbuf-cache.c b/libview/ev-pixbuf-cache.c index 0ebfeae..df06705 100644 --- a/libview/ev-pixbuf-cache.c +++ b/libview/ev-pixbuf-cache.c @@ -1,7 +1,6 @@ #include <config.h> #include "ev-pixbuf-cache.h" #include "ev-job-scheduler.h" -#include "ev-page-cache.h" #include "ev-mapping.h" #include "ev-document-forms.h" #include "ev-document-images.h" @@ -291,9 +290,8 @@ job_finished_cb (EvJob *job, */ static void check_job_size_and_unref (EvPixbufCache *pixbuf_cache, - CacheJobInfo *job_info, - EvPageCache *page_cache, - gfloat scale) + CacheJobInfo *job_info, + gfloat scale) { gint width, height; @@ -586,18 +584,15 @@ static void ev_pixbuf_cache_clear_job_sizes (EvPixbufCache *pixbuf_cache, gfloat scale) { - EvPageCache *page_cache; int i; - page_cache = ev_page_cache_get (pixbuf_cache->document); - for (i = 0; i < PAGE_CACHE_LEN (pixbuf_cache); i++) { - check_job_size_and_unref (pixbuf_cache, pixbuf_cache->job_list + i, page_cache, scale); + check_job_size_and_unref (pixbuf_cache, pixbuf_cache->job_list + i, scale); } for (i = 0; i < pixbuf_cache->preload_cache_size; i++) { - check_job_size_and_unref (pixbuf_cache, pixbuf_cache->prev_job + i, page_cache, scale); - check_job_size_and_unref (pixbuf_cache, pixbuf_cache->next_job + i, page_cache, scale); + check_job_size_and_unref (pixbuf_cache, pixbuf_cache->prev_job + i, scale); + check_job_size_and_unref (pixbuf_cache, pixbuf_cache->next_job + i, scale); } } @@ -672,7 +667,6 @@ add_job (EvPixbufCache *pixbuf_cache, static void add_job_if_needed (EvPixbufCache *pixbuf_cache, CacheJobInfo *job_info, - EvPageCache *page_cache, gint page, gint rotation, gfloat scale, @@ -702,19 +696,16 @@ ev_pixbuf_cache_add_jobs_if_needed (EvPixbufCache *pixbuf_cache, gint rotation, gfloat scale) { - EvPageCache *page_cache; CacheJobInfo *job_info; int page; int i; - page_cache = ev_page_cache_get (pixbuf_cache->document); - for (i = 0; i < PAGE_CACHE_LEN (pixbuf_cache); i++) { job_info = (pixbuf_cache->job_list + i); page = pixbuf_cache->start_page + i; add_job_if_needed (pixbuf_cache, job_info, - page_cache, page, rotation, scale, + page, rotation, scale, EV_JOB_PRIORITY_URGENT); } @@ -723,7 +714,7 @@ ev_pixbuf_cache_add_jobs_if_needed (EvPixbufCache *pixbuf_cache, page = pixbuf_cache->start_page - pixbuf_cache->preload_cache_size + i; add_job_if_needed (pixbuf_cache, job_info, - page_cache, page, rotation, scale, + page, rotation, scale, EV_JOB_PRIORITY_LOW); } @@ -732,7 +723,7 @@ ev_pixbuf_cache_add_jobs_if_needed (EvPixbufCache *pixbuf_cache, page = pixbuf_cache->end_page + 1 + i; add_job_if_needed (pixbuf_cache, job_info, - page_cache, page, rotation, scale, + page, rotation, scale, EV_JOB_PRIORITY_LOW); } diff --git a/libview/ev-view-private.h b/libview/ev-view-private.h index 2f01f72..a2710a9 100644 --- a/libview/ev-view-private.h +++ b/libview/ev-view-private.h @@ -26,8 +26,8 @@ #define __EV_VIEW_PRIVATE_H__ #include "ev-view.h" +#include "ev-document-model.h" #include "ev-pixbuf-cache.h" -#include "ev-page-cache.h" #include "ev-jobs.h" #include "ev-image.h" #include "ev-form-field.h" @@ -133,7 +133,8 @@ struct _EvView { gint find_result; gboolean jump_to_find_result; gboolean highlight_find_results; - + + EvDocumentModel *model; EvPageCache *page_cache; EvPixbufCache *pixbuf_cache; EvHeightToPageCache *height_to_page_cache; @@ -161,8 +162,6 @@ struct _EvView { gdouble scale; gint spacing; gdouble dpi; - gdouble max_scale; - gdouble min_scale; gboolean loading; gboolean continuous; diff --git a/libview/ev-view.c b/libview/ev-view.c index b2fb610..50e4f72 100644 --- a/libview/ev-view.c +++ b/libview/ev-view.c @@ -34,7 +34,6 @@ #include "ev-document-links.h" #include "ev-document-misc.h" #include "ev-document-transition.h" -#include "ev-page-cache.h" #include "ev-pixbuf-cache.h" #include "ev-transition-animation.h" #include "ev-view-marshal.h" @@ -85,9 +84,6 @@ typedef enum { #define ZOOM_IN_FACTOR 1.2 #define ZOOM_OUT_FACTOR (1.0/ZOOM_IN_FACTOR) -#define MIN_SCALE 0.05409 -#define MAX_SCALE 4.0 - #define SCROLL_TIME 150 /*** Scrolling ***/ @@ -219,8 +215,9 @@ static void ev_view_reload_page (EvView static void job_finished_cb (EvPixbufCache *pixbuf_cache, GdkRegion *region, EvView *view); -static void page_changed_cb (EvPageCache *page_cache, - int new_page, +static void ev_view_page_changed_cb (EvDocumentModel *model, + gint old_page, + gint new_page, EvView *view); static void on_adjustment_value_changed (GtkAdjustment *adjustment, EvView *view); @@ -663,11 +660,11 @@ view_update_range_and_current_page (EvView *view) } best_current_page = MAX (best_current_page, view->start_page); - current_page = ev_page_cache_get_current_page (view->page_cache); + current_page = ev_document_model_get_page (view->model); if ((current_page != best_current_page) && (view->pending_scroll == SCROLL_TO_KEEP_POSITION)) { view->current_page = best_current_page; - ev_page_cache_set_current_page (view->page_cache, best_current_page); + ev_document_model_set_page (view->model, best_current_page); } if (start != view->start_page || end != view->end_page) { @@ -1218,7 +1215,7 @@ find_page_at_location (EvView *view, g_assert (x_offset); g_assert (y_offset); - for (i = view->start_page; i <= view->end_page; i++) { + for (i = view->start_page; i >= 0 && i <= view->end_page; i++) { GdkRectangle page_area; GtkBorder border; @@ -1411,8 +1408,8 @@ goto_fitr_dest (EvView *view, EvLinkDest *dest) ev_view_get_width (view), ev_view_get_height (view)); - ev_view_set_sizing_mode (view, EV_SIZING_FREE); - ev_view_set_zoom (view, zoom, FALSE); + ev_document_model_set_sizing_mode (view->model, EV_SIZING_FREE); + ev_document_model_set_scale (view->model, zoom); doc_point.x = change_left ? left : 0; doc_point.y = change_top ? top : 0; @@ -1445,8 +1442,8 @@ goto_fitv_dest (EvView *view, EvLinkDest *dest) ev_view_get_width (view), ev_view_get_height (view)); - ev_view_set_sizing_mode (view, EV_SIZING_FREE); - ev_view_set_zoom (view, zoom, FALSE); + ev_document_model_set_sizing_mode (view->model, EV_SIZING_FREE); + ev_document_model_set_scale (view->model, zoom); view->current_page = page; if (change_left) @@ -1477,8 +1474,8 @@ goto_fith_dest (EvView *view, EvLinkDest *dest) ev_view_get_width (view), ev_view_get_height (view)); - ev_view_set_sizing_mode (view, EV_SIZING_FIT_WIDTH); - ev_view_set_zoom (view, zoom, FALSE); + ev_document_model_set_sizing_mode (view->model, EV_SIZING_FIT_WIDTH); + ev_document_model_set_scale (view->model, zoom); view->current_page = page; if (change_top) @@ -1502,8 +1499,8 @@ goto_fit_dest (EvView *view, EvLinkDest *dest) ev_view_get_width (view), ev_view_get_height (view)); - ev_view_set_sizing_mode (view, EV_SIZING_BEST_FIT); - ev_view_set_zoom (view, zoom, FALSE); + ev_document_model_set_sizing_mode (view->model, EV_SIZING_BEST_FIT); + ev_document_model_set_scale (view->model, zoom); view->current_page = page; view->pending_scroll = SCROLL_TO_PAGE_POSITION; @@ -1523,8 +1520,8 @@ goto_xyz_dest (EvView *view, EvLinkDest *dest) page = ev_link_dest_get_page (dest); if (change_zoom && zoom > 1) { - ev_view_set_sizing_mode (view, EV_SIZING_FREE); - ev_view_set_zoom (view, zoom, FALSE); + ev_document_model_set_sizing_mode (view->model, EV_SIZING_FREE); + ev_document_model_set_scale (view->model, zoom); } left = ev_link_dest_get_left (dest, &change_left); @@ -1559,7 +1556,7 @@ goto_dest (EvView *view, EvLinkDest *dest) switch (type) { case EV_LINK_DEST_TYPE_PAGE: - ev_page_cache_set_current_page (view->page_cache, page); + ev_document_model_set_page (view->model, page); break; case EV_LINK_DEST_TYPE_FIT: goto_fit_dest (view, dest); @@ -1577,15 +1574,14 @@ goto_dest (EvView *view, EvLinkDest *dest) goto_xyz_dest (view, dest); break; case EV_LINK_DEST_TYPE_PAGE_LABEL: - ev_page_cache_set_page_label (view->page_cache, ev_link_dest_get_page_label (dest)); + ev_document_model_set_page_by_label (view->model, ev_link_dest_get_page_label (dest)); break; default: g_assert_not_reached (); } if (current_page != view->current_page) - ev_page_cache_set_current_page (view->page_cache, - view->current_page); + ev_document_model_set_page (view->model, view->current_page); } static void @@ -3085,7 +3081,7 @@ ev_view_expose_event (GtkWidget *widget, cr = gdk_cairo_create (view->layout.bin_window); - for (i = view->start_page; i <= view->end_page; i++) { + for (i = view->start_page; i >= 0 && i <= view->end_page; i++) { GdkRectangle page_area; GtkBorder border; gboolean page_ready = TRUE; @@ -3881,8 +3877,9 @@ ev_view_goto_entry_activate (GtkEntry *entry, ev_view_goto_window_hide (view); - if (page >= 0 && page < ev_document_get_n_pages (view->document)) - ev_page_cache_set_current_page (view->page_cache, page); + if (page >= 0 && page < ev_document_get_n_pages (view->document)) { + ev_document_model_set_page (view->model, page); + } } static void @@ -4296,7 +4293,7 @@ draw_one_page (EvView *view, if (!view->presentation) { gint current_page; - current_page = ev_page_cache_get_current_page (view->page_cache); + current_page = ev_document_model_get_page (view->model); ev_document_misc_paint_one_page (view->layout.bin_window, GTK_WIDGET (view), page_area, border, @@ -4406,6 +4403,11 @@ ev_view_destroy (GtkObject *object) { EvView *view = EV_VIEW (object); + if (view->model) { + g_object_unref (view->model); + view->model = NULL; + } + if (view->document) { g_object_unref (view->document); view->document = NULL; @@ -4486,7 +4488,7 @@ ev_view_set_property (GObject *object, ev_view_set_sizing_mode (view, g_value_get_enum (value)); break; case PROP_ZOOM: - ev_view_set_zoom (view, g_value_get_double (value), FALSE); + ev_view_set_zoom (view, g_value_get_double (value)); break; case PROP_ROTATION: ev_view_set_rotation (view, g_value_get_int (value)); @@ -4697,6 +4699,7 @@ ev_view_class_init (EvViewClass *class) 360, 0, G_PARAM_READWRITE)); + g_object_class_install_property (object_class, PROP_HAS_SELECTION, g_param_spec_boolean ("has-selection", @@ -4861,10 +4864,14 @@ job_finished_cb (EvPixbufCache *pixbuf_cache, } static void -page_changed_cb (EvPageCache *page_cache, - int new_page, - EvView *view) +ev_view_page_changed_cb (EvDocumentModel *model, + gint old_page, + gint new_page, + EvView *view) { + if (!view->document) + return; + if (view->current_page != new_page) { if (view->presentation) ev_view_presentation_animation_start (view, new_page); @@ -4949,14 +4956,9 @@ ev_view_new (void) static void setup_caches (EvView *view) { - view->page_cache = ev_page_cache_get (view->document); view->height_to_page_cache = ev_view_get_height_to_page_cache (view); - g_signal_connect (view->page_cache, "page-changed", G_CALLBACK (page_changed_cb), view); view->pixbuf_cache = ev_pixbuf_cache_new (GTK_WIDGET (view), view->document); g_signal_connect (view->pixbuf_cache, "job-finished", G_CALLBACK (job_finished_cb), view); - page_changed_cb (view->page_cache, - ev_page_cache_get_current_page (view->page_cache), - view); } static void @@ -4966,10 +4968,6 @@ clear_caches (EvView *view) g_object_unref (view->pixbuf_cache); view->pixbuf_cache = NULL; } - - if (view->page_cache) { - view->page_cache = NULL; - } } void @@ -5053,20 +5051,20 @@ ev_view_autoscroll_stop (EvView *view) ev_view_handle_cursor_over_xy (view, x, y); } -void -ev_view_set_document (EvView *view, - EvDocument *document) +static void +ev_view_document_changed_cb (EvDocumentModel *model, + GParamSpec *pspec, + EvView *view) { - g_return_if_fail (EV_IS_VIEW (view)); + EvDocument *document = ev_document_model_get_document (model); view->loading = FALSE; - + if (document != view->document) { clear_caches (view); if (view->document) { g_object_unref (view->document); - view->page_cache = NULL; } view->document = document; @@ -5077,10 +5075,100 @@ ev_view_set_document (EvView *view, setup_caches (view); } - view_update_range_and_current_page (view); + ev_view_change_page (view, + ev_document_model_get_page (model), + TRUE); + } +} + +static void +ev_view_rotation_changed_cb (EvDocumentModel *model, + GParamSpec *pspec, + EvView *view) +{ + gint rotation = ev_document_model_get_rotation (model); + + ev_view_set_rotation (view, rotation); + + if (view->pixbuf_cache) { + ev_pixbuf_cache_clear (view->pixbuf_cache); + gtk_widget_queue_resize (GTK_WIDGET (view)); + } + + if (rotation != 0) + clear_selection (view); +} + +static void +ev_view_sizing_mode_changed_cb (EvDocumentModel *model, + GParamSpec *pspec, + EvView *view) +{ + EvSizingMode mode = ev_document_model_get_sizing_mode (model); + + ev_view_set_sizing_mode (view, mode); + if (mode != EV_SIZING_FREE) gtk_widget_queue_resize (GTK_WIDGET (view)); +} + +#define EPSILON 0.0000001 +static void +ev_view_scale_changed_cb (EvDocumentModel *model, + GParamSpec *pspec, + EvView *view) +{ + gdouble scale = ev_document_model_get_scale (model); + + if (ABS (view->scale - scale) < EPSILON) + return; + + if (view->loading_text) { + cairo_surface_destroy (view->loading_text); + view->loading_text = NULL; } + + ev_view_set_zoom (view, scale); + + view->pending_resize = TRUE; + gtk_widget_queue_resize (GTK_WIDGET (view)); +} + +void +ev_view_set_model (EvView *view, + EvDocumentModel *model) +{ + g_return_if_fail (EV_IS_VIEW (view)); + g_return_if_fail (EV_IS_DOCUMENT_MODEL (model)); + + if (model == view->model) + return; + + if (view->model) { + g_signal_handlers_disconnect_by_func (view->model, + ev_view_document_changed_cb, + view); + g_signal_handlers_disconnect_by_func (view->model, + ev_view_page_changed_cb, + view); + g_object_unref (view->model); + } + view->model = g_object_ref (model); + g_signal_connect (view->model, "notify::document", + G_CALLBACK (ev_view_document_changed_cb), + view); + g_signal_connect (view->model, "notify::rotation", + G_CALLBACK (ev_view_rotation_changed_cb), + view); + g_signal_connect (view->model, "notify::sizing-mode", + G_CALLBACK (ev_view_sizing_mode_changed_cb), + view); + g_signal_connect (view->model, "notify::scale", + G_CALLBACK (ev_view_scale_changed_cb), + view); + g_signal_connect (view->model, "page-changed", + G_CALLBACK (ev_view_page_changed_cb), + view); } static void @@ -5104,38 +5192,11 @@ ev_view_reload (EvView *view) /*** Zoom and sizing mode ***/ -#define EPSILON 0.0000001 void ev_view_set_zoom (EvView *view, - double factor, - gboolean relative) + double scale) { - double scale; - - if (relative) - scale = view->scale * factor; - else - scale = factor; - - scale = CLAMP (scale, - view->sizing_mode == EV_SIZING_FREE ? view->min_scale : 0, - view->max_scale); - - if (scale == view->scale) - return; - - if (ABS (view->scale - scale) < EPSILON) - return; - - if (view->loading_text) { - cairo_surface_destroy (view->loading_text); - view->loading_text = NULL; - } - view->scale = scale; - view->pending_resize = TRUE; - - gtk_widget_queue_resize (GTK_WIDGET (view)); g_object_notify (G_OBJECT (view), "zoom"); } @@ -5154,8 +5215,6 @@ ev_view_set_screen_dpi (EvView *view, g_return_if_fail (dpi > 0); view->dpi = dpi; - view->min_scale = MIN_SCALE * dpi / 72.0; - view->max_scale = MAX_SCALE * dpi / 72.0; } gboolean @@ -5259,8 +5318,8 @@ ev_view_set_presentation (EvView *view, view->scale_saved = view->scale; ev_view_set_sizing_mode (view, EV_SIZING_BEST_FIT); } else { - ev_view_set_sizing_mode (view, view->sizing_mode_saved); - ev_view_set_zoom (view, view->scale_saved, FALSE); + ev_document_model_set_sizing_mode (view->model, view->sizing_mode_saved); + ev_document_model_set_scale (view->model, view->scale_saved); } gtk_widget_queue_resize (GTK_WIDGET (view)); @@ -5336,13 +5395,7 @@ void ev_view_set_sizing_mode (EvView *view, EvSizingMode sizing_mode) { - g_return_if_fail (EV_IS_VIEW (view)); - - if (view->sizing_mode == sizing_mode) - return; - view->sizing_mode = sizing_mode; - gtk_widget_queue_resize (GTK_WIDGET (view)); g_object_notify (G_OBJECT (view), "sizing-mode"); } @@ -5358,61 +5411,43 @@ ev_view_get_sizing_mode (EvView *view) gboolean ev_view_can_zoom_in (EvView *view) { - return view->scale * ZOOM_IN_FACTOR <= view->max_scale; + return view->scale * ZOOM_IN_FACTOR <= ev_document_model_get_max_scale (view->model); } gboolean ev_view_can_zoom_out (EvView *view) { - return view->scale * ZOOM_OUT_FACTOR >= view->min_scale; + return view->scale * ZOOM_OUT_FACTOR >= ev_document_model_get_min_scale (view->model); } void ev_view_zoom_in (EvView *view) { + gdouble scale; + g_return_if_fail (view->sizing_mode == EV_SIZING_FREE); if (view->presentation) return; - + view->pending_scroll = SCROLL_TO_CENTER; - ev_view_set_zoom (view, ZOOM_IN_FACTOR, TRUE); + scale = ev_document_model_get_scale (view->model) * ZOOM_IN_FACTOR; + ev_document_model_set_scale (view->model, scale); } void ev_view_zoom_out (EvView *view) { + gdouble scale; + g_return_if_fail (view->sizing_mode == EV_SIZING_FREE); if (view->presentation) return; - - view->pending_scroll = SCROLL_TO_CENTER; - ev_view_set_zoom (view, ZOOM_OUT_FACTOR, TRUE); -} - -void -ev_view_rotate_right (EvView *view) -{ - int rotation = view->rotation + 90; - - if (rotation >= 360) { - rotation -= 360; - } - - ev_view_set_rotation (view, rotation); -} -void -ev_view_rotate_left (EvView *view) -{ - int rotation = view->rotation - 90; - - if (rotation < 0) { - rotation += 360; - } - - ev_view_set_rotation (view, rotation); + view->pending_scroll = SCROLL_TO_CENTER; + scale = ev_document_model_get_scale (view->model) * ZOOM_OUT_FACTOR; + ev_document_model_set_scale (view->model, scale); } void @@ -5420,14 +5455,6 @@ 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)); - } - - if (rotation != 0) - clear_selection (view); - g_object_notify (G_OBJECT (view), "rotation"); } @@ -5500,7 +5527,7 @@ ev_view_zoom_for_size_presentation (EvView *view, get_doc_page_size (view, view->current_page, &doc_width, &doc_height); scale = zoom_for_size_best_fit (doc_width, doc_height, width, height); - ev_view_set_zoom (view, scale, FALSE); + ev_document_model_set_scale (view->model, scale); } static void @@ -5534,7 +5561,7 @@ ev_view_zoom_for_size_continuous_and_dual_page (EvView *view, else g_assert_not_reached (); - ev_view_set_zoom (view, scale, FALSE); + ev_document_model_set_scale (view->model, scale); } static void @@ -5567,7 +5594,7 @@ ev_view_zoom_for_size_continuous (EvView *view, else g_assert_not_reached (); - ev_view_set_zoom (view, scale, FALSE); + ev_document_model_set_scale (view->model, scale); } static void @@ -5606,7 +5633,7 @@ ev_view_zoom_for_size_dual_page (EvView *view, else g_assert_not_reached (); - ev_view_set_zoom (view, scale, FALSE); + ev_document_model_set_scale (view->model, scale); } static void @@ -5633,7 +5660,7 @@ ev_view_zoom_for_size_single_page (EvView *view, else g_assert_not_reached (); - ev_view_set_zoom (view, scale, FALSE); + ev_document_model_set_scale (view->model, scale); } static void @@ -5726,7 +5753,7 @@ jump_to_find_page (EvView *view, EvViewFindDirection direction, gint shift) page = page + n_pages; if (ev_view_find_get_n_results (view, page) > 0) { - ev_page_cache_set_current_page (view->page_cache, page); + ev_document_model_set_page (view->model, page); break; } } @@ -6390,7 +6417,7 @@ ev_view_next_page (EvView *view) g_return_val_if_fail (EV_IS_VIEW (view), FALSE); - if (!view->page_cache) + if (!view->document) return FALSE; if (view->presentation && @@ -6407,7 +6434,7 @@ ev_view_next_page (EvView *view) ev_view_presentation_transition_stop (view); ev_view_reset_presentation_state (view); - page = ev_page_cache_get_current_page (view->page_cache); + page = ev_document_model_get_page (view->model); n_pages = ev_document_get_n_pages (view->document); if (view->dual_page && !view->presentation) @@ -6416,14 +6443,14 @@ ev_view_next_page (EvView *view) page = page + 1; if (page < n_pages) { - ev_page_cache_set_current_page (view->page_cache, page); + ev_document_model_set_page (view->model, page); return TRUE; } else if (view->presentation && page == n_pages) { view->presentation_state = EV_PRESENTATION_END; gtk_widget_queue_draw (GTK_WIDGET (view)); return TRUE; } else if (view->dual_page && page == n_pages) { - ev_page_cache_set_current_page (view->page_cache, page - 1); + ev_document_model_set_page (view->model, page - 1); return TRUE; } else { return FALSE; @@ -6437,7 +6464,7 @@ ev_view_previous_page (EvView *view) g_return_val_if_fail (EV_IS_VIEW (view), FALSE); - if (!view->page_cache) + if (!view->document) return FALSE; if (view->presentation && @@ -6459,7 +6486,7 @@ ev_view_previous_page (EvView *view) ev_view_reset_presentation_state (view); - page = ev_page_cache_get_current_page (view->page_cache); + page = ev_document_model_get_page (view->model); if (view->dual_page && !view->presentation) page = page - 2; @@ -6467,10 +6494,10 @@ ev_view_previous_page (EvView *view) page = page - 1; if (page >= 0) { - ev_page_cache_set_current_page (view->page_cache, page); + ev_document_model_set_page (view->model, page); return TRUE; } else if (ev_view_get_dual_page (view) && page == -1) { - ev_page_cache_set_current_page (view->page_cache, 0); + ev_document_model_set_page (view->model, 0); return TRUE; } else { return FALSE; diff --git a/libview/ev-view.h b/libview/ev-view.h index d9b5127..53bc7c8 100644 --- a/libview/ev-view.h +++ b/libview/ev-view.h @@ -28,6 +28,8 @@ #include <evince-document.h> +#include "ev-document-model.h" + G_BEGIN_DECLS #define EV_TYPE_VIEW (ev_view_get_type ()) @@ -37,13 +39,6 @@ G_BEGIN_DECLS typedef struct _EvView EvView; typedef struct _EvViewClass EvViewClass; - -typedef enum { - EV_SIZING_BEST_FIT, - EV_SIZING_FIT_WIDTH, - EV_SIZING_FREE, -} EvSizingMode; - typedef enum { EV_VIEW_SELECTION_TEXT, EV_VIEW_SELECTION_RECTANGLE, @@ -52,8 +47,8 @@ typedef enum { GType ev_view_get_type (void) G_GNUC_CONST; GtkWidget* ev_view_new (void); -void ev_view_set_document (EvView *view, - EvDocument *document); +void ev_view_set_model (EvView *view, + EvDocumentModel *model); void ev_view_set_loading (EvView *view, gboolean loading); void ev_view_reload (EvView *view); @@ -92,8 +87,7 @@ void ev_view_zoom_in (EvView *view); gboolean ev_view_can_zoom_out (EvView *view); void ev_view_zoom_out (EvView *view); void ev_view_set_zoom (EvView *view, - double factor, - gboolean relative); + double factor); double ev_view_get_zoom (EvView *view); void ev_view_set_screen_dpi (EvView *view, gdouble dpi); |