summaryrefslogtreecommitdiff
path: root/libview/ev-document-model.c
diff options
context:
space:
mode:
Diffstat (limited to 'libview/ev-document-model.c')
-rw-r--r--libview/ev-document-model.c571
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;
+}