From 34148304a0237fd9fd7c4ea05ca2e053d9ddd3ff Mon Sep 17 00:00:00 2001 From: Carlos Garcia Campos Date: Sun, 23 Aug 2009 18:02:41 +0200 Subject: [PATCH] Remove EvPageCache and use EvDocumentModel instead EvView is now another view for the common model EvDocumentModel. Now it's possible to have several windows for the same document without the symlink hack. Every window has its own model, while the document object is shared. --- evince-view.h | 2 +- libmisc/Makefile.am | 1 + libmisc/ev-page-action-widget.c | 93 ++++--- libmisc/ev-page-action-widget.h | 12 +- libmisc/ev-page-action.c | 100 +++----- libmisc/ev-page-action.h | 14 +- libview/Makefile.am | 4 +- libview/ev-document-model.c | 416 ++++++++++++++++++++++++++++++++ libview/ev-document-model.h | 75 ++++++ libview/ev-page-cache.c | 168 ------------- libview/ev-page-cache.h | 51 ---- libview/ev-pixbuf-cache.c | 25 +- libview/ev-view-private.h | 7 +- libview/ev-view.c | 301 ++++++++++++----------- libview/ev-view.h | 16 +- previewer/ev-previewer-window.c | 176 +++++++++----- previewer/ev-previewer-window.h | 5 +- previewer/ev-previewer.c | 28 ++- shell/ev-print-operation.c | 1 - shell/ev-properties-dialog.c | 1 - shell/ev-sidebar-attachments.c | 25 +- shell/ev-sidebar-layers.c | 28 ++- shell/ev-sidebar-links.c | 128 ++++++---- shell/ev-sidebar-page.c | 16 +- shell/ev-sidebar-page.h | 13 +- shell/ev-sidebar-thumbnails.c | 120 +++++---- shell/ev-sidebar-thumbnails.h | 8 +- shell/ev-sidebar.c | 51 ++-- shell/ev-sidebar.h | 18 +- shell/ev-window.c | 373 +++++++++++++++------------- shell/ev-window.h | 1 - 31 files changed, 1358 insertions(+), 919 deletions(-) create mode 100644 libview/ev-document-model.c create mode 100644 libview/ev-document-model.h delete mode 100644 libview/ev-page-cache.c delete mode 100644 libview/ev-page-cache.h diff --git a/evince-view.h b/evince-view.h index ed88853f..4c83d471 100644 --- a/evince-view.h +++ b/evince-view.h @@ -23,7 +23,7 @@ #include #include -#include +#include #include #include #include diff --git a/libmisc/Makefile.am b/libmisc/Makefile.am index 290f574f..38a43fa4 100644 --- a/libmisc/Makefile.am +++ b/libmisc/Makefile.am @@ -10,6 +10,7 @@ libevmisc_la_CFLAGS = \ -DDATADIR=\"$(pkgdatadir)\" \ -I$(top_srcdir) \ -I$(top_srcdir)/libdocument \ + -I$(top_srcdir)/libview \ $(SHELL_CORE_CFLAGS) \ $(WARNING_CFLAGS) \ $(DISABLE_DEPRECATED) diff --git a/libmisc/ev-page-action-widget.c b/libmisc/ev-page-action-widget.c index 249775cb..2b29e785 100644 --- a/libmisc/ev-page-action-widget.c +++ b/libmisc/ev-page-action-widget.c @@ -43,7 +43,7 @@ struct _EvPageActionWidget GtkToolItem parent; EvDocument *document; - EvPageCache *page_cache; + EvDocumentModel *doc_model; GtkWidget *entry; GtkWidget *label; @@ -74,9 +74,8 @@ update_pages_label (EvPageActionWidget *action_widget, } static void -page_changed_cb (EvPageCache *page_cache, - gint page, - EvPageActionWidget *action_widget) +ev_page_action_widget_set_current_page (EvPageActionWidget *action_widget, + gint page) { if (page >= 0) { gchar *page_label; @@ -97,19 +96,28 @@ page_changed_cb (EvPageCache *page_cache, update_pages_label (action_widget, page); } +static void +page_changed_cb (EvDocumentModel *model, + gint old_page, + gint new_page, + EvPageActionWidget *action_widget) +{ + ev_page_action_widget_set_current_page (action_widget, new_page); +} + static gboolean page_scroll_cb (EvPageActionWidget *action_widget, GdkEventScroll *event) { - EvPageCache *page_cache = action_widget->page_cache; + EvDocumentModel *model = action_widget->doc_model; gint pageno; - pageno = ev_page_cache_get_current_page (page_cache); + pageno = ev_document_model_get_page (model); if ((event->direction == GDK_SCROLL_DOWN) && (pageno < ev_document_get_n_pages (action_widget->document) - 1)) pageno++; if ((event->direction == GDK_SCROLL_UP) && (pageno > 0)) pageno--; - ev_page_cache_set_current_page (page_cache, pageno); + ev_document_model_set_page (model, pageno); return TRUE; } @@ -117,7 +125,7 @@ page_scroll_cb (EvPageActionWidget *action_widget, GdkEventScroll *event) static void activate_cb (EvPageActionWidget *action_widget) { - EvPageCache *page_cache; + EvDocumentModel *model; const char *text; gchar *page_label; EvLinkDest *link_dest; @@ -139,9 +147,9 @@ activate_cb (EvPageActionWidget *action_widget) /* rest the entry to the current page if we were unable to * change it */ - page_cache = action_widget->page_cache; + model = action_widget->doc_model; page_label = ev_document_get_page_label (action_widget->document, - ev_page_cache_get_current_page (page_cache)); + ev_document_model_get_page (model)); gtk_entry_set_text (GTK_ENTRY (action_widget->entry), page_label); gtk_editable_set_position (GTK_EDITABLE (action_widget->entry), -1); g_free (page_label); @@ -187,38 +195,48 @@ ev_page_action_widget_init (EvPageActionWidget *action_widget) gtk_widget_show (GTK_WIDGET (action_widget)); } -void -ev_page_action_widget_set_document (EvPageActionWidget *action_widget, - EvDocument *document) +static void +ev_page_action_widget_document_changed_cb (EvDocumentModel *model, + GParamSpec *pspec, + EvPageActionWidget *action_widget) { - EvPageCache *page_cache = ev_page_cache_get (document); + EvDocument *document = ev_document_model_get_document (model); g_object_ref (document); if (action_widget->document) g_object_unref (action_widget->document); action_widget->document = document; - if (action_widget->page_cache != NULL) { - if (action_widget->signal_id > 0) { - g_signal_handler_disconnect (action_widget->page_cache, - action_widget->signal_id); - action_widget->signal_id = 0; - } - g_object_remove_weak_pointer (G_OBJECT (action_widget->page_cache), - (gpointer)&action_widget->page_cache); - action_widget->page_cache = NULL; + if (action_widget->signal_id > 0) { + g_signal_handler_disconnect (action_widget->doc_model, + action_widget->signal_id); + action_widget->signal_id = 0; } - - action_widget->page_cache = page_cache; - g_object_add_weak_pointer (G_OBJECT (page_cache), - (gpointer)&action_widget->page_cache); action_widget->signal_id = - g_signal_connect_object (page_cache, "page-changed", + g_signal_connect_object (action_widget->doc_model, + "page-changed", G_CALLBACK (page_changed_cb), action_widget, 0); - page_changed_cb (page_cache, - ev_page_cache_get_current_page (page_cache), - action_widget); + + ev_page_action_widget_set_current_page (action_widget, + ev_document_model_get_page (model)); +} + +void +ev_page_action_widget_set_model (EvPageActionWidget *action_widget, + EvDocumentModel *model) +{ + if (action_widget->doc_model) { + g_object_remove_weak_pointer (G_OBJECT (action_widget->doc_model), + (gpointer)&action_widget->doc_model); + } + action_widget->doc_model = model; + g_object_add_weak_pointer (G_OBJECT (model), + (gpointer)&action_widget->doc_model); + + g_signal_connect (model, "notify::document", + G_CALLBACK (ev_page_action_widget_document_changed_cb), + action_widget); } static void @@ -226,15 +244,15 @@ ev_page_action_widget_finalize (GObject *object) { EvPageActionWidget *action_widget = EV_PAGE_ACTION_WIDGET (object); - if (action_widget->page_cache != NULL) { + if (action_widget->doc_model != NULL) { if (action_widget->signal_id > 0) { - g_signal_handler_disconnect (action_widget->page_cache, + g_signal_handler_disconnect (action_widget->doc_model, action_widget->signal_id); action_widget->signal_id = 0; } - g_object_remove_weak_pointer (G_OBJECT (action_widget->page_cache), - (gpointer)&action_widget->page_cache); - action_widget->page_cache = NULL; + g_object_remove_weak_pointer (G_OBJECT (action_widget->doc_model), + (gpointer)&action_widget->doc_model); + action_widget->doc_model = NULL; } if (action_widget->document) { @@ -432,7 +450,7 @@ get_filter_model_from_model (GtkTreeModel *model) void -ev_page_action_widget_update_model (EvPageActionWidget *proxy, GtkTreeModel *model) +ev_page_action_widget_update_links_model (EvPageActionWidget *proxy, GtkTreeModel *model) { GtkTreeModel *filter_model; GtkEntryCompletion *completion; @@ -470,7 +488,6 @@ ev_page_action_widget_update_model (EvPageActionWidget *proxy, GtkTreeModel *mod gtk_entry_set_completion (GTK_ENTRY (proxy->entry), completion); g_object_unref (completion); - g_object_unref (model); } void diff --git a/libmisc/ev-page-action-widget.h b/libmisc/ev-page-action-widget.h index 1c9ee35d..52e09b6e 100644 --- a/libmisc/ev-page-action-widget.h +++ b/libmisc/ev-page-action-widget.h @@ -36,11 +36,11 @@ struct _EvPageActionWidgetClass EvLink *link); }; -GType ev_page_action_widget_get_type (void) G_GNUC_CONST; +GType ev_page_action_widget_get_type (void) G_GNUC_CONST; -void ev_page_action_widget_update_model (EvPageActionWidget *proxy, - GtkTreeModel *model); +void ev_page_action_widget_update_links_model (EvPageActionWidget *proxy, + GtkTreeModel *model); -void ev_page_action_widget_set_document (EvPageActionWidget *action_widget, - EvDocument *document); -void ev_page_action_widget_grab_focus (EvPageActionWidget *proxy); +void ev_page_action_widget_set_model (EvPageActionWidget *action_widget, + EvDocumentModel *doc_model); +void ev_page_action_widget_grab_focus (EvPageActionWidget *proxy); diff --git a/libmisc/ev-page-action.c b/libmisc/ev-page-action.c index 090712e2..6c363519 100644 --- a/libmisc/ev-page-action.c +++ b/libmisc/ev-page-action.c @@ -33,7 +33,7 @@ struct _EvPageActionPrivate { - EvDocument *document; + EvDocumentModel *doc_model; GtkTreeModel *model; }; @@ -55,8 +55,7 @@ G_DEFINE_TYPE (EvPageAction, ev_page_action, GTK_TYPE_ACTION) enum { PROP_0, - PROP_DOCUMENT, - PROP_MODEL, + PROP_MODEL }; static GtkWidget * @@ -69,23 +68,10 @@ create_tool_item (GtkAction *action) return proxy; } -static void -update_document (EvPageAction *page, GParamSpec *pspec, EvPageActionWidget *proxy) -{ - if (page->priv->document) - ev_page_action_widget_set_document (proxy, page->priv->document); -} - static void update_model (EvPageAction *page, GParamSpec *pspec, EvPageActionWidget *proxy) { - GtkTreeModel *model; - - g_object_get (G_OBJECT (page), - "model", &model, - NULL); - - ev_page_action_widget_update_model (proxy, model); + ev_page_action_widget_update_links_model (proxy, page->priv->model); } static void @@ -97,10 +83,11 @@ activate_link_cb (EvPageActionWidget *proxy, EvLink *link, EvPageAction *action) static void connect_proxy (GtkAction *action, GtkWidget *proxy) { + EvPageAction *page = EV_PAGE_ACTION (action); + if (GTK_IS_TOOL_ITEM (proxy)) { - g_signal_connect_object (action, "notify::document", - G_CALLBACK (update_document), - proxy, 0); + ev_page_action_widget_set_model (EV_PAGE_ACTION_WIDGET (proxy), + page->priv->doc_model); g_signal_connect (proxy, "activate_link", G_CALLBACK (activate_link_cb), action); @@ -117,11 +104,13 @@ ev_page_action_dispose (GObject *object) { EvPageAction *page = EV_PAGE_ACTION (object); - if (page->priv->document) { - g_object_unref (page->priv->document); - page->priv->document = NULL; + if (page->priv->model) { + g_object_unref (page->priv->model); + page->priv->model = NULL; } + page->priv->doc_model = NULL; + G_OBJECT_CLASS (ev_page_action_parent_class)->dispose (object); } @@ -131,25 +120,13 @@ ev_page_action_set_property (GObject *object, const GValue *value, GParamSpec *pspec) { - EvPageAction *page; - EvDocument *document; + EvPageAction *page = EV_PAGE_ACTION (object); GtkTreeModel *model; - page = EV_PAGE_ACTION (object); - switch (prop_id) { - case PROP_DOCUMENT: - document = page->priv->document; - page->priv->document = EV_DOCUMENT (g_value_dup_object (value)); - if (document) - g_object_unref (document); - break; case PROP_MODEL: - model = page->priv->model; - page->priv->model = GTK_TREE_MODEL (g_value_dup_object (value)); - if (model) - g_object_unref (model); + ev_page_action_set_links_model (page, g_value_get_object (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -163,15 +140,10 @@ ev_page_action_get_property (GObject *object, GValue *value, GParamSpec *pspec) { - EvPageAction *page; - - page = EV_PAGE_ACTION (object); + EvPageAction *page = EV_PAGE_ACTION (object); switch (prop_id) { - case PROP_DOCUMENT: - g_value_set_object (value, page->priv->document); - break; case PROP_MODEL: g_value_set_object (value, page->priv->model); break; @@ -182,21 +154,33 @@ ev_page_action_get_property (GObject *object, } void -ev_page_action_set_document (EvPageAction *page, EvDocument *document) +ev_page_action_set_model (EvPageAction *page, + EvDocumentModel *model) { - g_object_set (page, - "document", document, - "model", NULL, - NULL); + g_return_if_fail (EV_IS_PAGE_ACTION (page)); + g_return_if_fail (EV_IS_DOCUMENT_MODEL (model)); + + if (page->priv->doc_model == model) + return; + + page->priv->doc_model = model; } void -ev_page_action_set_model (EvPageAction *page_action, - GtkTreeModel *model) +ev_page_action_set_links_model (EvPageAction *page, + GtkTreeModel *links_model) { - g_object_set (page_action, - "model", model, - NULL); + g_return_if_fail (EV_IS_PAGE_ACTION (page)); + g_return_if_fail (GTK_IS_TREE_MODEL (links_model)); + + if (page->priv->model == links_model) + return; + + if (page->priv->model) + g_object_unref (page->priv->model); + page->priv->model = g_object_ref (links_model); + + g_object_notify (G_OBJECT (page), "model"); } void @@ -244,19 +228,11 @@ ev_page_action_class_init (EvPageActionClass *class) G_TYPE_NONE, 1, G_TYPE_OBJECT); - g_object_class_install_property (object_class, - PROP_DOCUMENT, - g_param_spec_object ("document", - "Document", - "Current document", - EV_TYPE_DOCUMENT, - G_PARAM_READWRITE)); - g_object_class_install_property (object_class, PROP_MODEL, g_param_spec_object ("model", "Model", - "Current Model", + "Current Links Model", GTK_TYPE_TREE_MODEL, G_PARAM_READWRITE)); diff --git a/libmisc/ev-page-action.h b/libmisc/ev-page-action.h index dc13bdd0..1817089b 100644 --- a/libmisc/ev-page-action.h +++ b/libmisc/ev-page-action.h @@ -24,6 +24,7 @@ #include #include +#include G_BEGIN_DECLS @@ -54,12 +55,13 @@ struct _EvPageActionClass EvLink *link); }; -GType ev_page_action_get_type (void); -void ev_page_action_set_document (EvPageAction *page_action, - EvDocument *document); -void ev_page_action_set_model (EvPageAction *page_action, - GtkTreeModel *model); -void ev_page_action_grab_focus (EvPageAction *page_action); +GType ev_page_action_get_type (void) G_GNUC_CONST; + +void ev_page_action_set_model (EvPageAction *page_action, + EvDocumentModel *model); +void ev_page_action_set_links_model (EvPageAction *page_action, + GtkTreeModel *links_model); +void ev_page_action_grab_focus (EvPageAction *page_action); G_END_DECLS diff --git a/libview/Makefile.am b/libview/Makefile.am index d9e4c082..1964eeed 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 00000000..a850e841 --- /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 00000000..14c960a0 --- /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 can be included directly." +#endif + +#ifndef __EV_DOCUMENT_MODEL_H__ +#define __EV_DOCUMENT_MODEL_H__ + +#include +#include + +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 8fba8c6a..00000000 --- a/libview/ev-page-cache.c +++ /dev/null @@ -1,168 +0,0 @@ -#include -#include "ev-page-cache.h" -#include "ev-document-thumbnails.h" -#include "ev-page.h" -#include -#include - -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 82e2791d..00000000 --- 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 can be included directly." -#endif - -#ifndef __EV_PAGE_CACHE_H__ -#define __EV_PAGE_CACHE_H__ - -#include - -#include - -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 0ebfeaef..df06705c 100644 --- a/libview/ev-pixbuf-cache.c +++ b/libview/ev-pixbuf-cache.c @@ -1,7 +1,6 @@ #include #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 2f01f72a..a2710a99 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 b2fb610d..50e4f722 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 d9b5127d..53bc7c8a 100644 --- a/libview/ev-view.h +++ b/libview/ev-view.h @@ -28,6 +28,8 @@ #include +#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); diff --git a/previewer/ev-previewer-window.c b/previewer/ev-previewer-window.c index c406a223..08eb8956 100644 --- a/previewer/ev-previewer-window.c +++ b/previewer/ev-previewer-window.c @@ -32,6 +32,7 @@ struct _EvPreviewerWindow { GtkWindow base_instance; + EvDocumentModel *model; EvDocument *document; GtkActionGroup *action_group; @@ -55,6 +56,14 @@ struct _EvPreviewerWindowClass { GtkWindowClass base_class; }; +enum { + PROP_0, + PROP_MODEL +}; + +#define MIN_SCALE 0.05409 +#define MAX_SCALE 4.0 + G_DEFINE_TYPE (EvPreviewerWindow, ev_previewer_window, GTK_TYPE_WINDOW) static gdouble @@ -109,7 +118,7 @@ static void ev_previewer_window_zoom_in (GtkAction *action, EvPreviewerWindow *window) { - ev_view_set_sizing_mode (window->view, EV_SIZING_FREE); + ev_document_model_set_sizing_mode (window->model, EV_SIZING_FREE); ev_view_zoom_in (window->view); } @@ -117,7 +126,7 @@ static void ev_previewer_window_zoom_out (GtkAction *action, EvPreviewerWindow *window) { - ev_view_set_sizing_mode (window->view, EV_SIZING_FREE); + ev_document_model_set_sizing_mode (window->model, EV_SIZING_FREE); ev_view_zoom_out (window->view); } @@ -125,22 +134,18 @@ static void ev_previewer_window_zoom_best_fit (GtkToggleAction *action, EvPreviewerWindow *window) { - if (gtk_toggle_action_get_active (action)) { - ev_view_set_sizing_mode (window->view, EV_SIZING_BEST_FIT); - } else { - ev_view_set_sizing_mode (window->view, EV_SIZING_FREE); - } + ev_document_model_set_sizing_mode (window->model, + gtk_toggle_action_get_active (action) ? + EV_SIZING_BEST_FIT : EV_SIZING_FREE); } static void ev_previewer_window_zoom_page_width (GtkToggleAction *action, EvPreviewerWindow *window) { - if (gtk_toggle_action_get_active (action)) { - ev_view_set_sizing_mode (window->view, EV_SIZING_FIT_WIDTH); - } else { - ev_view_set_sizing_mode (window->view, EV_SIZING_FREE); - } + ev_document_model_set_sizing_mode (window->model, + gtk_toggle_action_get_active (action) ? + EV_SIZING_FIT_WIDTH : EV_SIZING_FREE); } static void @@ -273,22 +278,14 @@ static const GtkToggleActionEntry toggle_action_entries[] = { G_CALLBACK (ev_previewer_window_zoom_page_width) } }; -/* EvView callbacks */ static void -view_sizing_mode_changed (EvView *view, +view_sizing_mode_changed (EvDocumentModel *model, GParamSpec *pspec, EvPreviewerWindow *window) { - EvSizingMode sizing_mode; + EvSizingMode sizing_mode = ev_document_model_get_sizing_mode (model); GtkAction *action; - if (!window->view) - return; - - g_object_get (window->view, - "sizing_mode", &sizing_mode, - NULL); - action = gtk_action_group_get_action (window->action_group, "ViewBestFit"); g_signal_handlers_block_by_func (action, G_CALLBACK (ev_previewer_window_zoom_best_fit), @@ -310,11 +307,32 @@ view_sizing_mode_changed (EvView *view, window); } +static void +ev_previewer_window_set_document (EvPreviewerWindow *window, + GParamSpec *pspec, + EvDocumentModel *model) +{ + EvDocument *document = ev_document_model_get_document (model); + + window->document = g_object_ref (document); + + g_signal_connect (model, "notify::sizing-mode", + G_CALLBACK (view_sizing_mode_changed), + window); + ev_view_set_loading (window->view, FALSE); + gtk_action_group_set_sensitive (window->action_group, TRUE); +} + static void ev_previewer_window_dispose (GObject *object) { EvPreviewerWindow *window = EV_PREVIEWER_WINDOW (object); + if (window->model) { + g_object_unref (window->model); + window->model = NULL; + } + if (window->document) { g_object_unref (window->document); window->document = NULL; @@ -380,14 +398,55 @@ data_dir (void) static void ev_previewer_window_init (EvPreviewerWindow *window) { - GtkWidget *vbox; - GtkWidget *toolbar; - GtkAction *action; - GError *error = NULL; - gchar *datadir, *ui_path; - gtk_window_set_default_size (GTK_WINDOW (window), 600, 600); - +} + +static void +ev_previewer_window_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + EvPreviewerWindow *window = EV_PREVIEWER_WINDOW (object); + + switch (prop_id) { + case PROP_MODEL: + window->model = g_value_dup_object (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + } +} + +static GObject * +ev_previewer_window_constructor (GType type, + guint n_construct_properties, + GObjectConstructParam *construct_params) +{ + GObject *object; + EvPreviewerWindow *window; + GtkWidget *vbox; + GtkWidget *toolbar; + GtkAction *action; + GError *error = NULL; + gchar *datadir, *ui_path; + gdouble dpi; + + g_print ("DBG: constructor\n"); + + object = G_OBJECT_CLASS (ev_previewer_window_parent_class)->constructor (type, + n_construct_properties, + construct_params); + window = EV_PREVIEWER_WINDOW (object); + + dpi = get_screen_dpi (GTK_WINDOW (window)); + ev_document_model_set_min_scale (window->model, MIN_SCALE * dpi / 72.0); + ev_document_model_set_max_scale (window->model, MAX_SCALE * dpi / 72.0); + ev_document_model_set_sizing_mode (window->model, EV_SIZING_FIT_WIDTH); + g_signal_connect_swapped (window->model, "notify::document", + G_CALLBACK (ev_previewer_window_set_document), + window); + window->action_group = gtk_action_group_new ("PreviewerActions"); gtk_action_group_set_translation_domain (window->action_group, NULL); gtk_action_group_add_actions (window->action_group, action_entries, @@ -405,6 +464,7 @@ ev_previewer_window_init (EvPreviewerWindow *window) "icon_name", "text-x-generic", "visible_overflown", FALSE, NULL); + ev_page_action_set_model (EV_PAGE_ACTION (action), window->model); g_signal_connect (action, "activate_link", G_CALLBACK (ev_previewer_window_action_page_activated), window); @@ -425,75 +485,61 @@ ev_previewer_window_init (EvPreviewerWindow *window) g_free (ui_path); g_free (datadir); + view_sizing_mode_changed (window->model, NULL, window); + vbox = gtk_vbox_new (FALSE, 0); toolbar = gtk_ui_manager_get_widget (window->ui_manager, "/PreviewToolbar"); gtk_box_pack_start (GTK_BOX (vbox), toolbar, FALSE, FALSE, 0); gtk_widget_show (toolbar); - + window->swindow = gtk_scrolled_window_new (NULL, NULL); gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (window->swindow), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - - window->view = EV_VIEW (ev_view_new ()); - g_signal_connect (window->view, "notify::sizing-mode", - G_CALLBACK (view_sizing_mode_changed), - window); - ev_view_set_screen_dpi (window->view, get_screen_dpi (GTK_WINDOW (window))); + window->view = EV_VIEW (ev_view_new ()); + ev_view_set_model (window->view, window->model); ev_view_set_continuous (window->view, FALSE); - ev_view_set_sizing_mode (window->view, EV_SIZING_FIT_WIDTH); ev_view_set_loading (window->view, TRUE); - view_sizing_mode_changed (window->view, NULL, window); gtk_container_add (GTK_CONTAINER (window->swindow), GTK_WIDGET (window->view)); gtk_widget_show (GTK_WIDGET (window->view)); gtk_box_pack_start (GTK_BOX (vbox), window->swindow, TRUE, TRUE, 0); gtk_widget_show (window->swindow); - + gtk_container_add (GTK_CONTAINER (window), vbox); gtk_widget_show (vbox); + + return object; } + static void ev_previewer_window_class_init (EvPreviewerWindowClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + gobject_class->constructor = ev_previewer_window_constructor; + gobject_class->set_property = ev_previewer_window_set_property; gobject_class->dispose = ev_previewer_window_dispose; + + g_object_class_install_property (gobject_class, + PROP_MODEL, + g_param_spec_object ("model", + "Model", + "The document model", + EV_TYPE_DOCUMENT_MODEL, + G_PARAM_WRITABLE | + G_PARAM_CONSTRUCT_ONLY)); } /* Public methods */ GtkWidget * -ev_previewer_window_new (void) +ev_previewer_window_new (EvDocumentModel *model) { - return GTK_WIDGET (g_object_new (EV_TYPE_PREVIEWER_WINDOW, NULL)); -} - -void -ev_previewer_window_set_document (EvPreviewerWindow *window, - EvDocument *document) -{ - GtkAction *action; - - g_return_if_fail (EV_IS_PREVIEWER_WINDOW (window)); - g_return_if_fail (EV_IS_DOCUMENT (document)); - - if (window->document) - return; - - action = gtk_action_group_get_action (window->action_group, "PageSelector"); - ev_page_action_set_document (EV_PAGE_ACTION (action), document); - gtk_action_group_set_sensitive (window->action_group, TRUE); - - window->document = g_object_ref (document); - ev_view_set_document (window->view, document); - ev_view_set_zoom (window->view, - get_screen_dpi (GTK_WINDOW (window)) / 72.0, - FALSE); - ev_view_set_loading (window->view, FALSE); + return GTK_WIDGET (g_object_new (EV_TYPE_PREVIEWER_WINDOW, "model", model, NULL)); } void diff --git a/previewer/ev-previewer-window.h b/previewer/ev-previewer-window.h index aba56d7a..8d8217b8 100644 --- a/previewer/ev-previewer-window.h +++ b/previewer/ev-previewer-window.h @@ -24,6 +24,7 @@ #include #include +#include G_BEGIN_DECLS @@ -38,10 +39,8 @@ typedef struct _EvPreviewerWindow EvPreviewerWindow; typedef struct _EvPreviewerWindowClass EvPreviewerWindowClass; GType ev_previewer_window_get_type (void) G_GNUC_CONST; -GtkWidget *ev_previewer_window_new (void); +GtkWidget *ev_previewer_window_new (EvDocumentModel *model); -void ev_previewer_window_set_document (EvPreviewerWindow *window, - EvDocument *document); void ev_previewer_window_set_print_settings (EvPreviewerWindow *window, const gchar *print_settings); void ev_previewer_window_set_source_file (EvPreviewerWindow *window, diff --git a/previewer/ev-previewer.c b/previewer/ev-previewer.c index 5c1980a0..7a83eee0 100644 --- a/previewer/ev-previewer.c +++ b/previewer/ev-previewer.c @@ -65,8 +65,8 @@ ev_previewer_unlink_tempfile (const gchar *filename) } static void -ev_previewer_load_job_finished (EvJob *job, - EvPreviewerWindow *window) +ev_previewer_load_job_finished (EvJob *job, + EvDocumentModel *model) { if (ev_job_is_failed (job)) { g_warning ("%s", job->error->message); @@ -74,14 +74,13 @@ ev_previewer_load_job_finished (EvJob *job, return; } - - ev_previewer_window_set_document (window, job->document); + ev_document_model_set_document (model, job->document); g_object_unref (job); } static void -ev_previewer_load_document (const gchar *filename, - EvPreviewerWindow *window) +ev_previewer_load_document (const gchar *filename, + EvDocumentModel *model) { EvJob *job; gchar *uri; @@ -90,7 +89,7 @@ ev_previewer_load_document (const gchar *filename, job = ev_job_load_new (uri); g_signal_connect (job, "finished", G_CALLBACK (ev_previewer_load_job_finished), - window); + model); ev_job_scheduler_push_job (job, EV_JOB_PRIORITY_NONE); g_free (uri); } @@ -98,10 +97,11 @@ ev_previewer_load_document (const gchar *filename, gint main (gint argc, gchar **argv) { - GtkWidget *window; - GOptionContext *context; - const gchar *filename; - GError *error = NULL; + GtkWidget *window; + GOptionContext *context; + const gchar *filename; + EvDocumentModel *model; + GError *error = NULL; #ifdef G_OS_WIN32 if (fileno (stdout) != -1 && @@ -175,7 +175,8 @@ main (gint argc, gchar **argv) g_set_application_name (_("GNOME Document Previewer")); gtk_window_set_default_icon_name ("evince"); - window = ev_previewer_window_new (); + model = ev_document_model_new (); + window = ev_previewer_window_new (model); ev_previewer_window_set_source_file (EV_PREVIEWER_WINDOW (window), filename); ev_previewer_window_set_print_settings (EV_PREVIEWER_WINDOW (window), print_settings); g_signal_connect (window, "delete-event", @@ -184,7 +185,7 @@ main (gint argc, gchar **argv) G_CALLBACK (gtk_main_quit), NULL); gtk_widget_show (window); - ev_previewer_load_document (filename, EV_PREVIEWER_WINDOW (window)); + ev_previewer_load_document (filename, model); gtk_main (); @@ -195,6 +196,7 @@ main (gint argc, gchar **argv) ev_shutdown (); ev_stock_icons_shutdown (); + g_object_unref (model); return 0; } diff --git a/shell/ev-print-operation.c b/shell/ev-print-operation.c index fe5ef540..eb0f9bec 100644 --- a/shell/ev-print-operation.c +++ b/shell/ev-print-operation.c @@ -28,7 +28,6 @@ #include #include -#include "ev-page-cache.h" #include "ev-file-exporter.h" #include "ev-jobs.h" #include "ev-job-scheduler.h" diff --git a/shell/ev-properties-dialog.c b/shell/ev-properties-dialog.c index 0ca4661b..b19408e2 100644 --- a/shell/ev-properties-dialog.c +++ b/shell/ev-properties-dialog.c @@ -26,7 +26,6 @@ #include #include "ev-document-fonts.h" -#include "ev-page-cache.h" #include "ev-properties-dialog.h" #include "ev-properties-fonts.h" #include "ev-properties-view.h" diff --git a/shell/ev-sidebar-attachments.c b/shell/ev-sidebar-attachments.c index b63c5efc..d89617b1 100644 --- a/shell/ev-sidebar-attachments.c +++ b/shell/ev-sidebar-attachments.c @@ -651,13 +651,21 @@ job_finished_callback (EvJobAttachments *job, g_object_unref (job); } + static void -ev_sidebar_attachments_set_document (EvSidebarPage *page, - EvDocument *document) +ev_sidebar_attachments_document_changed_cb (EvDocumentModel *model, + GParamSpec *pspec, + EvSidebarAttachments *ev_attachbar) { - EvSidebarAttachments *ev_attachbar = EV_SIDEBAR_ATTACHMENTS (page); + EvDocument *document = ev_document_model_get_document (model); EvJob *job; + if (!EV_IS_DOCUMENT_ATTACHMENTS (document)) + return; + + if (!ev_document_attachments_has_attachments (EV_DOCUMENT_ATTACHMENTS (document))) + return; + if (!ev_attachbar->priv->icon_theme) { GdkScreen *screen; @@ -682,6 +690,15 @@ ev_sidebar_attachments_set_document (EvSidebarPage *page, ev_job_scheduler_push_job (job, EV_JOB_PRIORITY_NONE); } +static void +ev_sidebar_attachments_set_model (EvSidebarPage *page, + EvDocumentModel *model) +{ + g_signal_connect (model, "notify::document", + G_CALLBACK (ev_sidebar_attachments_document_changed_cb), + page); +} + static gboolean ev_sidebar_attachments_support_document (EvSidebarPage *sidebar_page, EvDocument *document) @@ -700,7 +717,7 @@ static void ev_sidebar_attachments_page_iface_init (EvSidebarPageIface *iface) { iface->support_document = ev_sidebar_attachments_support_document; - iface->set_document = ev_sidebar_attachments_set_document; + iface->set_model = ev_sidebar_attachments_set_model; iface->get_label = ev_sidebar_attachments_get_label; } diff --git a/shell/ev-sidebar-layers.c b/shell/ev-sidebar-layers.c index cebd96d4..5f168956 100644 --- a/shell/ev-sidebar-layers.c +++ b/shell/ev-sidebar-layers.c @@ -346,18 +346,15 @@ job_finished_callback (EvJobLayers *job, } static void -ev_sidebar_layers_set_document (EvSidebarPage *sidebar_page, - EvDocument *document) +ev_sidebar_layers_document_changed_cb (EvDocumentModel *model, + GParamSpec *pspec, + EvSidebarLayers *sidebar_layers) { - EvSidebarLayers *sidebar_layers; - EvSidebarLayersPrivate *priv; - - g_return_if_fail (EV_IS_SIDEBAR_PAGE (sidebar_page)); - g_return_if_fail (EV_IS_DOCUMENT (document)); - - sidebar_layers = EV_SIDEBAR_LAYERS (sidebar_page); + EvDocument *document = ev_document_model_get_document (model); + EvSidebarLayersPrivate *priv = sidebar_layers->priv; - priv = sidebar_layers->priv; + if (!EV_IS_DOCUMENT_LAYERS (document)) + return; if (priv->document) { gtk_tree_view_set_model (GTK_TREE_VIEW (priv->tree_view), NULL); @@ -381,6 +378,15 @@ ev_sidebar_layers_set_document (EvSidebarPage *sidebar_page, ev_job_scheduler_push_job (priv->job, EV_JOB_PRIORITY_NONE); } +static void +ev_sidebar_layers_set_model (EvSidebarPage *sidebar_page, + EvDocumentModel *model) +{ + g_signal_connect (model, "notify::document", + G_CALLBACK (ev_sidebar_layers_document_changed_cb), + sidebar_page); +} + static gboolean ev_sidebar_layers_support_document (EvSidebarPage *sidebar_page, EvDocument *document) @@ -399,7 +405,7 @@ static void ev_sidebar_layers_page_iface_init (EvSidebarPageIface *iface) { iface->support_document = ev_sidebar_layers_support_document; - iface->set_document = ev_sidebar_layers_set_document; + iface->set_model = ev_sidebar_layers_set_model; iface->get_label = ev_sidebar_layers_get_label; } diff --git a/shell/ev-sidebar-links.c b/shell/ev-sidebar-links.c index 8993e5f8..6eb7e235 100644 --- a/shell/ev-sidebar-links.c +++ b/shell/ev-sidebar-links.c @@ -46,7 +46,7 @@ struct _EvSidebarLinksPrivate { EvJob *job; GtkTreeModel *model; EvDocument *document; - EvPageCache *page_cache; + EvDocumentModel *doc_model; }; enum { @@ -60,18 +60,20 @@ enum { N_SIGNALS }; -static void update_page_callback (EvPageCache *page_cache, - gint current_page, - EvSidebarLinks *sidebar_links); +static void update_page_callback (EvSidebarLinks *sidebar_links, + gint old_page, + gint current_page); static void row_activated_callback (GtkTreeView *treeview, GtkTreePath *arg1, GtkTreeViewColumn *arg2, gpointer user_data); +static void ev_sidebar_links_set_links_model (EvSidebarLinks *links, + GtkTreeModel *model); static void job_finished_callback (EvJobLinks *job, EvSidebarLinks *sidebar_links); +static void ev_sidebar_links_set_current_page (EvSidebarLinks *sidebar_links, + gint current_page); static void ev_sidebar_links_page_iface_init (EvSidebarPageIface *iface); -static void ev_sidebar_links_set_document (EvSidebarPage *sidebar_page, - EvDocument *document); static gboolean ev_sidebar_links_support_document (EvSidebarPage *sidebar_page, EvDocument *document); static const gchar* ev_sidebar_links_get_label (EvSidebarPage *sidebar_page); @@ -95,18 +97,12 @@ ev_sidebar_links_set_property (GObject *object, const GValue *value, GParamSpec *pspec) { - EvSidebarLinks *ev_sidebar_links; - GtkTreeModel *model; - - ev_sidebar_links = EV_SIDEBAR_LINKS (object); + EvSidebarLinks *ev_sidebar_links = EV_SIDEBAR_LINKS (object); switch (prop_id) { case PROP_MODEL: - model = ev_sidebar_links->priv->model; - ev_sidebar_links->priv->model = GTK_TREE_MODEL (g_value_dup_object (value)); - if (model) - g_object_unref (model); + ev_sidebar_links_set_links_model (ev_sidebar_links, g_value_get_object (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -159,7 +155,7 @@ ev_sidebar_links_dispose (GObject *object) if (sidebar->priv->document) { g_object_unref (sidebar->priv->document); sidebar->priv->document = NULL; - sidebar->priv->page_cache = NULL; + sidebar->priv->doc_model = NULL; } G_OBJECT_CLASS (ev_sidebar_links_parent_class)->dispose (object); @@ -175,9 +171,8 @@ ev_sidebar_links_map (GtkWidget *widget) GTK_WIDGET_CLASS (ev_sidebar_links_parent_class)->map (widget); if (links->priv->model) { - update_page_callback (links->priv->page_cache, - ev_page_cache_get_current_page (links->priv->page_cache), - links); + ev_sidebar_links_set_current_page (links, + ev_document_model_get_page (links->priv->doc_model)); } } @@ -239,10 +234,10 @@ selection_changed_callback (GtkTreeSelection *selection, if (link == NULL) return; - g_signal_handler_block (ev_sidebar_links->priv->page_cache, + g_signal_handler_block (ev_sidebar_links->priv->doc_model, ev_sidebar_links->priv->page_changed_id); g_signal_emit (ev_sidebar_links, signals[LINK_ACTIVATED], 0, link); - g_signal_handler_unblock (ev_sidebar_links->priv->page_cache, + g_signal_handler_unblock (ev_sidebar_links->priv->doc_model, ev_sidebar_links->priv->page_changed_id); g_object_unref (link); @@ -523,7 +518,7 @@ update_page_callback_foreach (GtkTreeModel *model, dest_page = ev_link_get_page (link); g_object_unref (link); - current_page = ev_page_cache_get_current_page (sidebar_links->priv->page_cache); + current_page = ev_document_model_get_page (sidebar_links->priv->doc_model); if (dest_page == current_page) { gtk_tree_view_expand_to_path (GTK_TREE_VIEW (sidebar_links->priv->tree_view), @@ -539,9 +534,8 @@ update_page_callback_foreach (GtkTreeModel *model, } static void -update_page_callback (EvPageCache *page_cache, - gint current_page, - EvSidebarLinks *sidebar_links) +ev_sidebar_links_set_current_page (EvSidebarLinks *sidebar_links, + gint current_page) { GtkTreeSelection *selection; GtkTreeModel *model; @@ -586,6 +580,14 @@ update_page_callback (EvPageCache *page_cache, g_signal_handler_unblock (sidebar_links->priv->tree_view, sidebar_links->priv->row_activated_id); } +static void +update_page_callback (EvSidebarLinks *sidebar_links, + gint old_page, + gint new_page) +{ + ev_sidebar_links_set_current_page (sidebar_links, new_page); +} + static void row_activated_callback (GtkTreeView *treeview, GtkTreePath *arg1, @@ -622,19 +624,32 @@ expand_open_links (GtkTreeView *tree_view, GtkTreeModel *model, GtkTreeIter *par } while (gtk_tree_model_iter_next (model, &iter)); } } - + +static void +ev_sidebar_links_set_links_model (EvSidebarLinks *sidebar_links, + GtkTreeModel *model) +{ + EvSidebarLinksPrivate *priv = sidebar_links->priv; + + if (priv->model == model) + return; + + if (priv->model) + g_object_unref (priv->model); + priv->model = g_object_ref (model); + + g_object_notify (G_OBJECT (sidebar_links), "model"); +} + static void job_finished_callback (EvJobLinks *job, EvSidebarLinks *sidebar_links) { - EvSidebarLinksPrivate *priv; + EvSidebarLinksPrivate *priv = sidebar_links->priv; GtkTreeSelection *selection; - priv = sidebar_links->priv; - - priv->model = job->model; - g_object_notify (G_OBJECT (sidebar_links), "model"); - + ev_sidebar_links_set_links_model (sidebar_links, job->model); + gtk_tree_model_foreach (priv->model, (GtkTreeModelForeachFunc)fill_page_labels, sidebar_links); gtk_tree_view_set_model (GTK_TREE_VIEW (priv->tree_view), job->model); @@ -653,34 +668,34 @@ job_finished_callback (EvJobLinks *job, G_CALLBACK (selection_changed_callback), sidebar_links); } - priv->page_changed_id = g_signal_connect (priv->page_cache, "page-changed", - G_CALLBACK (update_page_callback), - sidebar_links); + priv->page_changed_id = + g_signal_connect_swapped (priv->doc_model, "page-changed", + G_CALLBACK (update_page_callback), + sidebar_links); if (priv->row_activated_id <= 0) { priv->row_activated_id = g_signal_connect (priv->tree_view, "row-activated", G_CALLBACK (row_activated_callback), sidebar_links); } - - update_page_callback (priv->page_cache, - ev_page_cache_get_current_page (priv->page_cache), - sidebar_links); + + ev_sidebar_links_set_current_page (sidebar_links, + ev_document_model_get_page (priv->doc_model)); } static void -ev_sidebar_links_set_document (EvSidebarPage *sidebar_page, - EvDocument *document) +ev_sidebar_links_document_changed_cb (EvDocumentModel *model, + GParamSpec *pspec, + EvSidebarLinks *sidebar_links) { - EvSidebarLinks *sidebar_links; - EvSidebarLinksPrivate *priv; + EvDocument *document = ev_document_model_get_document (model); + EvSidebarLinksPrivate *priv = sidebar_links->priv; - g_return_if_fail (EV_IS_SIDEBAR_PAGE (sidebar_page)); - g_return_if_fail (EV_IS_DOCUMENT (document)); - - sidebar_links = EV_SIDEBAR_LINKS (sidebar_page); + if (!EV_IS_DOCUMENT_LINKS (document)) + return; - priv = sidebar_links->priv; + if (!ev_document_links_has_document_links (EV_DOCUMENT_LINKS (document))) + return; if (priv->document) { gtk_tree_view_set_model (GTK_TREE_VIEW (priv->tree_view), NULL); @@ -688,7 +703,6 @@ ev_sidebar_links_set_document (EvSidebarPage *sidebar_page, } priv->document = g_object_ref (document); - priv->page_cache = ev_page_cache_get (document); if (priv->job) { g_signal_handlers_disconnect_by_func (priv->job, @@ -706,6 +720,22 @@ ev_sidebar_links_set_document (EvSidebarPage *sidebar_page, ev_job_scheduler_push_job (priv->job, EV_JOB_PRIORITY_NONE); } +static void +ev_sidebar_links_set_model (EvSidebarPage *sidebar_page, + EvDocumentModel *model) +{ + EvSidebarLinks *sidebar_links = EV_SIDEBAR_LINKS (sidebar_page); + EvSidebarLinksPrivate *priv = sidebar_links->priv; + + if (priv->doc_model == model) + return; + + priv->doc_model = model; + g_signal_connect (model, "notify::document", + G_CALLBACK (ev_sidebar_links_document_changed_cb), + sidebar_page); +} + static gboolean ev_sidebar_links_support_document (EvSidebarPage *sidebar_page, EvDocument *document) @@ -724,7 +754,7 @@ static void ev_sidebar_links_page_iface_init (EvSidebarPageIface *iface) { iface->support_document = ev_sidebar_links_support_document; - iface->set_document = ev_sidebar_links_set_document; + iface->set_model = ev_sidebar_links_set_model; iface->get_label = ev_sidebar_links_get_label; } diff --git a/shell/ev-sidebar-page.c b/shell/ev-sidebar-page.c index 14bb847c..e0cf8143 100644 --- a/shell/ev-sidebar-page.c +++ b/shell/ev-sidebar-page.c @@ -39,25 +39,25 @@ ev_sidebar_page_support_document (EvSidebarPage *sidebar_page, iface = EV_SIDEBAR_PAGE_GET_IFACE (sidebar_page); - g_return_val_if_fail (iface->set_document, FALSE); + g_return_val_if_fail (iface->support_document, FALSE); return iface->support_document (sidebar_page, document); } -void -ev_sidebar_page_set_document (EvSidebarPage *sidebar_page, - EvDocument *document) +void +ev_sidebar_page_set_model (EvSidebarPage *sidebar_page, + EvDocumentModel *model) { EvSidebarPageIface *iface; g_return_if_fail (EV_IS_SIDEBAR_PAGE (sidebar_page)); - g_return_if_fail (EV_IS_DOCUMENT (document)); + g_return_if_fail (EV_IS_DOCUMENT_MODEL (model)); iface = EV_SIDEBAR_PAGE_GET_IFACE (sidebar_page); - g_assert (iface->set_document); - - iface->set_document (sidebar_page, document); + g_assert (iface->set_model); + + iface->set_model (sidebar_page, model); } const gchar * diff --git a/shell/ev-sidebar-page.h b/shell/ev-sidebar-page.h index 3739a076..a3c0f13d 100644 --- a/shell/ev-sidebar-page.h +++ b/shell/ev-sidebar-page.h @@ -25,6 +25,7 @@ #include #include "ev-document.h" +#include "ev-document-model.h" G_BEGIN_DECLS @@ -45,16 +46,16 @@ struct _EvSidebarPageIface /* Methods */ gboolean (* support_document) (EvSidebarPage *sidebar_page, EvDocument *document); - void (* set_document) (EvSidebarPage *sidebar_page, - EvDocument *document); - const gchar*(* get_label) (EvSidebarPage *sidebar_page); + void (* set_model) (EvSidebarPage *sidebar_page, + EvDocumentModel *model); + const gchar*(* get_label) (EvSidebarPage *sidebar_page); }; -GType ev_sidebar_page_get_type (void); +GType ev_sidebar_page_get_type (void) G_GNUC_CONST; gboolean ev_sidebar_page_support_document (EvSidebarPage *sidebar_page, EvDocument *document); -void ev_sidebar_page_set_document (EvSidebarPage *sidebar_page, - EvDocument *document); +void ev_sidebar_page_set_model (EvSidebarPage *sidebar_page, + EvDocumentModel *model); const gchar* ev_sidebar_page_get_label (EvSidebarPage *page); diff --git a/shell/ev-sidebar-thumbnails.c b/shell/ev-sidebar-thumbnails.c index 7137fa1c..e104c3eb 100644 --- a/shell/ev-sidebar-thumbnails.c +++ b/shell/ev-sidebar-thumbnails.c @@ -66,7 +66,7 @@ struct _EvSidebarThumbnailsPrivate { GtkListStore *list_store; GHashTable *loading_icons; EvDocument *document; - EvPageCache *page_cache; + EvDocumentModel *model; EvThumbsSizeCache *size_cache; gint n_pages, pages_done; @@ -94,8 +94,6 @@ static void ev_sidebar_thumbnails_clear_model (EvSidebarThumbnails static gboolean ev_sidebar_thumbnails_support_document (EvSidebarPage *sidebar_page, EvDocument *document); static void ev_sidebar_thumbnails_page_iface_init (EvSidebarPageIface *iface); -static void ev_sidebar_thumbnails_set_document (EvSidebarPage *sidebar_page, - EvDocument *document); static const gchar* ev_sidebar_thumbnails_get_label (EvSidebarPage *sidebar_page); static void thumbnail_job_completed_callback (EvJobThumbnail *job, EvSidebarThumbnails *sidebar_thumbnails); @@ -585,34 +583,6 @@ ev_sidebar_thumbnails_fill_model (EvSidebarThumbnails *sidebar_thumbnails) } } -static gboolean -refresh (EvSidebarThumbnails *sidebar_thumbnails) -{ - adjustment_changed_cb (sidebar_thumbnails); - return FALSE; -} - -void -ev_sidebar_thumbnails_refresh (EvSidebarThumbnails *sidebar_thumbnails, - int rotation) -{ - sidebar_thumbnails->priv->rotation = rotation; - if (sidebar_thumbnails->priv->loading_icons) - g_hash_table_remove_all (sidebar_thumbnails->priv->loading_icons); - - if (sidebar_thumbnails->priv->document == NULL || - sidebar_thumbnails->priv->n_pages <= 0) - return; - - ev_sidebar_thumbnails_clear_model (sidebar_thumbnails); - ev_sidebar_thumbnails_fill_model (sidebar_thumbnails); - - /* Trigger a redraw */ - sidebar_thumbnails->priv->start_page = -1; - sidebar_thumbnails->priv->end_page = -1; - g_idle_add ((GSourceFunc)refresh, sidebar_thumbnails); -} - static void ev_sidebar_tree_selection_changed (GtkTreeSelection *selection, EvSidebarThumbnails *ev_sidebar_thumbnails) @@ -630,7 +600,7 @@ ev_sidebar_tree_selection_changed (GtkTreeSelection *selection, page = gtk_tree_path_get_indices (path)[0]; gtk_tree_path_free (path); - ev_page_cache_set_current_page_history (priv->page_cache, page); + ev_document_model_set_page (priv->model, page); } static void @@ -655,7 +625,7 @@ ev_sidebar_icon_selection_changed (GtkIconView *icon_view, gtk_tree_path_free (path); g_list_free (selected); - ev_page_cache_set_current_page_history (priv->page_cache, page); + ev_document_model_set_page (priv->model, page); } static void @@ -749,9 +719,8 @@ ev_sidebar_thumbnails_init (EvSidebarThumbnails *ev_sidebar_thumbnails) } static void -page_changed_cb (EvPageCache *page_cache, - int page, - EvSidebarThumbnails *sidebar) +ev_sidebar_thumbnails_set_current_page (EvSidebarThumbnails *sidebar, + gint page) { GtkTreeView *tree_view; GtkTreePath *path; @@ -780,6 +749,45 @@ page_changed_cb (EvPageCache *page_cache, gtk_tree_path_free (path); } +static void +page_changed_cb (EvSidebarThumbnails *sidebar, + gint old_page, + gint new_page) +{ + ev_sidebar_thumbnails_set_current_page (sidebar, new_page); +} + +static gboolean +refresh (EvSidebarThumbnails *sidebar_thumbnails) +{ + adjustment_changed_cb (sidebar_thumbnails); + return FALSE; +} + +static void +ev_sidebar_thumbnails_rotation_changed_cb (EvDocumentModel *model, + GParamSpec *pspec, + EvSidebarThumbnails *sidebar_thumbnails) +{ + gint rotation = ev_document_model_get_rotation (model); + + sidebar_thumbnails->priv->rotation = rotation; + if (sidebar_thumbnails->priv->loading_icons) + g_hash_table_remove_all (sidebar_thumbnails->priv->loading_icons); + + if (sidebar_thumbnails->priv->document == NULL || + sidebar_thumbnails->priv->n_pages <= 0) + return; + + ev_sidebar_thumbnails_clear_model (sidebar_thumbnails); + ev_sidebar_thumbnails_fill_model (sidebar_thumbnails); + + /* Trigger a redraw */ + sidebar_thumbnails->priv->start_page = -1; + sidebar_thumbnails->priv->end_page = -1; + g_idle_add ((GSourceFunc)refresh, sidebar_thumbnails); +} + static void thumbnail_job_completed_callback (EvJobThumbnail *job, EvSidebarThumbnails *sidebar_thumbnails) @@ -797,15 +805,13 @@ thumbnail_job_completed_callback (EvJobThumbnail *job, } static void -ev_sidebar_thumbnails_set_document (EvSidebarPage *sidebar_page, - EvDocument *document) +ev_sidebar_thumbnails_document_changed_cb (EvDocumentModel *model, + GParamSpec *pspec, + EvSidebarThumbnails *sidebar_thumbnails) { - EvSidebarThumbnails *sidebar_thumbnails = EV_SIDEBAR_THUMBNAILS (sidebar_page); - + EvDocument *document = ev_document_model_get_document (model); EvSidebarThumbnailsPrivate *priv = sidebar_thumbnails->priv; - priv->page_cache = ev_page_cache_get (document); - if (!EV_IS_DOCUMENT_THUMBNAILS (document) || ev_document_get_n_pages (document) <= 0 || !ev_document_check_dimensions (document)) { @@ -849,15 +855,35 @@ ev_sidebar_thumbnails_set_document (EvSidebarPage *sidebar_page, } /* Connect to the signal and trigger a fake callback */ - g_signal_connect (priv->page_cache, "page-changed", G_CALLBACK (page_changed_cb), sidebar_thumbnails); + g_signal_connect_swapped (priv->model, "page-changed", + G_CALLBACK (page_changed_cb), + sidebar_thumbnails); + g_signal_connect (priv->model, "notify::rotation", + G_CALLBACK (ev_sidebar_thumbnails_rotation_changed_cb), + sidebar_thumbnails); sidebar_thumbnails->priv->start_page = -1; sidebar_thumbnails->priv->end_page = -1; - page_changed_cb (priv->page_cache, - ev_page_cache_get_current_page (priv->page_cache), - sidebar_thumbnails); + ev_sidebar_thumbnails_set_current_page (sidebar_thumbnails, + ev_document_model_get_page (model)); adjustment_changed_cb (sidebar_thumbnails); } +static void +ev_sidebar_thumbnails_set_model (EvSidebarPage *sidebar_page, + EvDocumentModel *model) +{ + EvSidebarThumbnails *sidebar_thumbnails = EV_SIDEBAR_THUMBNAILS (sidebar_page); + EvSidebarThumbnailsPrivate *priv = sidebar_thumbnails->priv; + + if (priv->model == model) + return; + + priv->model = model; + g_signal_connect (model, "notify::document", + G_CALLBACK (ev_sidebar_thumbnails_document_changed_cb), + sidebar_page); +} + static gboolean ev_sidebar_thumbnails_clear_job (GtkTreeModel *model, GtkTreePath *path, @@ -903,7 +929,7 @@ static void ev_sidebar_thumbnails_page_iface_init (EvSidebarPageIface *iface) { iface->support_document = ev_sidebar_thumbnails_support_document; - iface->set_document = ev_sidebar_thumbnails_set_document; + iface->set_model = ev_sidebar_thumbnails_set_model; iface->get_label = ev_sidebar_thumbnails_get_label; } diff --git a/shell/ev-sidebar-thumbnails.h b/shell/ev-sidebar-thumbnails.h index 5a3dddae..d49836d0 100644 --- a/shell/ev-sidebar-thumbnails.h +++ b/shell/ev-sidebar-thumbnails.h @@ -26,8 +26,6 @@ #include -#include "ev-document.h" - G_BEGIN_DECLS typedef struct _EvSidebarThumbnails EvSidebarThumbnails; @@ -37,7 +35,7 @@ typedef struct _EvSidebarThumbnailsPrivate EvSidebarThumbnailsPrivate; #define EV_TYPE_SIDEBAR_THUMBNAILS (ev_sidebar_thumbnails_get_type()) #define EV_SIDEBAR_THUMBNAILS(object) (G_TYPE_CHECK_INSTANCE_CAST((object), EV_TYPE_SIDEBAR_THUMBNAILS, EvSidebarThumbnails)) #define EV_SIDEBAR_THUMBNAILS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), EV_TYPE_SIDEBAR_THUMBNAILS, EvSidebarThumbnailsClass)) -#define EV_IS_SIDEBAR_THUMBNAILS(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), EV_TYPE_SIDEBAR_THUMBNAILS)) +#define EV_IS_SIDEBAR_THUMBNAILS(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), EV_TYPE_SIDEBAR_THUMBNAILS)) #define EV_IS_SIDEBAR_THUMBNAILS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), EV_TYPE_SIDEBAR_THUMBNAILS)) #define EV_SIDEBAR_THUMBNAILS_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS((object), EV_TYPE_SIDEBAR_THUMBNAILS, EvSidebarThumbnailsClass)) @@ -51,10 +49,8 @@ struct _EvSidebarThumbnailsClass { GtkVBoxClass base_class; }; -GType ev_sidebar_thumbnails_get_type (void); +GType ev_sidebar_thumbnails_get_type (void) G_GNUC_CONST; GtkWidget *ev_sidebar_thumbnails_new (void); -void ev_sidebar_thumbnails_refresh (EvSidebarThumbnails *sidebar_thumbnails, - int rotation); G_END_DECLS diff --git a/shell/ev-sidebar.c b/shell/ev-sidebar.c index 2d97381d..f15b376a 100644 --- a/shell/ev-sidebar.c +++ b/shell/ev-sidebar.c @@ -53,7 +53,8 @@ struct _EvSidebarPrivate { GtkWidget *menu; GtkWidget *hbox; GtkWidget *label; - + + EvDocumentModel *model; GtkTreeModel *page_model; }; @@ -439,7 +440,9 @@ ev_sidebar_add_page (EvSidebar *ev_sidebar, g_return_if_fail (EV_IS_SIDEBAR (ev_sidebar)); g_return_if_fail (EV_IS_SIDEBAR_PAGE (main_widget)); g_return_if_fail (GTK_IS_WIDGET (main_widget)); - + + ev_sidebar_page_set_model (EV_SIDEBAR_PAGE (main_widget), + ev_sidebar->priv->model); title = ev_sidebar_page_get_label (EV_SIDEBAR_PAGE (main_widget)); index = gtk_notebook_append_page (GTK_NOTEBOOK (ev_sidebar->priv->notebook), @@ -480,22 +483,17 @@ ev_sidebar_add_page (EvSidebar *ev_sidebar, g_free (label_title); } -void -ev_sidebar_set_document (EvSidebar *sidebar, - EvDocument *document) +static void +ev_sidebar_document_changed_cb (EvDocumentModel *model, + GParamSpec *pspec, + EvSidebar *sidebar) { - EvSidebarPrivate *priv; + EvSidebarPrivate *priv = sidebar->priv; + EvDocument *document = ev_document_model_get_document (model); GtkTreeIter iter; gboolean valid; - gboolean has_pages; - - g_return_if_fail (EV_IS_SIDEBAR (sidebar)); - g_return_if_fail (EV_IS_DOCUMENT (document)); - - priv = sidebar->priv; - - has_pages = FALSE; - + gboolean has_pages = FALSE; + for (valid = gtk_tree_model_get_iter_first (priv->page_model, &iter); valid; valid = gtk_tree_model_iter_next (priv->page_model, &iter)) { @@ -506,18 +504,16 @@ ev_sidebar_set_document (EvSidebar *sidebar, PAGE_COLUMN_MAIN_WIDGET, &widget, PAGE_COLUMN_MENU_ITEM, &menu_widget, -1); - if (ev_sidebar_page_support_document (EV_SIDEBAR_PAGE (widget), document)) { - ev_sidebar_page_set_document (EV_SIDEBAR_PAGE (widget), document); - has_pages = TRUE; + has_pages = TRUE; } else { - gtk_widget_set_sensitive (menu_widget, FALSE); + gtk_widget_set_sensitive (menu_widget, FALSE); } g_object_unref (widget); g_object_unref (menu_widget); } - + if (!has_pages) { gtk_widget_hide (GTK_WIDGET (sidebar)); } else { @@ -526,3 +522,18 @@ ev_sidebar_set_document (EvSidebar *sidebar, } } +void +ev_sidebar_set_model (EvSidebar *sidebar, + EvDocumentModel *model) +{ + g_return_if_fail (EV_IS_SIDEBAR (sidebar)); + g_return_if_fail (EV_IS_DOCUMENT_MODEL (model)); + + if (model == sidebar->priv->model) + return; + + sidebar->priv->model = model; + g_signal_connect (model, "notify::document", + G_CALLBACK (ev_sidebar_document_changed_cb), + sidebar); +} diff --git a/shell/ev-sidebar.h b/shell/ev-sidebar.h index 5f01132e..3601b73d 100644 --- a/shell/ev-sidebar.h +++ b/shell/ev-sidebar.h @@ -26,7 +26,7 @@ #include -#include "ev-document.h" +#include "ev-document-model.h" G_BEGIN_DECLS @@ -51,14 +51,14 @@ struct _EvSidebarClass { GtkVBoxClass base_class; }; -GType ev_sidebar_get_type (void); -GtkWidget *ev_sidebar_new (void); -void ev_sidebar_add_page (EvSidebar *ev_sidebar, - GtkWidget *main_widget); -void ev_sidebar_set_page (EvSidebar *ev_sidebar, - GtkWidget *main_widget); -void ev_sidebar_set_document (EvSidebar *ev_sidebar, - EvDocument *document); +GType ev_sidebar_get_type (void) G_GNUC_CONST; +GtkWidget *ev_sidebar_new (void); +void ev_sidebar_add_page (EvSidebar *ev_sidebar, + GtkWidget *main_widget); +void ev_sidebar_set_page (EvSidebar *ev_sidebar, + GtkWidget *main_widget); +void ev_sidebar_set_model (EvSidebar *sidebar, + EvDocumentModel *model); G_END_DECLS diff --git a/shell/ev-window.c b/shell/ev-window.c index 7593fd8f..82425dc2 100644 --- a/shell/ev-window.c +++ b/shell/ev-window.c @@ -176,6 +176,7 @@ struct _EvWindowPrivate { GList *attach_list; /* Document */ + EvDocumentModel *model; char *uri; glong uri_mtime; char *local_uri; @@ -185,7 +186,6 @@ struct _EvWindowPrivate { EvDocument *document; EvHistory *history; - EvPageCache *page_cache; EvWindowPageMode page_mode; EvWindowTitle *title; @@ -226,6 +226,9 @@ struct _EvWindowPrivate { #define ATTACHMENTS_SIDEBAR_ID "attachments" #define LAYERS_SIDEBAR_ID "layers" +#define MIN_SCALE 0.05409 +#define MAX_SCALE 4.0 + static const gchar *document_print_settings[] = { GTK_PRINT_SETTINGS_N_COPIES, GTK_PRINT_SETTINGS_COLLATE, @@ -254,10 +257,10 @@ static void ev_window_set_icon_from_thumbnail (EvJobThumbnail *job, EvWindow *ev_window); static void ev_window_save_job_cb (EvJob *save, EvWindow *window); -static void ev_window_sizing_mode_changed_cb (EvView *view, +static void ev_window_sizing_mode_changed_cb (EvDocumentModel *model, GParamSpec *pspec, EvWindow *ev_window); -static void ev_window_zoom_changed_cb (EvView *view, +static void ev_window_zoom_changed_cb (EvDocumentModel *model, GParamSpec *pspec, EvWindow *ev_window); static void ev_window_add_recent (EvWindow *window, @@ -339,11 +342,8 @@ ev_window_setup_action_sensitivity (EvWindow *ev_window) if (document) { has_document = TRUE; - info = ev_document_get_info (document); - } - - if (has_document && ev_window->priv->page_cache) { has_pages = ev_document_get_n_pages (document) > 0; + info = ev_document_get_info (document); } if (!info || info->fields_mask == 0) { @@ -422,9 +422,10 @@ ev_window_update_actions (EvWindow *ev_window) gboolean has_pages = FALSE; gboolean presentation_mode; gboolean can_find_in_page = FALSE; + EvSizingMode sizing_mode; - if (ev_window->priv->document && ev_window->priv->page_cache) { - page = ev_page_cache_get_current_page (ev_window->priv->page_cache); + if (ev_window->priv->document) { + page = ev_document_model_get_page (ev_window->priv->model); n_pages = ev_document_get_n_pages (ev_window->priv->document); has_pages = n_pages > 0; } @@ -466,17 +467,16 @@ ev_window_update_actions (EvWindow *ev_window) ev_window_set_action_sensitive (ev_window, "GoLastPage", FALSE); } - if (has_pages && - ev_view_get_sizing_mode (view) != EV_SIZING_FIT_WIDTH && - ev_view_get_sizing_mode (view) != EV_SIZING_BEST_FIT) { + sizing_mode = ev_document_model_get_sizing_mode (ev_window->priv->model); + if (has_pages && sizing_mode != EV_SIZING_FIT_WIDTH && sizing_mode != EV_SIZING_BEST_FIT) { GtkAction *action; float zoom; float real_zoom; - action = gtk_action_group_get_action (ev_window->priv->action_group, + action = gtk_action_group_get_action (ev_window->priv->action_group, ZOOM_CONTROL_ACTION); - real_zoom = ev_view_get_zoom (EV_VIEW (ev_window->priv->view)); + real_zoom = ev_document_model_get_scale (ev_window->priv->model); real_zoom *= 72.0 / get_screen_dpi (GTK_WINDOW (ev_window)); zoom = ephy_zoom_get_nearest_zoom_level (real_zoom); @@ -732,19 +732,6 @@ ev_window_warning_message (EvWindow *window, ev_window_set_message_area (window, area); } -static void -page_changed_cb (EvPageCache *page_cache, - gint page, - EvWindow *ev_window) -{ - ev_window_update_actions (ev_window); - - ev_window_update_find_status_message (ev_window); - - if (!ev_window_is_empty (ev_window)) - ev_metadata_manager_set_int (ev_window->priv->uri, "page", page); -} - typedef struct _FindTask { const gchar *page_label; gchar *chapter; @@ -843,23 +830,29 @@ ev_window_add_history (EvWindow *window, gint page, EvLink *link) static void view_handle_link_cb (EvView *view, EvLink *link, EvWindow *window) { - int current_page = ev_page_cache_get_current_page (window->priv->page_cache); + int current_page = ev_document_model_get_page (window->priv->model); ev_window_add_history (window, 0, link); ev_window_add_history (window, current_page, NULL); } static void -history_changed_cb (EvPageCache *page_cache, - gint page, - EvWindow *window) +ev_window_page_changed_cb (EvWindow *ev_window, + gint old_page, + gint new_page, + EvDocumentModel *model) { - int current_page = ev_page_cache_get_current_page (window->priv->page_cache); + ev_window_update_actions (ev_window); - ev_window_add_history (window, page, NULL); - ev_window_add_history (window, current_page, NULL); + ev_window_update_find_status_message (ev_window); - return; + if (abs (new_page - old_page) > 1) { + ev_window_add_history (ev_window, new_page, NULL); + ev_window_add_history (ev_window, old_page, NULL); + } + + if (!ev_window_is_empty (ev_window)) + ev_metadata_manager_set_int (ev_window->priv->uri, "page", new_page); } static void @@ -939,6 +932,66 @@ setup_sidebar_from_metadata (EvWindow *window) } } +static void +setup_model_from_metadata (EvWindow *window) +{ + gchar *uri = window->priv->uri; + GValue page = { 0, }; + GValue sizing_mode = { 0, }; + GValue zoom = { 0, }; + GValue rotation = { 0, }; + + /* Current page */ + if (ev_metadata_manager_get (uri, "page", &page, TRUE)) { + ev_document_model_set_page (window->priv->model, + g_value_get_int (&page)); + g_value_unset (&page); + } + + /* Sizing mode */ + if (ev_metadata_manager_get (uri, "sizing_mode", &sizing_mode, FALSE)) { + GEnumValue *enum_value; + + enum_value = g_enum_get_value_by_nick + (g_type_class_peek (EV_TYPE_SIZING_MODE), g_value_get_string (&sizing_mode)); + ev_document_model_set_sizing_mode (window->priv->model, enum_value->value); + g_value_unset (&sizing_mode); + } + + /* Zoom */ + if (ev_document_model_get_sizing_mode (window->priv->model) == EV_SIZING_FREE && + ev_metadata_manager_get (uri, "zoom", &zoom, FALSE)) { + gdouble zoom_value; + + zoom_value = g_value_get_double (&zoom); + zoom_value *= get_screen_dpi (GTK_WINDOW (window)) / 72.0; + ev_document_model_set_scale (window->priv->model, zoom_value); + g_value_unset (&zoom); + } + + /* Rotation */ + if (ev_metadata_manager_get (uri, "rotation", &rotation, TRUE)) { + gint rotation_value; + + switch (g_value_get_int (&rotation)) { + case 90: + rotation_value = 90; + break; + case 180: + rotation_value = 180; + break; + case 270: + rotation_value = 270; + break; + default: + rotation_value = 0; + break; + } + ev_document_model_set_rotation (window->priv->model, rotation_value); + g_value_unset (&rotation); + } +} + static void setup_document_from_metadata (EvWindow *window) { @@ -949,20 +1002,21 @@ setup_document_from_metadata (EvWindow *window) GValue width_ratio = { 0, }; GValue height_ratio = { 0, }; +#if 0 /* FIXME */ /* View the previously shown page, but make sure to not open a document on * the last page, since closing it on the last page most likely means the * user was finished reading the document. In that case, reopening should * show the first page. */ - if (uri && ev_metadata_manager_get (uri, "page", &page, TRUE)) { + if (ev_metadata_manager_get (uri, "page", &page, TRUE)) { gint n_pages; gint new_page; n_pages = ev_document_get_n_pages (window->priv->document); new_page = CLAMP (g_value_get_int (&page), 0, n_pages - 1); - ev_page_cache_set_current_page (window->priv->page_cache, - new_page); + ev_document_model_set_page (window->priv->model, new_page); g_value_unset (&page); } +#endif setup_sidebar_from_metadata (window); @@ -1045,33 +1099,10 @@ setup_view_from_metadata (EvWindow *window) { EvView *view = EV_VIEW (window->priv->view); gchar *uri = window->priv->uri; - GEnumValue *enum_value; - GValue sizing_mode = { 0, }; - GValue zoom = { 0, }; GValue continuous = { 0, }; GValue dual_page = { 0, }; GValue presentation = { 0, }; GValue fullscreen = { 0, }; - GValue rotation = { 0, }; - - /* Sizing mode */ - if (ev_metadata_manager_get (uri, "sizing_mode", &sizing_mode, FALSE)) { - enum_value = g_enum_get_value_by_nick - (g_type_class_peek (EV_TYPE_SIZING_MODE), g_value_get_string (&sizing_mode)); - g_value_unset (&sizing_mode); - ev_view_set_sizing_mode (view, enum_value->value); - } - - /* Zoom */ - if (ev_metadata_manager_get (uri, "zoom", &zoom, FALSE) && - ev_view_get_sizing_mode (view) == EV_SIZING_FREE) { - gdouble zoom_value; - - zoom_value = g_value_get_double (&zoom); - zoom_value *= get_screen_dpi (GTK_WINDOW (window)) / 72.0; - ev_view_set_zoom (view, zoom_value, FALSE); - g_value_unset (&zoom); - } /* Continuous */ if (ev_metadata_manager_get (uri, "continuous", &continuous, FALSE)) { @@ -1100,26 +1131,6 @@ setup_view_from_metadata (EvWindow *window) } g_value_unset (&fullscreen); } - - /* Rotation */ - if (ev_metadata_manager_get (uri, "rotation", &rotation, TRUE)) { - if (g_value_get_int (&rotation)) { - switch (g_value_get_int (&rotation)) { - case 90: - ev_view_set_rotation (view, 90); - break; - case 180: - ev_view_set_rotation (view, 180); - break; - case 270: - ev_view_set_rotation (view, 270); - break; - default: - break; - } - } - g_value_unset (&rotation); - } } static void @@ -1179,7 +1190,6 @@ ev_window_setup_document (EvWindow *ev_window) { const EvDocumentInfo *info; EvDocument *document = ev_window->priv->document; - EvSidebar *sidebar = EV_SIDEBAR (ev_window->priv->sidebar); GtkAction *action; ev_window->priv->setup_document_idle = 0; @@ -1190,10 +1200,6 @@ ev_window_setup_document (EvWindow *ev_window) ev_window_title_set_document (ev_window->priv->title, document); ev_window_title_set_uri (ev_window->priv->title, ev_window->priv->uri); - ev_sidebar_set_document (sidebar, document); - - action = gtk_action_group_get_action (ev_window->priv->action_group, PAGE_SELECTOR_ACTION); - ev_page_action_set_document (EV_PAGE_ACTION (action), document); ev_window_setup_action_sensitivity (ev_window); if (ev_window->priv->history) @@ -1219,19 +1225,14 @@ ev_window_setup_document (EvWindow *ev_window) static void ev_window_set_document (EvWindow *ev_window, EvDocument *document) { - EvView *view = EV_VIEW (ev_window->priv->view); + if (ev_window->priv->document == document) + return; if (ev_window->priv->document) g_object_unref (ev_window->priv->document); ev_window->priv->document = g_object_ref (document); ev_window_set_message_area (ev_window, NULL); - - ev_window->priv->page_cache = ev_page_cache_get (ev_window->priv->document); - g_signal_connect (ev_window->priv->page_cache, "page-changed", - G_CALLBACK (page_changed_cb), ev_window); - g_signal_connect (ev_window->priv->page_cache, "history-changed", - G_CALLBACK (history_changed_cb), ev_window); if (ev_window->priv->in_reload && ev_window->priv->dest) { gint page; @@ -1240,7 +1241,7 @@ ev_window_set_document (EvWindow *ev_window, EvDocument *document) page = CLAMP (ev_link_dest_get_page (ev_window->priv->dest), 0, ev_document_get_n_pages (document) - 1); - ev_page_cache_set_current_page (ev_window->priv->page_cache, page); + ev_document_model_set_page (ev_window->priv->model, page); g_object_unref (ev_window->priv->dest); ev_window->priv->dest = NULL; } @@ -1251,8 +1252,6 @@ ev_window_set_document (EvWindow *ev_window, EvDocument *document) } else if (!ev_document_check_dimensions (document)) { ev_window_warning_message (ev_window, "%s", _("The document contains only empty pages")); - } else { - ev_view_set_document (view, document); } if (ev_window->priv->setup_document_idle > 0) @@ -1386,7 +1385,7 @@ ev_window_load_job_cb (EvJob *job, /* Success! */ if (!ev_job_is_failed (job)) { - ev_window_set_document (ev_window, document); + ev_document_model_set_document (ev_window->priv->model, document); setup_document_from_metadata (ev_window); setup_view_from_metadata (ev_window); @@ -1503,8 +1502,8 @@ ev_window_reload_job_cb (EvJob *job, if (ev_window->priv->dest) { dest = g_object_ref (ev_window->priv->dest); } - ev_window_set_document (ev_window, job->document); - + ev_document_model_set_document (ev_window->priv->model, + job->document); ev_window_handle_link (ev_window, dest); /* Restart the search after reloading */ @@ -1839,6 +1838,7 @@ ev_window_open_uri (EvWindow *ev_window, ev_window->priv->dest = dest ? g_object_ref (dest) : NULL; setup_size_from_metadata (ev_window); + setup_model_from_metadata (ev_window); ev_window->priv->load_job = ev_job_load_new (uri); g_signal_connect (ev_window->priv->load_job, @@ -2013,7 +2013,7 @@ ev_window_reload_document (EvWindow *ev_window, ev_window_clear_reload_job (ev_window); ev_window->priv->in_reload = TRUE; - page = ev_page_cache_get_current_page (ev_window->priv->page_cache); + page = ev_document_model_get_page (ev_window->priv->model); if (ev_window->priv->dest) g_object_unref (ev_window->priv->dest); @@ -2194,13 +2194,11 @@ ev_window_cmd_file_open_copy_at_dest (EvWindow *window, EvLinkDest *dest) static void ev_window_cmd_file_open_copy (GtkAction *action, EvWindow *window) { - EvPageCache *page_cache; EvLinkDest *dest; gint current_page; - page_cache = ev_page_cache_get (window->priv->document); - current_page = ev_page_cache_get_current_page (page_cache); - + current_page = ev_document_model_get_page (window->priv->model); + dest = ev_link_dest_new_page (current_page); ev_window_cmd_file_open_copy_at_dest (window, dest); g_object_unref (dest); @@ -2988,7 +2986,6 @@ ev_window_print_range (EvWindow *ev_window, gint last_page) { EvPrintOperation *op; - EvPageCache *page_cache; gint current_page; gint document_last_page; @@ -3014,8 +3011,7 @@ ev_window_print_range (EvWindow *ev_window, G_CALLBACK (ev_window_print_operation_done), (gpointer)ev_window); - page_cache = ev_page_cache_get (ev_window->priv->document); - current_page = ev_page_cache_get_current_page (page_cache); + current_page = ev_document_model_get_page (ev_window->priv->model); document_last_page = ev_document_get_n_pages (ev_window->priv->document); if (!ev_window->priv->print_settings) { @@ -3238,9 +3234,9 @@ ev_window_cmd_view_best_fit (GtkAction *action, EvWindow *ev_window) ev_window_stop_presentation (ev_window, TRUE); if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action))) { - ev_view_set_sizing_mode (EV_VIEW (ev_window->priv->view), EV_SIZING_BEST_FIT); + ev_document_model_set_sizing_mode (ev_window->priv->model, EV_SIZING_BEST_FIT); } else { - ev_view_set_sizing_mode (EV_VIEW (ev_window->priv->view), EV_SIZING_FREE); + ev_document_model_set_sizing_mode (ev_window->priv->model, EV_SIZING_FREE); } ev_window_update_actions (ev_window); } @@ -3251,9 +3247,9 @@ ev_window_cmd_view_page_width (GtkAction *action, EvWindow *ev_window) ev_window_stop_presentation (ev_window, TRUE); if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action))) { - ev_view_set_sizing_mode (EV_VIEW (ev_window->priv->view), EV_SIZING_FIT_WIDTH); + ev_document_model_set_sizing_mode (ev_window->priv->model, EV_SIZING_FIT_WIDTH); } else { - ev_view_set_sizing_mode (EV_VIEW (ev_window->priv->view), EV_SIZING_FREE); + ev_document_model_set_sizing_mode (ev_window->priv->model, EV_SIZING_FREE); } ev_window_update_actions (ev_window); } @@ -3665,15 +3661,17 @@ ev_window_screen_changed (GtkWidget *widget, EvWindow *window = EV_WINDOW (widget); EvWindowPrivate *priv = window->priv; GdkScreen *screen; + gdouble dpi; screen = gtk_widget_get_screen (widget); if (screen == old_screen) return; ev_window_setup_gtk_settings (window); - ev_view_set_screen_dpi (EV_VIEW (priv->view), - get_screen_dpi (GTK_WINDOW (window))); - + dpi = get_screen_dpi (GTK_WINDOW (window)); + ev_document_model_set_min_scale (priv->model, MIN_SCALE * dpi / 72.0); + ev_document_model_set_max_scale (priv->model, MAX_SCALE * dpi / 72.0); + if (GTK_WIDGET_CLASS (ev_window_parent_class)->screen_changed) { GTK_WIDGET_CLASS (ev_window_parent_class)->screen_changed (widget, old_screen); } @@ -3745,13 +3743,17 @@ ev_window_set_page_mode (EvWindow *window, static void ev_window_cmd_edit_rotate_left (GtkAction *action, EvWindow *ev_window) { - ev_view_rotate_left (EV_VIEW (ev_window->priv->view)); + gint rotation = ev_document_model_get_rotation (ev_window->priv->model); + + ev_document_model_set_rotation (ev_window->priv->model, rotation - 90); } static void ev_window_cmd_edit_rotate_right (GtkAction *action, EvWindow *ev_window) { - ev_view_rotate_right (EV_VIEW (ev_window->priv->view)); + gint rotation = ev_document_model_get_rotation (ev_window->priv->model); + + ev_document_model_set_rotation (ev_window->priv->model, rotation + 90); } static void @@ -3803,7 +3805,7 @@ ev_window_cmd_view_zoom_in (GtkAction *action, EvWindow *ev_window) { g_return_if_fail (EV_IS_WINDOW (ev_window)); - ev_view_set_sizing_mode (EV_VIEW (ev_window->priv->view), EV_SIZING_FREE); + ev_document_model_set_sizing_mode (ev_window->priv->model, EV_SIZING_FREE); ev_view_zoom_in (EV_VIEW (ev_window->priv->view)); } @@ -3812,7 +3814,7 @@ ev_window_cmd_view_zoom_out (GtkAction *action, EvWindow *ev_window) { g_return_if_fail (EV_IS_WINDOW (ev_window)); - ev_view_set_sizing_mode (EV_VIEW (ev_window->priv->view), EV_SIZING_FREE); + ev_document_model_set_sizing_mode (ev_window->priv->model, EV_SIZING_FREE); ev_view_zoom_out (EV_VIEW (ev_window->priv->view)); } @@ -3837,7 +3839,7 @@ ev_window_cmd_go_first_page (GtkAction *action, EvWindow *ev_window) { g_return_if_fail (EV_IS_WINDOW (ev_window)); - ev_page_cache_set_current_page (ev_window->priv->page_cache, 0); + ev_document_model_set_page (ev_window->priv->model, 0); } static void @@ -3845,8 +3847,8 @@ ev_window_cmd_go_last_page (GtkAction *action, EvWindow *ev_window) { g_return_if_fail (EV_IS_WINDOW (ev_window)); - ev_page_cache_set_current_page (ev_window->priv->page_cache, - ev_document_get_n_pages (ev_window->priv->document) - 1); + ev_document_model_set_page (ev_window->priv->model, + ev_document_get_n_pages (ev_window->priv->document) - 1); } static void @@ -3857,10 +3859,11 @@ ev_window_cmd_go_forward (GtkAction *action, EvWindow *ev_window) g_return_if_fail (EV_IS_WINDOW (ev_window)); n_pages = ev_document_get_n_pages (ev_window->priv->document); - current_page = ev_page_cache_get_current_page (ev_window->priv->page_cache); + current_page = ev_document_model_get_page (ev_window->priv->model); - if (current_page + 10 < n_pages) - ev_page_cache_set_current_page (ev_window->priv->page_cache, current_page + 10); + if (current_page + 10 < n_pages) { + ev_document_model_set_page (ev_window->priv->model, current_page + 10); + } } static void @@ -3870,10 +3873,11 @@ ev_window_cmd_go_backward (GtkAction *action, EvWindow *ev_window) g_return_if_fail (EV_IS_WINDOW (ev_window)); - current_page = ev_page_cache_get_current_page (ev_window->priv->page_cache); + current_page = ev_document_model_get_page (ev_window->priv->model); - if (current_page - 10 >= 0) - ev_page_cache_set_current_page (ev_window->priv->page_cache, current_page - 10); + if (current_page - 10 >= 0) { + ev_document_model_set_page (ev_window->priv->model, current_page - 10); + } } static void @@ -3957,23 +3961,30 @@ save_sizing_mode (EvWindow *window) EvSizingMode mode; GEnumValue *enum_value; - mode = ev_view_get_sizing_mode (EV_VIEW (window->priv->view)); - enum_value = g_enum_get_value (g_type_class_peek (EV_TYPE_SIZING_MODE), mode); + if (ev_window_is_empty (window)) + return; - if (!ev_window_is_empty (window)) - ev_metadata_manager_set_string (window->priv->uri, "sizing_mode", - enum_value->value_nick); + mode = ev_document_model_get_sizing_mode (window->priv->model); + enum_value = g_enum_get_value (g_type_class_peek (EV_TYPE_SIZING_MODE), mode); + ev_metadata_manager_set_string (window->priv->uri, "sizing_mode", + enum_value->value_nick); } -static void -ev_window_sizing_mode_changed_cb (EvView *view, GParamSpec *pspec, - EvWindow *ev_window) +static void +ev_window_document_changed_cb (EvDocumentModel *model, + GParamSpec *pspec, + EvWindow *ev_window) { - EvSizingMode sizing_mode; + ev_window_set_document (ev_window, + ev_document_model_get_document (model)); +} - g_object_get (ev_window->priv->view, - "sizing-mode", &sizing_mode, - NULL); +static void +ev_window_sizing_mode_changed_cb (EvDocumentModel *model, + GParamSpec *pspec, + EvWindow *ev_window) +{ + EvSizingMode sizing_mode = ev_document_model_get_sizing_mode (model); g_object_set (ev_window->priv->scrolled_window, "hscrollbar-policy", @@ -3986,15 +3997,15 @@ ev_window_sizing_mode_changed_cb (EvView *view, GParamSpec *pspec, save_sizing_mode (ev_window); } -static void -ev_window_zoom_changed_cb (EvView *view, GParamSpec *pspec, EvWindow *ev_window) +static void +ev_window_zoom_changed_cb (EvDocumentModel *model, GParamSpec *pspec, EvWindow *ev_window) { ev_window_update_actions (ev_window); - if (ev_view_get_sizing_mode (view) == EV_SIZING_FREE && !ev_window_is_empty (ev_window)) { + if (ev_document_model_get_sizing_mode (model) == EV_SIZING_FREE && !ev_window_is_empty (ev_window)) { gdouble zoom; - zoom = ev_view_get_zoom (view); + zoom = ev_document_model_get_scale (model); zoom *= 72.0 / get_screen_dpi (GTK_WINDOW(ev_window)); ev_metadata_manager_set_double (ev_window->priv->uri, "zoom", zoom); } @@ -4038,19 +4049,15 @@ ev_window_continuous_changed_cb (EvView *view, GParamSpec *pspec, EvWindow *ev_w ev_view_get_continuous (EV_VIEW (ev_window->priv->view))); } -static void -ev_window_rotation_changed_cb (EvView *view, GParamSpec *pspec, EvWindow *window) +static void +ev_window_rotation_changed_cb (EvDocumentModel *model, GParamSpec *pspec, EvWindow *window) { - int rotation; - - rotation = ev_view_get_rotation (EV_VIEW (window->priv->view)); + gint rotation = ev_document_model_get_rotation (model); if (!ev_window_is_empty (window)) ev_metadata_manager_set_int (window->priv->uri, "rotation", rotation); - ev_sidebar_thumbnails_refresh (EV_SIDEBAR_THUMBNAILS (window->priv->sidebar_thumbs), - rotation); ev_window_refresh_window_thumbnail (window, rotation); } @@ -4376,7 +4383,7 @@ ev_window_update_find_status_message (EvWindow *ev_window) gint n_results; n_results = ev_job_find_get_n_results (EV_JOB_FIND (ev_window->priv->find_job), - ev_page_cache_get_current_page (ev_window->priv->page_cache)); + ev_document_model_get_page (ev_window->priv->model)); /* TRANS: Sometimes this could be better translated as "%d hit(s) on this page". Therefore this string contains plural cases. */ @@ -4479,7 +4486,7 @@ find_bar_search_changed_cb (EggFindBar *find_bar, if (search_string && search_string[0]) { ev_window->priv->find_job = ev_job_find_new (ev_window->priv->document, - ev_page_cache_get_current_page (ev_window->priv->page_cache), + ev_document_model_get_page (ev_window->priv->model), ev_document_get_n_pages (ev_window->priv->document), search_string, case_sensitive); @@ -4534,8 +4541,6 @@ zoom_control_changed_cb (EphyZoomAction *action, EvWindow *ev_window) { EvSizingMode mode; - - g_return_if_fail (EV_IS_WINDOW (ev_window)); if (zoom == EPHY_ZOOM_BEST_FIT) { mode = EV_SIZING_BEST_FIT; @@ -4545,12 +4550,11 @@ zoom_control_changed_cb (EphyZoomAction *action, mode = EV_SIZING_FREE; } - ev_view_set_sizing_mode (EV_VIEW (ev_window->priv->view), mode); - + ev_document_model_set_sizing_mode (ev_window->priv->model, mode); + if (mode == EV_SIZING_FREE) { - ev_view_set_zoom (EV_VIEW (ev_window->priv->view), - zoom * get_screen_dpi (GTK_WINDOW (ev_window)) / 72.0, - FALSE); + ev_document_model_set_scale (ev_window->priv->model, + zoom * get_screen_dpi (GTK_WINDOW (ev_window)) / 72.0); } } @@ -4671,9 +4675,12 @@ ev_window_dispose (GObject *object) priv->recent_ui_id = 0; - if (priv->page_cache) { - g_signal_handlers_disconnect_by_func (priv->page_cache, page_changed_cb, window); - priv->page_cache = NULL; + if (priv->model) { + g_signal_handlers_disconnect_by_func (priv->model, + ev_window_page_changed_cb, + window); + g_object_unref (priv->model); + priv->model = NULL; } if (priv->document) { @@ -5103,6 +5110,8 @@ register_custom_actions (EvWindow *window, GtkActionGroup *group) "icon_name", "text-x-generic", "visible_overflown", FALSE, NULL); + ev_page_action_set_model (EV_PAGE_ACTION (action), + window->priv->model); g_signal_connect (action, "activate_link", G_CALLBACK (activate_link_cb), window); gtk_action_group_add_action (group, action); @@ -5213,7 +5222,7 @@ sidebar_widget_model_set (EvSidebarLinks *ev_sidebar_links, NULL); action = gtk_action_group_get_action (ev_window->priv->action_group, PAGE_SELECTOR_ACTION); - ev_page_action_set_model (EV_PAGE_ACTION (action), model); + ev_page_action_set_links_model (EV_PAGE_ACTION (action), model); g_object_unref (model); } @@ -5858,6 +5867,7 @@ ev_window_init (EvWindow *ev_window) GtkWidget *sidebar_widget; GObject *mpkeys; gchar *ui_path; + gdouble dpi; g_signal_connect (ev_window, "configure_event", G_CALLBACK (window_configure_event_cb), NULL); @@ -5866,6 +5876,8 @@ ev_window_init (EvWindow *ev_window) ev_window->priv = EV_WINDOW_GET_PRIVATE (ev_window); + ev_window->priv->model = ev_document_model_new (); + ev_window->priv->page_mode = PAGE_MODE_DOCUMENT; ev_window->priv->title = ev_window_title_new (ev_window); @@ -5964,6 +5976,8 @@ ev_window_init (EvWindow *ev_window) gtk_widget_show (ev_window->priv->hpaned); ev_window->priv->sidebar = ev_sidebar_new (); + ev_sidebar_set_model (EV_SIDEBAR (ev_window->priv->sidebar), + ev_window->priv->model); gtk_paned_pack1 (GTK_PANED (ev_window->priv->hpaned), ev_window->priv->sidebar, FALSE, FALSE); gtk_widget_show (ev_window->priv->sidebar); @@ -6031,6 +6045,10 @@ ev_window_init (EvWindow *ev_window) gtk_widget_show (ev_window->priv->view_box); ev_window->priv->view = ev_view_new (); + ev_view_set_model (EV_VIEW (ev_window->priv->view), ev_window->priv->model); + dpi = get_screen_dpi (GTK_WINDOW (ev_window)); + ev_document_model_set_min_scale (ev_window->priv->model, MIN_SCALE * dpi / 72.0); + ev_document_model_set_max_scale (ev_window->priv->model, MAX_SCALE * dpi / 72.0); ev_view_set_screen_dpi (EV_VIEW (ev_window->priv->view), get_screen_dpi (GTK_WINDOW (ev_window))); ev_window->priv->password_view = ev_password_view_new (GTK_WINDOW (ev_window)); @@ -6070,14 +6088,29 @@ ev_window_init (EvWindow *ev_window) gtk_container_add (GTK_CONTAINER (ev_window->priv->scrolled_window), ev_window->priv->view); - g_signal_connect (ev_window->priv->view, + /* Connect to model signals */ + g_signal_connect_swapped (ev_window->priv->model, + "page-changed", + G_CALLBACK (ev_window_page_changed_cb), + ev_window); + g_signal_connect (ev_window->priv->model, + "notify::document", + G_CALLBACK (ev_window_document_changed_cb), + ev_window); + g_signal_connect (ev_window->priv->model, + "notify::scale", + G_CALLBACK (ev_window_zoom_changed_cb), + ev_window); + g_signal_connect (ev_window->priv->model, "notify::sizing-mode", G_CALLBACK (ev_window_sizing_mode_changed_cb), ev_window); - g_signal_connect (ev_window->priv->view, - "notify::zoom", - G_CALLBACK (ev_window_zoom_changed_cb), + g_signal_connect (ev_window->priv->model, + "notify::rotation", + G_CALLBACK (ev_window_rotation_changed_cb), ev_window); + + /* Connect to view signals */ g_signal_connect (ev_window->priv->view, "notify::dual-page", G_CALLBACK (ev_window_dual_mode_changed_cb), @@ -6086,10 +6119,6 @@ ev_window_init (EvWindow *ev_window) "notify::continuous", G_CALLBACK (ev_window_continuous_changed_cb), ev_window); - g_signal_connect (ev_window->priv->view, - "notify::rotation", - G_CALLBACK (ev_window_rotation_changed_cb), - ev_window); g_signal_connect (ev_window->priv->view, "notify::has-selection", G_CALLBACK (ev_window_has_selection_changed_cb), @@ -6169,7 +6198,7 @@ ev_window_init (EvWindow *ev_window) setup_view_from_metadata (ev_window); setup_sidebar_from_metadata (ev_window); - ev_window_sizing_mode_changed_cb (EV_VIEW (ev_window->priv->view), NULL, ev_window); + ev_window_sizing_mode_changed_cb (ev_window->priv->model, NULL, ev_window); ev_window_setup_action_sensitivity (ev_window); /* Drag and Drop */ diff --git a/shell/ev-window.h b/shell/ev-window.h index 1df15ec9..c95c1a44 100644 --- a/shell/ev-window.h +++ b/shell/ev-window.h @@ -27,7 +27,6 @@ #include #include "ev-link.h" -#include "ev-page-cache.h" G_BEGIN_DECLS -- 2.43.5