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