diff options
Diffstat (limited to 'libview/ev-document-model.c')
-rw-r--r-- | libview/ev-document-model.c | 571 |
1 files changed, 571 insertions, 0 deletions
diff --git a/libview/ev-document-model.c b/libview/ev-document-model.c new file mode 100644 index 00000000..a15ab5ca --- /dev/null +++ b/libview/ev-document-model.c @@ -0,0 +1,571 @@ +/* this file is part of evince, a mate 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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; + guint continuous : 1; + guint dual_page : 1; + guint fullscreen : 1; + guint inverted_colors : 1; + + 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_INVERTED_COLORS, + PROP_SCALE, + PROP_SIZING_MODE, + PROP_CONTINUOUS, + PROP_DUAL_PAGE, + PROP_FULLSCREEN +}; + +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_INVERTED_COLORS: + ev_document_model_set_inverted_colors (model, g_value_get_boolean (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; + case PROP_CONTINUOUS: + ev_document_model_set_continuous (model, g_value_get_boolean (value)); + break; + case PROP_DUAL_PAGE: + ev_document_model_set_dual_page (model, g_value_get_boolean (value)); + break; + case PROP_FULLSCREEN: + ev_document_model_set_fullscreen (model, g_value_get_boolean (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_INVERTED_COLORS: + g_value_set_boolean (value, model->inverted_colors); + 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; + case PROP_CONTINUOUS: + g_value_set_boolean (value, ev_document_model_get_continuous (model)); + break; + case PROP_DUAL_PAGE: + g_value_set_boolean (value, ev_document_model_get_dual_page (model)); + break; + case PROP_FULLSCREEN: + g_value_set_boolean (value, ev_document_model_get_fullscreen (model)); + 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_INVERTED_COLORS, + g_param_spec_boolean ("inverted-colors", + "Inverted Colors", + "Whether document is displayed with inverted colors", + FALSE, + 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)); + g_object_class_install_property (g_object_class, + PROP_CONTINUOUS, + g_param_spec_boolean ("continuous", + "Continuous", + "Whether document is displayed in continuous mode", + TRUE, + G_PARAM_READWRITE)); + g_object_class_install_property (g_object_class, + PROP_DUAL_PAGE, + g_param_spec_boolean ("dual-page", + "Dual Page", + "Whether document is displayed in dual page mode", + FALSE, + G_PARAM_READWRITE)); + g_object_class_install_property (g_object_class, + PROP_FULLSCREEN, + g_param_spec_boolean ("fullscreen", + "Fullscreen", + "Whether document is displayed in fullscreen mode", + FALSE, + 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->continuous = TRUE; + model->inverted_colors = FALSE; + 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; +} + +void +ev_document_model_set_inverted_colors (EvDocumentModel *model, + gboolean inverted_colors) +{ + g_return_if_fail (EV_IS_DOCUMENT_MODEL (model)); + + if (inverted_colors == model->inverted_colors) + return; + + model->inverted_colors = inverted_colors; + + g_object_notify (G_OBJECT (model), "inverted-colors"); +} + +gboolean +ev_document_model_get_inverted_colors (EvDocumentModel *model) +{ + g_return_val_if_fail (EV_IS_DOCUMENT_MODEL (model), FALSE); + + return model->inverted_colors; +} + +void +ev_document_model_set_continuous (EvDocumentModel *model, + gboolean continuous) +{ + g_return_if_fail (EV_IS_DOCUMENT_MODEL (model)); + + continuous = continuous != FALSE; + + if (continuous == model->continuous) + return; + + model->continuous = continuous; + + g_object_notify (G_OBJECT (model), "continuous"); +} + +gboolean +ev_document_model_get_continuous (EvDocumentModel *model) +{ + g_return_val_if_fail (EV_IS_DOCUMENT_MODEL (model), TRUE); + + return model->continuous; +} + +void +ev_document_model_set_dual_page (EvDocumentModel *model, + gboolean dual_page) +{ + g_return_if_fail (EV_IS_DOCUMENT_MODEL (model)); + + dual_page = dual_page != FALSE; + + if (dual_page == model->dual_page) + return; + + model->dual_page = dual_page; + + g_object_notify (G_OBJECT (model), "dual-page"); +} + +gboolean +ev_document_model_get_dual_page (EvDocumentModel *model) +{ + g_return_val_if_fail (EV_IS_DOCUMENT_MODEL (model), FALSE); + + return model->dual_page; +} + +void +ev_document_model_set_fullscreen (EvDocumentModel *model, + gboolean fullscreen) +{ + g_return_if_fail (EV_IS_DOCUMENT_MODEL (model)); + + fullscreen = fullscreen != FALSE; + + if (fullscreen == model->fullscreen) + return; + + model->fullscreen = fullscreen; + + g_object_notify (G_OBJECT (model), "fullscreen"); +} + +gboolean +ev_document_model_get_fullscreen (EvDocumentModel *model) +{ + g_return_val_if_fail (EV_IS_DOCUMENT_MODEL (model), FALSE); + + return model->fullscreen; +} |