summaryrefslogtreecommitdiff
path: root/libdocument
diff options
context:
space:
mode:
authorPerberos <[email protected]>2011-11-09 18:17:43 -0300
committerPerberos <[email protected]>2011-11-09 18:17:43 -0300
commitf6ce926719943751cf65cacde7fae050593eb2d6 (patch)
tree9224d1751678cf2d1fbd0431f128b711311c0287 /libdocument
downloadatril-f6ce926719943751cf65cacde7fae050593eb2d6.tar.bz2
atril-f6ce926719943751cf65cacde7fae050593eb2d6.tar.xz
inicial
Diffstat (limited to 'libdocument')
-rw-r--r--libdocument/Makefile.am193
-rw-r--r--libdocument/ev-annotation.c1002
-rw-r--r--libdocument/ev-annotation.h161
-rw-r--r--libdocument/ev-async-renderer.c65
-rw-r--r--libdocument/ev-async-renderer.h65
-rw-r--r--libdocument/ev-attachment.c439
-rw-r--r--libdocument/ev-attachment.h79
-rw-r--r--libdocument/ev-backends-manager.c333
-rw-r--r--libdocument/ev-backends-manager.h48
-rw-r--r--libdocument/ev-debug.c177
-rw-r--r--libdocument/ev-debug.h106
-rw-r--r--libdocument/ev-document-annotations.c75
-rw-r--r--libdocument/ev-document-annotations.h99
-rw-r--r--libdocument/ev-document-attachments.c49
-rw-r--r--libdocument/ev-document-attachments.h59
-rw-r--r--libdocument/ev-document-factory.c397
-rw-r--r--libdocument/ev-document-factory.h39
-rw-r--r--libdocument/ev-document-find.c42
-rw-r--r--libdocument/ev-document-find.h65
-rw-r--r--libdocument/ev-document-fonts.c59
-rw-r--r--libdocument/ev-document-fonts.h78
-rw-r--r--libdocument/ev-document-forms.c161
-rw-r--r--libdocument/ev-document-forms.h128
-rw-r--r--libdocument/ev-document-images.c47
-rw-r--r--libdocument/ev-document-images.h65
-rw-r--r--libdocument/ev-document-info.h154
-rw-r--r--libdocument/ev-document-layers.c74
-rw-r--r--libdocument/ev-document-layers.h85
-rw-r--r--libdocument/ev-document-links.c129
-rw-r--r--libdocument/ev-document-links.h87
-rw-r--r--libdocument/ev-document-misc.c400
-rw-r--r--libdocument/ev-document-misc.h67
-rw-r--r--libdocument/ev-document-print.c41
-rw-r--r--libdocument/ev-document-print.h59
-rw-r--r--libdocument/ev-document-security.c48
-rw-r--r--libdocument/ev-document-security.h67
-rw-r--r--libdocument/ev-document-text.c70
-rw-r--r--libdocument/ev-document-text.h75
-rw-r--r--libdocument/ev-document-thumbnails.c63
-rw-r--r--libdocument/ev-document-thumbnails.h69
-rw-r--r--libdocument/ev-document-transition.c57
-rw-r--r--libdocument/ev-document-transition.h64
-rw-r--r--libdocument/ev-document-type-builtins.c.template44
-rw-r--r--libdocument/ev-document-type-builtins.h.template29
-rw-r--r--libdocument/ev-document.c867
-rw-r--r--libdocument/ev-document.h303
-rw-r--r--libdocument/ev-file-exporter.c84
-rw-r--r--libdocument/ev-file-exporter.h101
-rw-r--r--libdocument/ev-file-helpers.c683
-rw-r--r--libdocument/ev-file-helpers.h71
-rw-r--r--libdocument/ev-form-field.c209
-rw-r--r--libdocument/ev-form-field.h214
-rw-r--r--libdocument/ev-image.c181
-rw-r--r--libdocument/ev-image.h68
-rw-r--r--libdocument/ev-init.c154
-rw-r--r--libdocument/ev-init.h41
-rw-r--r--libdocument/ev-layer.c86
-rw-r--r--libdocument/ev-layer.h62
-rw-r--r--libdocument/ev-link-action.c341
-rw-r--r--libdocument/ev-link-action.h73
-rw-r--r--libdocument/ev-link-dest.c511
-rw-r--r--libdocument/ev-link-dest.h95
-rw-r--r--libdocument/ev-link.c202
-rw-r--r--libdocument/ev-link.h55
-rw-r--r--libdocument/ev-mapping-list.c146
-rw-r--r--libdocument/ev-mapping-list.h53
-rw-r--r--libdocument/ev-module.c196
-rw-r--r--libdocument/ev-module.h74
-rw-r--r--libdocument/ev-page.c62
-rw-r--r--libdocument/ev-page.h63
-rw-r--r--libdocument/ev-render-context.c101
-rw-r--r--libdocument/ev-render-context.h70
-rw-r--r--libdocument/ev-selection.c77
-rw-r--r--libdocument/ev-selection.h93
-rw-r--r--libdocument/ev-transition-effect.c224
-rw-r--r--libdocument/ev-transition-effect.h87
-rw-r--r--libdocument/ev-version.h.in69
77 files changed, 11429 insertions, 0 deletions
diff --git a/libdocument/Makefile.am b/libdocument/Makefile.am
new file mode 100644
index 00000000..90fd1127
--- /dev/null
+++ b/libdocument/Makefile.am
@@ -0,0 +1,193 @@
+lib_LTLIBRARIES = libevdocument.la
+
+NOINST_H_FILES = \
+ ev-debug.h \
+ ev-module.h
+
+INST_H_SRC_FILES = \
+ ev-annotation.h \
+ ev-async-renderer.h \
+ ev-attachment.h \
+ ev-backends-manager.h \
+ ev-document-factory.h \
+ ev-document-annotations.h \
+ ev-document-attachments.h \
+ ev-document-find.h \
+ ev-document-fonts.h \
+ ev-document-forms.h \
+ ev-document.h \
+ ev-document-images.h \
+ ev-document-info.h \
+ ev-document-layers.h \
+ ev-document-links.h \
+ ev-document-misc.h \
+ ev-document-print.h \
+ ev-document-security.h \
+ ev-document-thumbnails.h \
+ ev-document-transition.h \
+ ev-document-text.h \
+ ev-file-exporter.h \
+ ev-file-helpers.h \
+ ev-form-field.h \
+ ev-image.h \
+ ev-init.h \
+ ev-layer.h \
+ ev-link-action.h \
+ ev-link-dest.h \
+ ev-link.h \
+ ev-mapping-list.h \
+ ev-page.h \
+ ev-render-context.h \
+ ev-selection.h \
+ ev-transition-effect.h \
+ ev-version.h
+
+INST_H_FILES = \
+ $(INST_H_SRC_FILES) \
+ ev-document-type-builtins.h
+
+headerdir = $(includedir)/evince/$(EV_API_VERSION)/libdocument
+header_DATA = $(INST_H_FILES)
+
+libevdocument_la_SOURCES= \
+ ev-annotation.c \
+ ev-async-renderer.c \
+ ev-attachment.c \
+ ev-backends-manager.c \
+ ev-layer.c \
+ ev-link.c \
+ ev-link-action.c \
+ ev-link-dest.c \
+ ev-image.c \
+ ev-init.c \
+ ev-document.c \
+ ev-document-annotations.c \
+ ev-document-attachments.c \
+ ev-document-factory.c \
+ ev-document-thumbnails.c \
+ ev-document-fonts.c \
+ ev-document-layers.c \
+ ev-document-links.c \
+ ev-document-images.c \
+ ev-document-print.c \
+ ev-document-security.c \
+ ev-document-find.c \
+ ev-document-transition.c \
+ ev-document-forms.c \
+ ev-document-type-builtins.c \
+ ev-document-text.c \
+ ev-form-field.c \
+ ev-debug.c \
+ ev-file-exporter.c \
+ ev-file-helpers.c \
+ ev-mapping-list.c \
+ ev-module.c \
+ ev-page.c \
+ ev-render-context.c \
+ ev-selection.c \
+ ev-transition-effect.c \
+ ev-document-misc.c \
+ $(NOINST_H_FILES) \
+ $(INST_H_FILES)
+
+libevdocument_la_CPPFLAGS = \
+ -DG_LOG_DOMAIN=\"EvinceDocument\" \
+ -DEVINCE_UIDIR=\"$(pkgdatadir)\" \
+ -DMATELOCALEDIR=\"$(datadir)/locale\" \
+ -DEV_BACKENDSDIR=\"$(backenddir)\" \
+ -DEV_BACKENDSBINARYVERSION=\"$(backend_binary_version)\" \
+ -DEVINCE_COMPILATION \
+ $(AM_CPPFLAGS)
+
+libevdocument_la_CFLAGS = \
+ $(LIBDOCUMENT_CFLAGS) \
+ -I$(top_srcdir)/cut-n-paste/synctex \
+ $(WARN_CFLAGS) \
+ $(DISABLE_DEPRECATED) \
+ $(AM_CFLAGS)
+
+libevdocument_la_LDFLAGS = \
+ -version-info $(EV_DOCUMENT_LT_VERSION_INFO) \
+ -no-undefined \
+ -export-symbols-regex "^ev_*" \
+ $(AM_LDFLAGS)
+
+libevdocument_la_LIBADD = \
+ $(LIBDOCUMENT_LIBS) \
+ $(top_builddir)/cut-n-paste/synctex/libsynctex.la
+
+
+BUILT_SOURCES = \
+ ev-document-type-builtins.c \
+ ev-document-type-builtins.h
+
+CLEANFILES = \
+ $(BUILT_SOURCES) \
+ stamp-ev-document-type-builtins.h \
+ stamp-ev-document-type-builtins.c
+
+ev-document-type-builtins.h: stamp-ev-document-type-builtins.h
+ @true
+stamp-ev-document-type-builtins.h: ev-document-type-builtins.h.template $(INST_H_SRC_FILES)
+ $(AM_V_GEN)$(GLIB_MKENUMS) --template $< $(filter-out $<,$^) > xgen-etbh \
+ && (cmp -s xgen-etbh ev-document-type-builtins.h || cp xgen-etbh ev-document-type-builtins.h ) \
+ && rm -f xgen-etbh \
+ && echo timestamp > $(@F)
+
+ev-document-type-builtins.c: stamp-ev-document-type-builtins.c
+ @true
+stamp-ev-document-type-builtins.c: ev-document-type-builtins.c.template $(INST_H_SRC_FILES)
+ $(AM_V_GEN)$(GLIB_MKENUMS) --template $< $(filter-out $<,$^) > xgen-etbc \
+ && (cmp -s xgen-etbc ev-document-type-builtins.c || cp xgen-etbc ev-document-type-builtins.c ) \
+ && rm -f xgen-etbc \
+ && echo timestamp > $(@F)
+
+EXTRA_DIST = \
+ ev-document-type-builtins.c.template \
+ ev-document-type-builtins.h.template
+
+# GObject Introspection
+
+if ENABLE_INTROSPECTION
+
+EvinceDocument-$(EV_API_VERSION).gir: libevdocument.la Makefile $(INST_H_FILES) $(filter %.c,$(libevdocument_la_SOURCES))
+ $(AM_V_GEN) PKG_CONFIG_PATH=$(top_builddir):$$PKG_CONFIG_PATH \
+ $(G_IR_SCANNER) -v --namespace EvinceDocument \
+ --strip-prefix=Ev \
+ --nsversion=$(EV_API_VERSION) \
+ --include=GLib-2.0 \
+ --include=Gio-2.0 \
+ --include=Gdk-2.0 \
+ --include=GdkPixbuf-2.0 \
+ --include=Gtk-2.0 \
+ --library=evdocument \
+ --libtool="$(SAVED_LIBTOOL)" \
+ --output $@ \
+ --pkg evince-document-$(EV_API_VERSION) \
+ -I$(top_srcdir) \
+ -I$(top_builddir) \
+ -I$(srcdir) \
+ -I$(builddir) \
+ -DEVINCE_COMPILATION \
+ $(filter %.h,$^) \
+ $(filter %.c,$^)
+
+girdir = $(GIRDIR)
+gir_DATA = EvinceDocument-$(EV_API_VERSION).gir
+
+typelibsdir = $(GIRTYPELIBDIR)
+typelibs_DATA = EvinceDocument-$(EV_API_VERSION).typelib
+
+EXTRA_DIST += $(gir_DATA)
+CLEANFILES += $(gir_DATA) $(typelibs_DATA)
+
+%.typelib: %.gir
+ $(AM_V_GEN) LD_LIBRARY_PATH=$${LD_LIBRARY_PATH:+$$LD_LIBRARY_PATH:}. $(G_IR_COMPILER) \
+ --includedir=$(srcdir) \
+ --includedir=. \
+ $(G_IR_COMPILER_OPTS) \
+ $< -o $@
+
+endif # ENABLE_INTROSPECTION
+
+-include $(top_srcdir)/git.mk
diff --git a/libdocument/ev-annotation.c b/libdocument/ev-annotation.c
new file mode 100644
index 00000000..2d45c4a2
--- /dev/null
+++ b/libdocument/ev-annotation.c
@@ -0,0 +1,1002 @@
+/* ev-annotation.c
+ * this file is part of evince, a mate document viewer
+ *
+ * Copyright (C) 2009 Carlos Garcia Campos <[email protected]>
+ * Copyright (C) 2007 Iñigo Martinez <[email protected]>
+ *
+ * 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-annotation.h"
+#include "ev-document-misc.h"
+#include "ev-document-type-builtins.h"
+
+struct _EvAnnotation {
+ GObject parent;
+
+ EvAnnotationType type;
+ EvPage *page;
+
+ gchar *contents;
+ gchar *name;
+ gchar *modified;
+ GdkColor color;
+
+};
+
+struct _EvAnnotationClass {
+ GObjectClass parent_class;
+};
+
+struct _EvAnnotationMarkupInterface {
+ GTypeInterface base_iface;
+};
+
+struct _EvAnnotationText {
+ EvAnnotation parent;
+
+ gboolean is_open : 1;
+ EvAnnotationTextIcon icon;
+};
+
+struct _EvAnnotationTextClass {
+ EvAnnotationClass parent_class;
+};
+
+struct _EvAnnotationAttachment {
+ EvAnnotation parent;
+
+ EvAttachment *attachment;
+};
+
+struct _EvAnnotationAttachmentClass {
+ EvAnnotationClass parent_class;
+};
+
+static void ev_annotation_markup_default_init (EvAnnotationMarkupInterface *iface);
+static void ev_annotation_text_markup_iface_init (EvAnnotationMarkupInterface *iface);
+static void ev_annotation_attachment_markup_iface_init (EvAnnotationMarkupInterface *iface);
+
+/* EvAnnotation */
+enum {
+ PROP_ANNOT_0,
+ PROP_ANNOT_PAGE,
+ PROP_ANNOT_CONTENTS,
+ PROP_ANNOT_NAME,
+ PROP_ANNOT_MODIFIED,
+ PROP_ANNOT_COLOR
+};
+
+/* EvAnnotationMarkup */
+enum {
+ PROP_MARKUP_0,
+ PROP_MARKUP_LABEL,
+ PROP_MARKUP_OPACITY,
+ PROP_MARKUP_HAS_POPUP,
+ PROP_MARKUP_RECTANGLE,
+ PROP_MARKUP_POPUP_IS_OPEN
+};
+
+/* EvAnnotationText */
+enum {
+ PROP_TEXT_ICON = PROP_MARKUP_POPUP_IS_OPEN + 1,
+ PROP_TEXT_IS_OPEN
+};
+
+/* EvAnnotationAttachment */
+enum {
+ PROP_ATTACHMENT_ATTACHMENT = PROP_MARKUP_POPUP_IS_OPEN + 1
+};
+
+G_DEFINE_ABSTRACT_TYPE (EvAnnotation, ev_annotation, G_TYPE_OBJECT)
+G_DEFINE_INTERFACE (EvAnnotationMarkup, ev_annotation_markup, EV_TYPE_ANNOTATION)
+G_DEFINE_TYPE_WITH_CODE (EvAnnotationText, ev_annotation_text, EV_TYPE_ANNOTATION,
+ {
+ G_IMPLEMENT_INTERFACE (EV_TYPE_ANNOTATION_MARKUP,
+ ev_annotation_text_markup_iface_init);
+ });
+G_DEFINE_TYPE_WITH_CODE (EvAnnotationAttachment, ev_annotation_attachment, EV_TYPE_ANNOTATION,
+ {
+ G_IMPLEMENT_INTERFACE (EV_TYPE_ANNOTATION_MARKUP,
+ ev_annotation_attachment_markup_iface_init);
+ });
+
+/* EvAnnotation */
+static void
+ev_annotation_finalize (GObject *object)
+{
+ EvAnnotation *annot = EV_ANNOTATION (object);
+
+ if (annot->page) {
+ g_object_unref (annot->page);
+ annot->page = NULL;
+ }
+
+ if (annot->contents) {
+ g_free (annot->contents);
+ annot->contents = NULL;
+ }
+
+ if (annot->name) {
+ g_free (annot->name);
+ annot->name = NULL;
+ }
+
+ if (annot->modified) {
+ g_free (annot->modified);
+ annot->modified = NULL;
+ }
+
+ G_OBJECT_CLASS (ev_annotation_parent_class)->finalize (object);
+}
+
+static void
+ev_annotation_init (EvAnnotation *annot)
+{
+ annot->type = EV_ANNOTATION_TYPE_UNKNOWN;
+}
+
+static void
+ev_annotation_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ EvAnnotation *annot = EV_ANNOTATION (object);
+
+ switch (prop_id) {
+ case PROP_ANNOT_PAGE:
+ annot->page = g_value_dup_object (value);
+ break;
+ case PROP_ANNOT_CONTENTS:
+ ev_annotation_set_contents (annot, g_value_get_string (value));
+ break;
+ case PROP_ANNOT_NAME:
+ ev_annotation_set_name (annot, g_value_get_string (value));
+ break;
+ case PROP_ANNOT_MODIFIED:
+ ev_annotation_set_modified (annot, g_value_get_string (value));
+ break;
+ case PROP_ANNOT_COLOR:
+ ev_annotation_set_color (annot, g_value_get_pointer (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+ev_annotation_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ EvAnnotation *annot = EV_ANNOTATION (object);
+
+ switch (prop_id) {
+ case PROP_ANNOT_CONTENTS:
+ g_value_set_string (value, ev_annotation_get_contents (annot));
+ break;
+ case PROP_ANNOT_NAME:
+ g_value_set_string (value, ev_annotation_get_name (annot));
+ break;
+ case PROP_ANNOT_MODIFIED:
+ g_value_set_string (value, ev_annotation_get_modified (annot));
+ break;
+ case PROP_ANNOT_COLOR:
+ g_value_set_pointer (value, &annot->color);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+ev_annotation_class_init (EvAnnotationClass *klass)
+{
+ GObjectClass *g_object_class = G_OBJECT_CLASS (klass);
+
+ g_object_class->finalize = ev_annotation_finalize;
+ g_object_class->set_property = ev_annotation_set_property;
+ g_object_class->get_property = ev_annotation_get_property;
+
+ g_object_class_install_property (g_object_class,
+ PROP_ANNOT_PAGE,
+ g_param_spec_object ("page",
+ "Page",
+ "The page wehere the annotation is",
+ EV_TYPE_PAGE,
+ G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
+ g_object_class_install_property (g_object_class,
+ PROP_ANNOT_CONTENTS,
+ g_param_spec_string ("contents",
+ "Contents",
+ "The annotation contents",
+ NULL,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (g_object_class,
+ PROP_ANNOT_NAME,
+ g_param_spec_string ("name",
+ "Name",
+ "The annotation unique name",
+ NULL,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (g_object_class,
+ PROP_ANNOT_MODIFIED,
+ g_param_spec_string ("modified",
+ "Modified",
+ "Last modified date as string",
+ NULL,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (g_object_class,
+ PROP_ANNOT_COLOR,
+ g_param_spec_pointer ("color",
+ "Color",
+ "The annotation color",
+ G_PARAM_READWRITE));
+}
+
+EvAnnotationType
+ev_annotation_get_annotation_type (EvAnnotation *annot)
+{
+ g_return_val_if_fail (EV_IS_ANNOTATION (annot), 0);
+
+ return annot->type;
+}
+
+EvPage *
+ev_annotation_get_page (EvAnnotation *annot)
+{
+ g_return_val_if_fail (EV_IS_ANNOTATION (annot), NULL);
+
+ return annot->page;
+}
+
+guint
+ev_annotation_get_page_index (EvAnnotation *annot)
+{
+ g_return_val_if_fail (EV_IS_ANNOTATION (annot), 0);
+
+ return annot->page->index;
+}
+
+gboolean
+ev_annotation_equal (EvAnnotation *annot,
+ EvAnnotation *other)
+{
+ g_return_val_if_fail (EV_IS_ANNOTATION (annot), FALSE);
+ g_return_val_if_fail (EV_IS_ANNOTATION (other), FALSE);
+
+ return (annot == other || g_strcmp0 (annot->name, other->name) == 0);
+}
+
+const gchar *
+ev_annotation_get_contents (EvAnnotation *annot)
+{
+ g_return_val_if_fail (EV_IS_ANNOTATION (annot), NULL);
+
+ return annot->contents;
+}
+
+gboolean
+ev_annotation_set_contents (EvAnnotation *annot,
+ const gchar *contents)
+{
+ g_return_val_if_fail (EV_IS_ANNOTATION (annot), FALSE);
+
+ if (g_strcmp0 (annot->contents, contents) == 0)
+ return FALSE;
+
+ if (annot->contents)
+ g_free (annot->contents);
+ annot->contents = contents ? g_strdup (contents) : NULL;
+
+ g_object_notify (G_OBJECT (annot), "contents");
+
+ return TRUE;
+}
+
+const gchar *
+ev_annotation_get_name (EvAnnotation *annot)
+{
+ g_return_val_if_fail (EV_IS_ANNOTATION (annot), NULL);
+
+ return annot->name;
+}
+
+gboolean
+ev_annotation_set_name (EvAnnotation *annot,
+ const gchar *name)
+{
+ g_return_val_if_fail (EV_IS_ANNOTATION (annot), FALSE);
+
+ if (g_strcmp0 (annot->name, name) == 0)
+ return FALSE;
+
+ if (annot->name)
+ g_free (annot->name);
+ annot->name = name ? g_strdup (name) : NULL;
+
+ g_object_notify (G_OBJECT (annot), "name");
+
+ return TRUE;
+}
+
+const gchar *
+ev_annotation_get_modified (EvAnnotation *annot)
+{
+ g_return_val_if_fail (EV_IS_ANNOTATION (annot), NULL);
+
+ return annot->modified;
+}
+
+gboolean
+ev_annotation_set_modified (EvAnnotation *annot,
+ const gchar *modified)
+{
+ g_return_val_if_fail (EV_IS_ANNOTATION (annot), FALSE);
+
+ if (g_strcmp0 (annot->modified, modified) == 0)
+ return FALSE;
+
+ if (annot->modified)
+ g_free (annot->modified);
+ annot->modified = modified ? g_strdup (modified) : NULL;
+
+ g_object_notify (G_OBJECT (annot), "modified");
+
+ return TRUE;
+}
+
+gboolean
+ev_annotation_set_modified_from_time (EvAnnotation *annot,
+ GTime utime)
+{
+ gchar *modified;
+
+ g_return_val_if_fail (EV_IS_ANNOTATION (annot), FALSE);
+
+ modified = ev_document_misc_format_date (utime);
+
+ if (g_strcmp0 (annot->modified, modified) == 0) {
+ g_free (modified);
+ return FALSE;
+ }
+
+ if (annot->modified)
+ g_free (annot->modified);
+ annot->modified = modified;
+
+ g_object_notify (G_OBJECT (annot), "modified");
+
+ return TRUE;
+}
+
+void
+ev_annotation_get_color (EvAnnotation *annot,
+ GdkColor *color)
+{
+ g_return_if_fail (EV_IS_ANNOTATION (annot));
+
+ if (color)
+ *color = annot->color;
+}
+
+gboolean
+ev_annotation_set_color (EvAnnotation *annot,
+ const GdkColor *color)
+{
+ g_return_val_if_fail (EV_IS_ANNOTATION (annot), FALSE);
+
+ if (annot->color.red == color->red &&
+ annot->color.green == color->green &&
+ annot->color.blue == color->blue)
+ return FALSE;
+
+ if (color)
+ annot->color = *color;
+
+ g_object_notify (G_OBJECT (annot), "color");
+
+ return TRUE;
+}
+
+/* EvAnnotationMarkup */
+typedef struct {
+ gchar *label;
+ gdouble opacity;
+ gboolean has_popup;
+ gboolean popup_is_open;
+ EvRectangle rectangle;
+} EvAnnotationMarkupProps;
+
+static void
+ev_annotation_markup_default_init (EvAnnotationMarkupInterface *iface)
+{
+ static gboolean initialized = FALSE;
+
+ if (!initialized) {
+ g_object_interface_install_property (iface,
+ g_param_spec_string ("label",
+ "Label",
+ "Label of the markup annotation",
+ NULL,
+ G_PARAM_READWRITE));
+ g_object_interface_install_property (iface,
+ g_param_spec_double ("opacity",
+ "Opacity",
+ "Opacity of the markup annotation",
+ 0,
+ G_MAXDOUBLE,
+ 1.,
+ G_PARAM_READWRITE));
+ g_object_interface_install_property (iface,
+ g_param_spec_boolean ("has_popup",
+ "Has popup",
+ "Whether the markup annotation has "
+ "a popup window associated",
+ TRUE,
+ G_PARAM_READWRITE));
+ g_object_interface_install_property (iface,
+ g_param_spec_boxed ("rectangle",
+ "Rectangle",
+ "The Rectangle of the popup associated "
+ "to the markup annotation",
+ EV_TYPE_RECTANGLE,
+ G_PARAM_READWRITE));
+ g_object_interface_install_property (iface,
+ g_param_spec_boolean ("popup_is_open",
+ "PopupIsOpen",
+ "Whether the popup associated to "
+ "the markup annotation is open",
+ FALSE,
+ G_PARAM_READWRITE));
+ initialized = TRUE;
+ }
+}
+
+static void
+ev_annotation_markup_props_free (EvAnnotationMarkupProps *props)
+{
+ g_free (props->label);
+ g_slice_free (EvAnnotationMarkupProps, props);
+}
+
+static EvAnnotationMarkupProps *
+ev_annotation_markup_get_properties (EvAnnotationMarkup *markup)
+{
+ EvAnnotationMarkupProps *props;
+ static GQuark props_key = 0;
+
+ if (!props_key)
+ props_key = g_quark_from_static_string ("ev-annotation-markup-props");
+
+ props = g_object_get_qdata (G_OBJECT (markup), props_key);
+ if (!props) {
+ props = g_slice_new0 (EvAnnotationMarkupProps);
+ g_object_set_qdata_full (G_OBJECT (markup),
+ props_key, props,
+ (GDestroyNotify) ev_annotation_markup_props_free);
+ }
+
+ return props;
+}
+
+static void
+ev_annotation_markup_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ EvAnnotationMarkup *markup = EV_ANNOTATION_MARKUP (object);
+
+ switch (prop_id) {
+ case PROP_MARKUP_LABEL:
+ ev_annotation_markup_set_label (markup, g_value_get_string (value));
+ break;
+ case PROP_MARKUP_OPACITY:
+ ev_annotation_markup_set_opacity (markup, g_value_get_double (value));
+ break;
+ case PROP_MARKUP_HAS_POPUP:
+ ev_annotation_markup_set_has_popup (markup, g_value_get_boolean (value));
+ break;
+ case PROP_MARKUP_RECTANGLE:
+ ev_annotation_markup_set_rectangle (markup, g_value_get_boxed (value));
+ break;
+ case PROP_MARKUP_POPUP_IS_OPEN:
+ ev_annotation_markup_set_popup_is_open (markup, g_value_get_boolean (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+ev_annotation_markup_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ EvAnnotationMarkupProps *props;
+
+ props = ev_annotation_markup_get_properties (EV_ANNOTATION_MARKUP (object));
+
+ switch (prop_id) {
+ case PROP_MARKUP_LABEL:
+ g_value_set_string (value, props->label);
+ break;
+ case PROP_MARKUP_OPACITY:
+ g_value_set_double (value, props->opacity);
+ break;
+ case PROP_MARKUP_HAS_POPUP:
+ g_value_set_boolean (value, props->has_popup);
+ break;
+ case PROP_MARKUP_RECTANGLE:
+ g_value_set_boxed (value, &props->rectangle);
+ break;
+ case PROP_MARKUP_POPUP_IS_OPEN:
+ g_value_set_boolean (value, props->popup_is_open);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+ev_annotation_markup_class_install_properties (GObjectClass *klass)
+{
+ klass->set_property = ev_annotation_markup_set_property;
+ klass->get_property = ev_annotation_markup_get_property;
+
+ g_object_class_override_property (klass, PROP_MARKUP_LABEL, "label");
+ g_object_class_override_property (klass, PROP_MARKUP_OPACITY, "opacity");
+ g_object_class_override_property (klass, PROP_MARKUP_HAS_POPUP, "has_popup");
+ g_object_class_override_property (klass, PROP_MARKUP_RECTANGLE, "rectangle");
+ g_object_class_override_property (klass, PROP_MARKUP_POPUP_IS_OPEN, "popup_is_open");
+}
+
+const gchar *
+ev_annotation_markup_get_label (EvAnnotationMarkup *markup)
+{
+ EvAnnotationMarkupProps *props;
+
+ g_return_val_if_fail (EV_IS_ANNOTATION_MARKUP (markup), NULL);
+
+ props = ev_annotation_markup_get_properties (markup);
+ return props->label;
+}
+
+gboolean
+ev_annotation_markup_set_label (EvAnnotationMarkup *markup,
+ const gchar *label)
+{
+ EvAnnotationMarkupProps *props;
+
+ g_return_val_if_fail (EV_IS_ANNOTATION_MARKUP (markup), FALSE);
+ g_return_val_if_fail (label != NULL, FALSE);
+
+ props = ev_annotation_markup_get_properties (markup);
+ if (g_strcmp0 (props->label, label) == 0)
+ return FALSE;
+
+ if (props->label)
+ g_free (props->label);
+ props->label = g_strdup (label);
+
+ g_object_notify (G_OBJECT (markup), "label");
+
+ return TRUE;
+}
+
+gdouble
+ev_annotation_markup_get_opacity (EvAnnotationMarkup *markup)
+{
+ EvAnnotationMarkupProps *props;
+
+ g_return_val_if_fail (EV_IS_ANNOTATION_MARKUP (markup), 1.0);
+
+ props = ev_annotation_markup_get_properties (markup);
+ return props->opacity;
+}
+
+gboolean
+ev_annotation_markup_set_opacity (EvAnnotationMarkup *markup,
+ gdouble opacity)
+{
+ EvAnnotationMarkupProps *props;
+
+ g_return_val_if_fail (EV_IS_ANNOTATION_MARKUP (markup), FALSE);
+
+ props = ev_annotation_markup_get_properties (markup);
+ if (props->opacity == opacity)
+ return FALSE;
+
+ props->opacity = opacity;
+
+ g_object_notify (G_OBJECT (markup), "opacity");
+
+ return TRUE;
+}
+
+gboolean
+ev_annotation_markup_has_popup (EvAnnotationMarkup *markup)
+{
+ EvAnnotationMarkupProps *props;
+
+ g_return_val_if_fail (EV_IS_ANNOTATION_MARKUP (markup), FALSE);
+
+ props = ev_annotation_markup_get_properties (markup);
+ return props->has_popup;
+}
+
+gboolean
+ev_annotation_markup_set_has_popup (EvAnnotationMarkup *markup,
+ gboolean has_popup)
+{
+ EvAnnotationMarkupProps *props;
+
+ g_return_val_if_fail (EV_IS_ANNOTATION_MARKUP (markup), FALSE);
+
+ props = ev_annotation_markup_get_properties (markup);
+ if (props->has_popup == has_popup)
+ return FALSE;
+
+ props->has_popup = has_popup;
+
+ g_object_notify (G_OBJECT (markup), "has-popup");
+
+ return TRUE;
+}
+
+void
+ev_annotation_markup_get_rectangle (EvAnnotationMarkup *markup,
+ EvRectangle *ev_rect)
+{
+ EvAnnotationMarkupProps *props;
+
+ g_return_if_fail (EV_IS_ANNOTATION_MARKUP (markup));
+ g_return_if_fail (ev_rect != NULL);
+
+ props = ev_annotation_markup_get_properties (markup);
+ *ev_rect = props->rectangle;
+}
+
+gboolean
+ev_annotation_markup_set_rectangle (EvAnnotationMarkup *markup,
+ const EvRectangle *ev_rect)
+{
+ EvAnnotationMarkupProps *props;
+
+ g_return_val_if_fail (EV_IS_ANNOTATION_MARKUP (markup), FALSE);
+ g_return_val_if_fail (ev_rect != NULL, FALSE);
+
+ props = ev_annotation_markup_get_properties (markup);
+ if (props->rectangle.x1 == ev_rect->x1 &&
+ props->rectangle.y1 == ev_rect->y1 &&
+ props->rectangle.x2 == ev_rect->x2 &&
+ props->rectangle.y2 == ev_rect->y2)
+ return FALSE;
+
+ props->rectangle = *ev_rect;
+
+ g_object_notify (G_OBJECT (markup), "rectangle");
+
+ return TRUE;
+}
+
+gboolean
+ev_annotation_markup_get_popup_is_open (EvAnnotationMarkup *markup)
+{
+ EvAnnotationMarkupProps *props;
+
+ g_return_val_if_fail (EV_IS_ANNOTATION_MARKUP (markup), FALSE);
+
+ props = ev_annotation_markup_get_properties (markup);
+ return props->popup_is_open;
+}
+
+gboolean
+ev_annotation_markup_set_popup_is_open (EvAnnotationMarkup *markup,
+ gboolean is_open)
+{
+ EvAnnotationMarkupProps *props;
+
+ g_return_val_if_fail (EV_IS_ANNOTATION_MARKUP (markup), FALSE);
+
+ props = ev_annotation_markup_get_properties (markup);
+ if (props->popup_is_open == is_open)
+ return FALSE;
+
+ props->popup_is_open = is_open;
+
+ g_object_notify (G_OBJECT (markup), "popup_is_open");
+
+ return TRUE;
+}
+
+/* EvAnnotationText */
+static void
+ev_annotation_text_init (EvAnnotationText *annot)
+{
+ EV_ANNOTATION (annot)->type = EV_ANNOTATION_TYPE_TEXT;
+}
+
+static void
+ev_annotation_text_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ EvAnnotationText *annot = EV_ANNOTATION_TEXT (object);
+
+ if (prop_id < PROP_ATTACHMENT_ATTACHMENT) {
+ ev_annotation_markup_set_property (object, prop_id, value, pspec);
+ return;
+ }
+
+ switch (prop_id) {
+ case PROP_TEXT_ICON:
+ ev_annotation_text_set_icon (annot, g_value_get_enum (value));
+ break;
+ case PROP_TEXT_IS_OPEN:
+ ev_annotation_text_set_is_open (annot, g_value_get_boolean (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+ev_annotation_text_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ EvAnnotationText *annot = EV_ANNOTATION_TEXT (object);
+
+ if (prop_id < PROP_ATTACHMENT_ATTACHMENT) {
+ ev_annotation_markup_get_property (object, prop_id, value, pspec);
+ return;
+ }
+
+ switch (prop_id) {
+ case PROP_TEXT_ICON:
+ g_value_set_enum (value, annot->icon);
+ break;
+ case PROP_TEXT_IS_OPEN:
+ g_value_set_boolean (value, annot->is_open);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+ev_annotation_text_class_init (EvAnnotationTextClass *klass)
+{
+ GObjectClass *g_object_class = G_OBJECT_CLASS (klass);
+
+ ev_annotation_markup_class_install_properties (g_object_class);
+
+ g_object_class->set_property = ev_annotation_text_set_property;
+ g_object_class->get_property = ev_annotation_text_get_property;
+
+ g_object_class_install_property (g_object_class,
+ PROP_TEXT_ICON,
+ g_param_spec_enum ("icon",
+ "Icon",
+ "The icon fo the text annotation",
+ EV_TYPE_ANNOTATION_TEXT_ICON,
+ EV_ANNOTATION_TEXT_ICON_NOTE,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (g_object_class,
+ PROP_TEXT_IS_OPEN,
+ g_param_spec_boolean ("is_open",
+ "IsOpen",
+ "Whether text annot is initially open",
+ FALSE,
+ G_PARAM_READWRITE));
+}
+
+static void
+ev_annotation_text_markup_iface_init (EvAnnotationMarkupInterface *iface)
+{
+}
+
+EvAnnotation *
+ev_annotation_text_new (EvPage *page)
+{
+ return EV_ANNOTATION (g_object_new (EV_TYPE_ANNOTATION_TEXT,
+ "page", page,
+ NULL));
+}
+
+EvAnnotationTextIcon
+ev_annotation_text_get_icon (EvAnnotationText *text)
+{
+ g_return_val_if_fail (EV_IS_ANNOTATION_TEXT (text), 0);
+
+ return text->icon;
+}
+
+gboolean
+ev_annotation_text_set_icon (EvAnnotationText *text,
+ EvAnnotationTextIcon icon)
+{
+ g_return_val_if_fail (EV_IS_ANNOTATION_TEXT (text), FALSE);
+
+ if (text->icon == icon)
+ return FALSE;
+
+ text->icon = icon;
+
+ g_object_notify (G_OBJECT (text), "icon");
+
+ return TRUE;
+}
+
+gboolean
+ev_annotation_text_get_is_open (EvAnnotationText *text)
+{
+ g_return_val_if_fail (EV_IS_ANNOTATION_TEXT (text), FALSE);
+
+ return text->is_open;
+}
+
+gboolean
+ev_annotation_text_set_is_open (EvAnnotationText *text,
+ gboolean is_open)
+{
+ g_return_val_if_fail (EV_IS_ANNOTATION_TEXT (text), FALSE);
+
+ if (text->is_open == is_open)
+ return FALSE;
+
+ text->is_open = is_open;
+
+ g_object_notify (G_OBJECT (text), "is_open");
+
+ return TRUE;
+}
+
+/* EvAnnotationAttachment */
+static void
+ev_annotation_attachment_finalize (GObject *object)
+{
+ EvAnnotationAttachment *annot = EV_ANNOTATION_ATTACHMENT (object);
+
+ if (annot->attachment) {
+ g_object_unref (annot->attachment);
+ annot->attachment = NULL;
+ }
+
+ G_OBJECT_CLASS (ev_annotation_attachment_parent_class)->finalize (object);
+}
+
+static void
+ev_annotation_attachment_init (EvAnnotationAttachment *annot)
+{
+ EV_ANNOTATION (annot)->type = EV_ANNOTATION_TYPE_ATTACHMENT;
+}
+
+static void
+ev_annotation_attachment_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ EvAnnotationAttachment *annot = EV_ANNOTATION_ATTACHMENT (object);
+
+ if (prop_id < PROP_ATTACHMENT_ATTACHMENT) {
+ ev_annotation_markup_set_property (object, prop_id, value, pspec);
+ return;
+ }
+
+ switch (prop_id) {
+ case PROP_ATTACHMENT_ATTACHMENT:
+ ev_annotation_attachment_set_attachment (annot, g_value_get_object (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+ev_annotation_attachment_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ EvAnnotationAttachment *annot = EV_ANNOTATION_ATTACHMENT (object);
+
+ if (prop_id < PROP_ATTACHMENT_ATTACHMENT) {
+ ev_annotation_markup_get_property (object, prop_id, value, pspec);
+ return;
+ }
+
+ switch (prop_id) {
+ case PROP_ATTACHMENT_ATTACHMENT:
+ g_value_set_object (value, annot->attachment);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+ev_annotation_attachment_class_init (EvAnnotationAttachmentClass *klass)
+{
+ GObjectClass *g_object_class = G_OBJECT_CLASS (klass);
+
+ ev_annotation_markup_class_install_properties (g_object_class);
+
+ g_object_class->set_property = ev_annotation_attachment_set_property;
+ g_object_class->get_property = ev_annotation_attachment_get_property;
+ g_object_class->finalize = ev_annotation_attachment_finalize;
+
+ g_object_class_install_property (g_object_class,
+ PROP_ATTACHMENT_ATTACHMENT,
+ g_param_spec_object ("attachment",
+ "Attachment",
+ "The attachment of the annotation",
+ EV_TYPE_ATTACHMENT,
+ G_PARAM_CONSTRUCT |
+ G_PARAM_READWRITE));
+}
+
+static void
+ev_annotation_attachment_markup_iface_init (EvAnnotationMarkupInterface *iface)
+{
+}
+
+EvAnnotation *
+ev_annotation_attachment_new (EvPage *page,
+ EvAttachment *attachment)
+{
+ g_return_val_if_fail (EV_IS_ATTACHMENT (attachment), NULL);
+
+ return EV_ANNOTATION (g_object_new (EV_TYPE_ANNOTATION_ATTACHMENT,
+ "page", page,
+ "attachment", attachment,
+ NULL));
+}
+
+EvAttachment *
+ev_annotation_attachment_get_attachment (EvAnnotationAttachment *annot)
+{
+ g_return_val_if_fail (EV_IS_ANNOTATION_ATTACHMENT (annot), NULL);
+
+ return annot->attachment;
+}
+
+gboolean
+ev_annotation_attachment_set_attachment (EvAnnotationAttachment *annot,
+ EvAttachment *attachment)
+{
+ g_return_val_if_fail (EV_IS_ANNOTATION_ATTACHMENT (annot), FALSE);
+
+ if (annot->attachment == attachment)
+ return FALSE;
+
+ if (annot->attachment)
+ g_object_unref (annot->attachment);
+ annot->attachment = attachment ? g_object_ref (attachment) : NULL;
+
+ g_object_notify (G_OBJECT (annot), "attachment");
+
+ return TRUE;
+}
diff --git a/libdocument/ev-annotation.h b/libdocument/ev-annotation.h
new file mode 100644
index 00000000..1d5fca3f
--- /dev/null
+++ b/libdocument/ev-annotation.h
@@ -0,0 +1,161 @@
+/* ev-annotation.h
+ * this file is part of evince, a mate document viewer
+ *
+ * Copyright (C) 2009 Carlos Garcia Campos <[email protected]>
+ * Copyright (C) 2007 Iñigo Martinez <[email protected]>
+ *
+ * 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.
+ */
+
+#if !defined (__EV_EVINCE_DOCUMENT_H_INSIDE__) && !defined (EVINCE_COMPILATION)
+#error "Only <evince-document.h> can be included directly."
+#endif
+
+#ifndef EV_ANNOTATION_H
+#define EV_ANNOTATION_H
+
+#include <glib-object.h>
+
+#include "ev-document.h"
+#include "ev-attachment.h"
+
+G_BEGIN_DECLS
+
+/* EvAnnotation */
+#define EV_TYPE_ANNOTATION (ev_annotation_get_type())
+#define EV_ANNOTATION(object) (G_TYPE_CHECK_INSTANCE_CAST((object), EV_TYPE_ANNOTATION, EvAnnotation))
+#define EV_ANNOTATION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), EV_TYPE_ANNOTATION, EvAnnotationClass))
+#define EV_IS_ANNOTATION(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), EV_TYPE_ANNOTATION))
+#define EV_IS_ANNOTATION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), EV_TYPE_ANNOTATION))
+#define EV_ANNOTATION_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS((object), EV_TYPE_ANNOTATION, EvAnnotationClass))
+
+/* EvAnnotationMarkup */
+#define EV_TYPE_ANNOTATION_MARKUP (ev_annotation_markup_get_type ())
+#define EV_ANNOTATION_MARKUP(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EV_TYPE_ANNOTATION_MARKUP, EvAnnotationMarkup))
+#define EV_ANNOTATION_MARKUP_IFACE(k) (G_TYPE_CHECK_CLASS_CAST((k), EV_TYPE_ANNOTATION_MARKUP, EvAnnotationMarkupInterface))
+#define EV_IS_ANNOTATION_MARKUP(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EV_TYPE_ANNOTATION_MARKUP))
+#define EV_IS_ANNOTATION_MARKUP_IFACE(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EV_TYPE_ANNOTATION_MARKUP))
+#define EV_ANNOTATION_MARKUP_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), EV_TYPE_ANNOTATION_MARKUP, EvAnnotationMarkupInterface))
+
+/* EvAnnotationText */
+#define EV_TYPE_ANNOTATION_TEXT (ev_annotation_text_get_type())
+#define EV_ANNOTATION_TEXT(object) (G_TYPE_CHECK_INSTANCE_CAST((object), EV_TYPE_ANNOTATION_TEXT, EvAnnotationText))
+#define EV_ANNOTATION_TEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), EV_TYPE_ANNOTATION_TEXT, EvAnnotationTextClass))
+#define EV_IS_ANNOTATION_TEXT(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), EV_TYPE_ANNOTATION_TEXT))
+#define EV_IS_ANNOTATION_TEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), EV_TYPE_ANNOTATION_TEXT))
+#define EV_ANNOTATION_TEXT_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS((object), EV_TYPE_ANNOTATION_TEXT, EvAnnotationTextClass))
+
+/* EvAnnotationText */
+#define EV_TYPE_ANNOTATION_ATTACHMENT (ev_annotation_attachment_get_type())
+#define EV_ANNOTATION_ATTACHMENT(object) (G_TYPE_CHECK_INSTANCE_CAST((object), EV_TYPE_ANNOTATION_ATTACHMENT, EvAnnotationAttachment))
+#define EV_ANNOTATION_ATTACHMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), EV_TYPE_ANNOTATION_ATTACHMENT, EvAnnotationAttachmentClass))
+#define EV_IS_ANNOTATION_ATTACHMENT(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), EV_TYPE_ANNOTATION_ATTACHMENT))
+#define EV_IS_ANNOTATION_ATTACHMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), EV_TYPE_ANNOTATION_ATTACHMENT))
+#define EV_ANNOTATION_ATTACHMENT_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS((object), EV_TYPE_ANNOTATION_ATTACHMENT, EvAnnotationAttachmentClass))
+
+typedef struct _EvAnnotation EvAnnotation;
+typedef struct _EvAnnotationClass EvAnnotationClass;
+
+typedef struct _EvAnnotationMarkup EvAnnotationMarkup;
+typedef struct _EvAnnotationMarkupInterface EvAnnotationMarkupInterface;
+
+typedef struct _EvAnnotationText EvAnnotationText;
+typedef struct _EvAnnotationTextClass EvAnnotationTextClass;
+
+typedef struct _EvAnnotationAttachment EvAnnotationAttachment;
+typedef struct _EvAnnotationAttachmentClass EvAnnotationAttachmentClass;
+
+typedef enum {
+ EV_ANNOTATION_TYPE_UNKNOWN,
+ EV_ANNOTATION_TYPE_TEXT,
+ EV_ANNOTATION_TYPE_ATTACHMENT
+} EvAnnotationType;
+
+typedef enum {
+ EV_ANNOTATION_TEXT_ICON_NOTE,
+ EV_ANNOTATION_TEXT_ICON_COMMENT,
+ EV_ANNOTATION_TEXT_ICON_KEY,
+ EV_ANNOTATION_TEXT_ICON_HELP,
+ EV_ANNOTATION_TEXT_ICON_NEW_PARAGRAPH,
+ EV_ANNOTATION_TEXT_ICON_PARAGRAPH,
+ EV_ANNOTATION_TEXT_ICON_INSERT,
+ EV_ANNOTATION_TEXT_ICON_CROSS,
+ EV_ANNOTATION_TEXT_ICON_CIRCLE,
+ EV_ANNOTATION_TEXT_ICON_UNKNOWN
+} EvAnnotationTextIcon;
+
+/* EvAnnotation */
+GType ev_annotation_get_type (void) G_GNUC_CONST;
+EvAnnotationType ev_annotation_get_annotation_type (EvAnnotation *annot);
+EvPage *ev_annotation_get_page (EvAnnotation *annot);
+guint ev_annotation_get_page_index (EvAnnotation *annot);
+gboolean ev_annotation_equal (EvAnnotation *annot,
+ EvAnnotation *other);
+const gchar *ev_annotation_get_contents (EvAnnotation *annot);
+gboolean ev_annotation_set_contents (EvAnnotation *annot,
+ const gchar *contents);
+const gchar *ev_annotation_get_name (EvAnnotation *annot);
+gboolean ev_annotation_set_name (EvAnnotation *annot,
+ const gchar *name);
+const gchar *ev_annotation_get_modified (EvAnnotation *annot);
+gboolean ev_annotation_set_modified (EvAnnotation *annot,
+ const gchar *modified);
+gboolean ev_annotation_set_modified_from_time (EvAnnotation *annot,
+ GTime utime);
+void ev_annotation_get_color (EvAnnotation *annot,
+ GdkColor *color);
+gboolean ev_annotation_set_color (EvAnnotation *annot,
+ const GdkColor *color);
+
+/* EvAnnotationMarkup */
+GType ev_annotation_markup_get_type (void) G_GNUC_CONST;
+const gchar *ev_annotation_markup_get_label (EvAnnotationMarkup *markup);
+gboolean ev_annotation_markup_set_label (EvAnnotationMarkup *markup,
+ const gchar *label);
+gdouble ev_annotation_markup_get_opacity (EvAnnotationMarkup *markup);
+gboolean ev_annotation_markup_set_opacity (EvAnnotationMarkup *markup,
+ gdouble opacity);
+gboolean ev_annotation_markup_has_popup (EvAnnotationMarkup *markup);
+gboolean ev_annotation_markup_set_has_popup (EvAnnotationMarkup *markup,
+ gboolean has_popup);
+void ev_annotation_markup_get_rectangle (EvAnnotationMarkup *markup,
+ EvRectangle *ev_rect);
+gboolean ev_annotation_markup_set_rectangle (EvAnnotationMarkup *markup,
+ const EvRectangle *ev_rect);
+gboolean ev_annotation_markup_get_popup_is_open (EvAnnotationMarkup *markup);
+gboolean ev_annotation_markup_set_popup_is_open (EvAnnotationMarkup *markup,
+ gboolean is_open);
+
+/* EvAnnotationText */
+GType ev_annotation_text_get_type (void) G_GNUC_CONST;
+EvAnnotation *ev_annotation_text_new (EvPage *page);
+EvAnnotationTextIcon ev_annotation_text_get_icon (EvAnnotationText *text);
+gboolean ev_annotation_text_set_icon (EvAnnotationText *text,
+ EvAnnotationTextIcon icon);
+gboolean ev_annotation_text_get_is_open (EvAnnotationText *text);
+gboolean ev_annotation_text_set_is_open (EvAnnotationText *text,
+ gboolean is_open);
+
+/* EvAnnotationAttachment */
+GType ev_annotation_attachment_get_type (void) G_GNUC_CONST;
+EvAnnotation *ev_annotation_attachment_new (EvPage *page,
+ EvAttachment *attachment);
+EvAttachment *ev_annotation_attachment_get_attachment (EvAnnotationAttachment *annot);
+gboolean ev_annotation_attachment_set_attachment (EvAnnotationAttachment *annot,
+ EvAttachment *attachment);
+
+G_END_DECLS
+
+#endif /* EV_ANNOTATION_H */
diff --git a/libdocument/ev-async-renderer.c b/libdocument/ev-async-renderer.c
new file mode 100644
index 00000000..3b8d7b73
--- /dev/null
+++ b/libdocument/ev-async-renderer.c
@@ -0,0 +1,65 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; c-indent-level: 8 -*- */
+/*
+ * Copyright (C) 2004 Marco Pesenti Gritti
+ *
+ * This program 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, or (at your option)
+ * any later version.
+ *
+ * This program 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-async-renderer.h"
+#include "ev-document.h"
+
+enum
+{
+ RENDER_FINISHED,
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+G_DEFINE_INTERFACE (EvAsyncRenderer, ev_async_renderer, 0)
+
+static void
+ev_async_renderer_default_init (EvAsyncRendererInterface *klass)
+{
+ static gboolean initialized = FALSE;
+
+ if (!initialized) {
+ signals[RENDER_FINISHED] =
+ g_signal_new ("render_finished",
+ EV_TYPE_ASYNC_RENDERER,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (EvAsyncRendererInterface, render_finished),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__OBJECT,
+ G_TYPE_NONE,
+ 1,
+ GDK_TYPE_PIXBUF);
+ initialized = TRUE;
+ }
+}
+
+void
+ev_async_renderer_render_pixbuf (EvAsyncRenderer *async_renderer,
+ int page,
+ double scale,
+ int rotation)
+{
+ EvAsyncRendererInterface *iface = EV_ASYNC_RENDERER_GET_IFACE (async_renderer);
+
+ iface->render_pixbuf (async_renderer, page, scale, rotation);
+}
diff --git a/libdocument/ev-async-renderer.h b/libdocument/ev-async-renderer.h
new file mode 100644
index 00000000..4ce3caa7
--- /dev/null
+++ b/libdocument/ev-async-renderer.h
@@ -0,0 +1,65 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; c-indent-level: 8 -*- */
+/*
+ * Copyright (C) 2000-2003 Marco Pesenti Gritti
+ *
+ * This program 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, or (at your option)
+ * any later version.
+ *
+ * This program 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.
+ *
+ */
+
+#if !defined (__EV_EVINCE_DOCUMENT_H_INSIDE__) && !defined (EVINCE_COMPILATION)
+#error "Only <evince-document.h> can be included directly."
+#endif
+
+#ifndef EV_ASYNC_RENDERER_H
+#define EV_ASYNC_RENDERER_H
+
+#include <glib-object.h>
+#include <glib.h>
+#include <gdk/gdk.h>
+
+G_BEGIN_DECLS
+
+#define EV_TYPE_ASYNC_RENDERER (ev_async_renderer_get_type ())
+#define EV_ASYNC_RENDERER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EV_TYPE_ASYNC_RENDERER, EvAsyncRenderer))
+#define EV_ASYNC_RENDERER_IFACE(k) (G_TYPE_CHECK_CLASS_CAST((k), EV_TYPE_ASYNC_RENDERER, EvAsyncRendererInterface))
+#define EV_IS_ASYNC_RENDERER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EV_TYPE_ASYNC_RENDERER))
+#define EV_IS_ASYNC_RENDERER_IFACE(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EV_TYPE_ASYNC_RENDERER))
+#define EV_ASYNC_RENDERER_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), EV_TYPE_ASYNC_RENDERER, EvAsyncRendererInterface))
+
+typedef struct _EvAsyncRenderer EvAsyncRenderer;
+typedef struct _EvAsyncRendererInterface EvAsyncRendererInterface;
+
+struct _EvAsyncRendererInterface
+{
+ GTypeInterface base_iface;
+
+ void (* render_finished) (EvAsyncRenderer *renderer,
+ GdkPixbuf *pixbuf);
+
+ void (* render_pixbuf) (EvAsyncRenderer *renderer,
+ int page,
+ double scale,
+ int rotation);
+};
+
+GType ev_async_renderer_get_type (void);
+void ev_async_renderer_render_pixbuf (EvAsyncRenderer *renderer,
+ int page,
+ double scale,
+ int rotation);
+
+G_END_DECLS
+
+#endif
diff --git a/libdocument/ev-attachment.c b/libdocument/ev-attachment.c
new file mode 100644
index 00000000..7f41771e
--- /dev/null
+++ b/libdocument/ev-attachment.c
@@ -0,0 +1,439 @@
+/* this file is part of evince, a mate document viewer
+ *
+ * Copyright (C) 2006 Carlos Garcia Campos <[email protected]>
+ *
+ * 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 <glib/gi18n-lib.h>
+#include <glib/gstdio.h>
+#include <gtk/gtk.h>
+#include "ev-file-helpers.h"
+#include "ev-attachment.h"
+
+enum
+{
+ PROP_0,
+ PROP_NAME,
+ PROP_DESCRIPTION,
+ PROP_MTIME,
+ PROP_CTIME,
+ PROP_SIZE,
+ PROP_DATA
+};
+
+struct _EvAttachmentPrivate {
+ gchar *name;
+ gchar *description;
+ GTime mtime;
+ GTime ctime;
+ gsize size;
+ gchar *data;
+ gchar *mime_type;
+
+ GAppInfo *app;
+ GFile *tmp_file;
+};
+
+#define EV_ATTACHMENT_GET_PRIVATE(object) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((object), EV_TYPE_ATTACHMENT, EvAttachmentPrivate))
+
+G_DEFINE_TYPE (EvAttachment, ev_attachment, G_TYPE_OBJECT)
+
+GQuark
+ev_attachment_error_quark (void)
+{
+ static GQuark error_quark = 0;
+
+ if (error_quark == 0)
+ error_quark =
+ g_quark_from_static_string ("ev-attachment-error-quark");
+
+ return error_quark;
+}
+
+static void
+ev_attachment_finalize (GObject *object)
+{
+ EvAttachment *attachment = EV_ATTACHMENT (object);
+
+ if (attachment->priv->name) {
+ g_free (attachment->priv->name);
+ attachment->priv->name = NULL;
+ }
+
+ if (attachment->priv->description) {
+ g_free (attachment->priv->description);
+ attachment->priv->description = NULL;
+ }
+
+ if (attachment->priv->data) {
+ g_free (attachment->priv->data);
+ attachment->priv->data = NULL;
+ }
+
+ if (attachment->priv->mime_type) {
+ g_free (attachment->priv->mime_type);
+ attachment->priv->mime_type = NULL;
+ }
+
+ if (attachment->priv->app) {
+ g_object_unref (attachment->priv->app);
+ attachment->priv->app = NULL;
+ }
+
+ if (attachment->priv->tmp_file) {
+ ev_tmp_file_unlink (attachment->priv->tmp_file);
+ g_object_unref (attachment->priv->tmp_file);
+ attachment->priv->tmp_file = NULL;
+ }
+
+ G_OBJECT_CLASS (ev_attachment_parent_class)->finalize (object);
+}
+
+static void
+ev_attachment_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *param_spec)
+{
+ EvAttachment *attachment = EV_ATTACHMENT (object);
+
+ switch (prop_id) {
+ case PROP_NAME:
+ attachment->priv->name = g_value_dup_string (value);
+ break;
+ case PROP_DESCRIPTION:
+ attachment->priv->description = g_value_dup_string (value);
+ break;
+ case PROP_MTIME:
+ attachment->priv->mtime = g_value_get_ulong (value);
+ break;
+ case PROP_CTIME:
+ attachment->priv->ctime = g_value_get_ulong (value);
+ break;
+ case PROP_SIZE:
+ attachment->priv->size = g_value_get_uint (value);
+ break;
+ case PROP_DATA:
+ attachment->priv->data = g_value_get_pointer (value);
+ attachment->priv->mime_type = g_content_type_guess (attachment->priv->name,
+ (guchar *) attachment->priv->data,
+ attachment->priv->size,
+ NULL);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object,
+ prop_id,
+ param_spec);
+ break;
+ }
+}
+
+static void
+ev_attachment_class_init (EvAttachmentClass *klass)
+{
+ GObjectClass *g_object_class;
+
+ g_object_class = G_OBJECT_CLASS (klass);
+
+ g_object_class->set_property = ev_attachment_set_property;
+
+ g_type_class_add_private (g_object_class, sizeof (EvAttachmentPrivate));
+
+ /* Properties */
+ g_object_class_install_property (g_object_class,
+ PROP_NAME,
+ g_param_spec_string ("name",
+ "Name",
+ "The attachment name",
+ NULL,
+ G_PARAM_WRITABLE |
+ G_PARAM_CONSTRUCT_ONLY));
+ g_object_class_install_property (g_object_class,
+ PROP_DESCRIPTION,
+ g_param_spec_string ("description",
+ "Description",
+ "The attachment description",
+ NULL,
+ G_PARAM_WRITABLE |
+ G_PARAM_CONSTRUCT_ONLY));
+ g_object_class_install_property (g_object_class,
+ PROP_MTIME,
+ g_param_spec_ulong ("mtime",
+ "ModifiedTime",
+ "The attachment modification date",
+ 0, G_MAXULONG, 0,
+ G_PARAM_WRITABLE |
+ G_PARAM_CONSTRUCT_ONLY));
+ g_object_class_install_property (g_object_class,
+ PROP_CTIME,
+ g_param_spec_ulong ("ctime",
+ "CreationTime",
+ "The attachment creation date",
+ 0, G_MAXULONG, 0,
+ G_PARAM_WRITABLE |
+ G_PARAM_CONSTRUCT_ONLY));
+ g_object_class_install_property (g_object_class,
+ PROP_SIZE,
+ g_param_spec_uint ("size",
+ "Size",
+ "The attachment size",
+ 0, G_MAXUINT, 0,
+ G_PARAM_WRITABLE |
+ G_PARAM_CONSTRUCT_ONLY));
+ g_object_class_install_property (g_object_class,
+ PROP_DATA,
+ g_param_spec_pointer ("data",
+ "Data",
+ "The attachment data",
+ G_PARAM_WRITABLE |
+ G_PARAM_CONSTRUCT_ONLY));
+
+ g_object_class->finalize = ev_attachment_finalize;
+}
+
+static void
+ev_attachment_init (EvAttachment *attachment)
+{
+ attachment->priv = EV_ATTACHMENT_GET_PRIVATE (attachment);
+
+ attachment->priv->name = NULL;
+ attachment->priv->description = NULL;
+ attachment->priv->data = NULL;
+ attachment->priv->mime_type = NULL;
+
+ attachment->priv->tmp_file = NULL;
+}
+
+EvAttachment *
+ev_attachment_new (const gchar *name,
+ const gchar *description,
+ GTime mtime,
+ GTime ctime,
+ gsize size,
+ gpointer data)
+{
+ EvAttachment *attachment;
+
+ attachment = g_object_new (EV_TYPE_ATTACHMENT,
+ "name", name,
+ "description", description,
+ "mtime", mtime,
+ "ctime", ctime,
+ "size", size,
+ "data", data,
+ NULL);
+
+ return attachment;
+}
+
+const gchar *
+ev_attachment_get_name (EvAttachment *attachment)
+{
+ g_return_val_if_fail (EV_IS_ATTACHMENT (attachment), NULL);
+
+ return attachment->priv->name;
+}
+
+const gchar *
+ev_attachment_get_description (EvAttachment *attachment)
+{
+ g_return_val_if_fail (EV_IS_ATTACHMENT (attachment), NULL);
+
+ return attachment->priv->description;
+}
+
+GTime
+ev_attachment_get_modification_date (EvAttachment *attachment)
+{
+ g_return_val_if_fail (EV_IS_ATTACHMENT (attachment), 0);
+
+ return attachment->priv->mtime;
+}
+
+GTime
+ev_attachment_get_creation_date (EvAttachment *attachment)
+{
+ g_return_val_if_fail (EV_IS_ATTACHMENT (attachment), 0);
+
+ return attachment->priv->ctime;
+}
+
+const gchar *
+ev_attachment_get_mime_type (EvAttachment *attachment)
+{
+ g_return_val_if_fail (EV_IS_ATTACHMENT (attachment), NULL);
+
+ return attachment->priv->mime_type;
+}
+
+gboolean
+ev_attachment_save (EvAttachment *attachment,
+ GFile *file,
+ GError **error)
+{
+ GFileOutputStream *output_stream;
+ GError *ioerror = NULL;
+ gssize written_bytes;
+
+ g_return_val_if_fail (EV_IS_ATTACHMENT (attachment), FALSE);
+ g_return_val_if_fail (G_IS_FILE (file), FALSE);
+
+ output_stream = g_file_replace (file, NULL, FALSE, 0, NULL, &ioerror);
+ if (output_stream == NULL) {
+ char *uri;
+
+ uri = g_file_get_uri (file);
+ g_set_error (error,
+ EV_ATTACHMENT_ERROR,
+ ioerror->code,
+ _("Couldn't save attachment “%s”: %s"),
+ uri,
+ ioerror->message);
+
+ g_error_free (ioerror);
+ g_free (uri);
+
+ return FALSE;
+ }
+
+ written_bytes = g_output_stream_write (G_OUTPUT_STREAM (output_stream),
+ attachment->priv->data,
+ attachment->priv->size,
+ NULL, &ioerror);
+ if (written_bytes == -1) {
+ char *uri;
+
+ uri = g_file_get_uri (file);
+ g_set_error (error,
+ EV_ATTACHMENT_ERROR,
+ ioerror->code,
+ _("Couldn't save attachment “%s”: %s"),
+ uri,
+ ioerror->message);
+
+ g_output_stream_close (G_OUTPUT_STREAM (output_stream), NULL, NULL);
+ g_error_free (ioerror);
+ g_free (uri);
+
+ return FALSE;
+ }
+
+ g_output_stream_close (G_OUTPUT_STREAM (output_stream), NULL, NULL);
+
+ return TRUE;
+
+}
+
+static gboolean
+ev_attachment_launch_app (EvAttachment *attachment,
+ GdkScreen *screen,
+ guint32 timestamp,
+ GError **error)
+{
+ gboolean result;
+ GList *files = NULL;
+ GAppLaunchContext *context = NULL;
+ GError *ioerror = NULL;
+
+ g_assert (G_IS_FILE (attachment->priv->tmp_file));
+ g_assert (G_IS_APP_INFO (attachment->priv->app));
+
+ files = g_list_prepend (files, attachment->priv->tmp_file);
+
+ context = G_APP_LAUNCH_CONTEXT (gdk_app_launch_context_new ());
+ gdk_app_launch_context_set_screen (GDK_APP_LAUNCH_CONTEXT (context), screen);
+ gdk_app_launch_context_set_timestamp (GDK_APP_LAUNCH_CONTEXT (context), timestamp);
+
+ result = g_app_info_launch (attachment->priv->app, files,
+ context, &ioerror);
+
+ if (context)
+ g_object_unref (context);
+
+ if (!result) {
+ g_set_error (error,
+ EV_ATTACHMENT_ERROR,
+ (gint) result,
+ _("Couldn't open attachment “%s”: %s"),
+ attachment->priv->name,
+ ioerror->message);
+
+ g_list_free (files);
+ g_error_free (ioerror);
+
+ return FALSE;
+ }
+
+ g_list_free (files);
+
+ return TRUE;
+}
+
+gboolean
+ev_attachment_open (EvAttachment *attachment,
+ GdkScreen *screen,
+ guint32 timestamp,
+ GError **error)
+{
+ GAppInfo *app_info;
+ gboolean retval = FALSE;
+
+ g_return_val_if_fail (EV_IS_ATTACHMENT (attachment), FALSE);
+
+ if (!attachment->priv->app) {
+ app_info = g_app_info_get_default_for_type (attachment->priv->mime_type, FALSE);
+ attachment->priv->app = app_info;
+ }
+
+ if (!attachment->priv->app) {
+ g_set_error (error,
+ EV_ATTACHMENT_ERROR,
+ 0,
+ _("Couldn't open attachment “%s”"),
+ attachment->priv->name);
+
+ return FALSE;
+ }
+
+ if (attachment->priv->tmp_file) {
+ retval = ev_attachment_launch_app (attachment, screen,
+ timestamp, error);
+ } else {
+ char *template;
+ GFile *file;
+
+ /* FIXMEchpe: convert to filename encoding first! */
+ template = g_strdup_printf ("%s.XXXXXX", ev_attachment_get_name (attachment));
+ file = ev_mkstemp_file (template, error);
+ g_free (template);
+
+ if (file != NULL && ev_attachment_save (attachment, file, error)) {
+ if (attachment->priv->tmp_file)
+ g_object_unref (attachment->priv->tmp_file);
+ attachment->priv->tmp_file = g_object_ref (file);
+
+ retval = ev_attachment_launch_app (attachment, screen,
+ timestamp, error);
+ }
+
+ g_object_unref (file);
+ }
+
+ return retval;
+}
+
diff --git a/libdocument/ev-attachment.h b/libdocument/ev-attachment.h
new file mode 100644
index 00000000..79ec1a8b
--- /dev/null
+++ b/libdocument/ev-attachment.h
@@ -0,0 +1,79 @@
+/* this file is part of evince, a mate document viewer
+ *
+ * Copyright (C) 2006 Carlos Garcia Campos <[email protected]>
+ *
+ * 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.
+ */
+
+#if !defined (__EV_EVINCE_DOCUMENT_H_INSIDE__) && !defined (EVINCE_COMPILATION)
+#error "Only <evince-document.h> can be included directly."
+#endif
+
+#ifndef __EV_ATTACHMENT_H__
+#define __EV_ATTACHMENT_H__
+
+#include <glib-object.h>
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+typedef struct _EvAttachment EvAttachment;
+typedef struct _EvAttachmentClass EvAttachmentClass;
+typedef struct _EvAttachmentPrivate EvAttachmentPrivate;
+
+#define EV_TYPE_ATTACHMENT (ev_attachment_get_type())
+#define EV_ATTACHMENT(object) (G_TYPE_CHECK_INSTANCE_CAST((object), EV_TYPE_ATTACHMENT, EvAttachment))
+#define EV_ATTACHMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), EV_TYPE_ATTACHMENT, EvAttachmentClass))
+#define EV_IS_ATTACHMENT(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), EV_TYPE_ATTACHMENT))
+#define EV_IS_ATTACHMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), EV_TYPE_ATTACHMENT))
+#define EV_ATTACHMENT_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS((object), EV_TYPE_ATTACHMENT, EvAttachmentClass))
+
+#define EV_ATTACHMENT_ERROR (ev_attachment_error_quark ())
+
+struct _EvAttachment {
+ GObject base_instance;
+
+ EvAttachmentPrivate *priv;
+};
+
+struct _EvAttachmentClass {
+ GObjectClass base_class;
+};
+
+GType ev_attachment_get_type (void) G_GNUC_CONST;
+GQuark ev_attachment_error_quark (void) G_GNUC_CONST;
+EvAttachment *ev_attachment_new (const gchar *name,
+ const gchar *description,
+ GTime mtime,
+ GTime ctime,
+ gsize size,
+ gpointer data);
+
+const gchar *ev_attachment_get_name (EvAttachment *attachment);
+const gchar *ev_attachment_get_description (EvAttachment *attachment);
+GTime ev_attachment_get_modification_date (EvAttachment *attachment);
+GTime ev_attachment_get_creation_date (EvAttachment *attachment);
+const gchar *ev_attachment_get_mime_type (EvAttachment *attachment);
+gboolean ev_attachment_save (EvAttachment *attachment,
+ GFile *file,
+ GError **error);
+gboolean ev_attachment_open (EvAttachment *attachment,
+ GdkScreen *screen,
+ guint32 timestamp,
+ GError **error);
+
+G_END_DECLS
+
+#endif /* __EV_ATTACHMENT_H__ */
diff --git a/libdocument/ev-backends-manager.c b/libdocument/ev-backends-manager.c
new file mode 100644
index 00000000..f0b1d902
--- /dev/null
+++ b/libdocument/ev-backends-manager.c
@@ -0,0 +1,333 @@
+/* this file is part of evince, a mate document viewer
+ *
+ * Copyright (C) 2007 Carlos Garcia Campos <[email protected]>
+ *
+ * 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 <glib/gstdio.h>
+
+#include "ev-module.h"
+#include "ev-backends-manager.h"
+
+static GList *ev_backends_list = NULL;
+
+typedef struct _EvBackendInfo EvBackendInfo;
+struct _EvBackendInfo {
+ gchar *module_name;
+ GTypeModule *module;
+ gboolean resident;
+
+ GType type_id;
+
+ gchar *type_desc;
+ gchar **mime_types;
+};
+
+#define EV_BACKENDS_GROUP "Evince Backend"
+#define EV_BACKENDS_EXTENSION ".evince-backend"
+
+static gchar *backendsdir = NULL;
+
+static const gchar *
+backends_dir (void)
+{
+ if (!backendsdir) {
+#ifdef G_OS_WIN32
+ gchar *dir;
+
+ dir = g_win32_get_package_installation_directory_of_module (NULL);
+ backendsdir = g_build_filename (dir, "lib", "evince",
+ EV_BACKENDSBINARYVERSION,
+ "backends", NULL);
+ g_free (dir);
+#else
+ backendsdir = g_strdup (EV_BACKENDSDIR);
+#endif
+ }
+
+ return backendsdir;
+}
+
+static void
+ev_backend_info_free (EvBackendInfo *info)
+{
+ g_free (info->module_name);
+ g_free (info->type_desc);
+ g_strfreev (info->mime_types);
+ g_free (info);
+}
+
+static EvBackendInfo *
+ev_backends_manager_load_backend (const gchar *file)
+{
+ EvBackendInfo *info;
+ GKeyFile *backend_file = NULL;
+ GError *error = NULL;
+
+ backend_file = g_key_file_new ();
+ if (!g_key_file_load_from_file (backend_file, file, G_KEY_FILE_NONE, &error)) {
+ g_warning ("Error opening backend file %s: %s",
+ file, error->message);
+ g_error_free (error);
+ g_key_file_free (backend_file);
+
+ return NULL;
+ }
+
+ info = g_new0 (EvBackendInfo, 1);
+ info->module_name = g_key_file_get_string (backend_file, EV_BACKENDS_GROUP,
+ "Module", NULL);
+ if (!info->module_name) {
+ g_warning ("Bad evince backend file %s: Could not find 'Module'",
+ file);
+ ev_backend_info_free (info);
+ g_key_file_free (backend_file);
+
+ return NULL;
+ }
+
+ info->resident = g_key_file_get_boolean (backend_file, EV_BACKENDS_GROUP,
+ "Resident", NULL);
+
+ info->type_desc = g_key_file_get_locale_string (backend_file, EV_BACKENDS_GROUP,
+ "TypeDescription", NULL, NULL);
+ if (!info->type_desc) {
+ g_warning ("Bad evince backend file %s: Could not find 'TypeDescription'",
+ file);
+ ev_backend_info_free (info);
+ g_key_file_free (backend_file);
+
+ return NULL;
+ }
+
+ info->mime_types = g_key_file_get_string_list (backend_file, EV_BACKENDS_GROUP,
+ "MimeType", NULL, NULL);
+ if (!info->mime_types) {
+ g_warning ("Bad evince backend file %s: Could not find 'MimeType'",
+ file);
+ ev_backend_info_free (info);
+ g_key_file_free (backend_file);
+
+ return NULL;
+ }
+
+ g_key_file_free (backend_file);
+
+ return info;
+}
+
+static gboolean
+ev_backends_manager_load (void)
+{
+ GDir *dir;
+ const gchar *dirent;
+ GError *error = NULL;
+
+ dir = g_dir_open (backends_dir(), 0, &error);
+ if (!dir) {
+ g_warning ("%s", error->message);
+ g_error_free (error);
+
+ return FALSE;
+ }
+
+ while ((dirent = g_dir_read_name (dir))) {
+ EvBackendInfo *info;
+ gchar *file;
+
+ if (!g_str_has_suffix (dirent, EV_BACKENDS_EXTENSION))
+ continue;
+
+ file = g_build_filename (backends_dir(), dirent, NULL);
+ info = ev_backends_manager_load_backend (file);
+ g_free (file);
+
+ if (!info)
+ continue;
+
+ ev_backends_list = g_list_prepend (ev_backends_list, info);
+ }
+
+ g_dir_close (dir);
+
+ return ev_backends_list != NULL;
+}
+
+/*
+ * _ev_backends_manager_init:
+ *
+ * Initializes the evince backends manager.
+ *
+ * Returns: %TRUE if there were any backends found; %FALSE otherwise
+ */
+gboolean
+_ev_backends_manager_init (void)
+{
+ if (ev_backends_list)
+ return TRUE;
+
+ return ev_backends_manager_load ();
+}
+
+/*
+ * _ev_backends_manager_shutdown:
+ *
+ * Shuts the evince backends manager down.
+ */
+void
+_ev_backends_manager_shutdown (void)
+{
+ g_list_foreach (ev_backends_list, (GFunc)ev_backend_info_free, NULL);
+ g_list_free (ev_backends_list);
+ ev_backends_list = NULL;
+
+ g_free (backendsdir);
+}
+
+static EvBackendInfo *
+ev_backends_manager_get_backend_info (const gchar *mime_type)
+{
+ GList *l;
+
+ for (l = ev_backends_list; l; l = g_list_next (l)) {
+ EvBackendInfo *info;
+ gint i = 0;
+ const char *mime;
+
+ info = (EvBackendInfo *)l->data;
+
+ while ((mime = info->mime_types[i++])) {
+ if (g_ascii_strcasecmp (mime, mime_type) == 0)
+ return info;
+ }
+ }
+
+ return NULL;
+}
+
+EvDocument *
+ev_backends_manager_get_document (const gchar *mime_type)
+{
+ EvDocument *document;
+ EvBackendInfo *info;
+
+ info = ev_backends_manager_get_backend_info (mime_type);
+ if (!info)
+ return NULL;
+
+ if (!info->module) {
+ gchar *path;
+
+ path = g_module_build_path (backends_dir(), info->module_name);
+ info->module = G_TYPE_MODULE (ev_module_new (path, info->resident));
+ g_free (path);
+ }
+
+ if (!g_type_module_use (info->module)) {
+ g_warning ("Cannot load backend '%s' since file '%s' cannot be read.",
+ info->module_name,
+ ev_module_get_path (EV_MODULE (info->module)));
+ g_object_unref (G_OBJECT (info->module));
+ info->module = NULL;
+
+ return NULL;
+ }
+
+ document = EV_DOCUMENT (ev_module_new_object (EV_MODULE (info->module)));
+ g_type_module_unuse (info->module);
+
+ return document;
+}
+
+static EvBackendInfo *
+get_document_backend_info (EvDocument *document)
+{
+ GList *l;
+
+ for (l = ev_backends_list; l; l = g_list_next (l)) {
+ EvBackendInfo *info;
+ GType type_id;
+
+ info = (EvBackendInfo *)l->data;
+
+ if (!info->module)
+ continue;
+
+ type_id = ev_module_get_object_type (EV_MODULE (info->module));
+
+ if (G_TYPE_CHECK_INSTANCE_TYPE (document, type_id)) {
+ return info;
+ }
+ }
+
+ return NULL;
+}
+
+const gchar *
+ev_backends_manager_get_document_module_name (EvDocument *document)
+{
+ EvBackendInfo *info;
+
+ info = get_document_backend_info (document);
+ return info ? info->module_name : NULL;
+}
+
+static EvTypeInfo *
+ev_type_info_new (const gchar *desc, const gchar **mime_types)
+{
+ EvTypeInfo *info;
+
+ info = g_new (EvTypeInfo, 1);
+
+ info->desc = desc;
+ info->mime_types = mime_types;
+
+ return info;
+}
+
+EvTypeInfo *
+ev_backends_manager_get_document_type_info (EvDocument *document)
+{
+ EvBackendInfo *info;
+
+ info = get_document_backend_info (document);
+ return info ?
+ ev_type_info_new (info->type_desc,
+ (const gchar **)info->mime_types)
+ : NULL;
+}
+
+GList *
+ev_backends_manager_get_all_types_info (void)
+{
+ GList *l;
+ GList *retval = NULL;
+
+ for (l = ev_backends_list; l; l = g_list_next (l)) {
+ EvBackendInfo *info;
+ EvTypeInfo *type_info;
+
+ info = (EvBackendInfo *)l->data;
+
+ type_info = ev_type_info_new (info->type_desc,
+ (const gchar **)info->mime_types);
+ retval = g_list_prepend (retval, type_info);
+ }
+
+ return retval;
+}
diff --git a/libdocument/ev-backends-manager.h b/libdocument/ev-backends-manager.h
new file mode 100644
index 00000000..b2d7d245
--- /dev/null
+++ b/libdocument/ev-backends-manager.h
@@ -0,0 +1,48 @@
+/* this file is part of evince, a mate document viewer
+ *
+ * Copyright (C) 2007 Carlos Garcia Campos <[email protected]>
+ *
+ * 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.
+ */
+
+#if !defined (__EV_EVINCE_DOCUMENT_H_INSIDE__) && !defined (EVINCE_COMPILATION)
+#error "Only <evince-document.h> can be included directly."
+#endif
+
+#ifndef EV_BACKENDS_MANAGER
+#define EV_BACKENDS_MANAGER
+
+#include <glib.h>
+
+#include "ev-document.h"
+
+G_BEGIN_DECLS
+
+typedef struct _EvTypeInfo {
+ const gchar *desc;
+ const gchar **mime_types;
+} EvTypeInfo;
+
+gboolean _ev_backends_manager_init (void);
+void _ev_backends_manager_shutdown (void);
+
+EvDocument *ev_backends_manager_get_document (const gchar *mime_type);
+const gchar *ev_backends_manager_get_document_module_name (EvDocument *document);
+EvTypeInfo *ev_backends_manager_get_document_type_info (EvDocument *document);
+GList *ev_backends_manager_get_all_types_info (void);
+
+G_END_DECLS
+
+#endif /* EV_BACKENDS_MANAGER */
diff --git a/libdocument/ev-debug.c b/libdocument/ev-debug.c
new file mode 100644
index 00000000..4750c9d3
--- /dev/null
+++ b/libdocument/ev-debug.c
@@ -0,0 +1,177 @@
+/*
+ * ev-debug.c
+ * This file is part of Evince
+ *
+ * Copyright (C) 1998, 1999 Alex Roberts, Evan Lawrence
+ * Copyright (C) 2000, 2001 Chema Celorio, Paolo Maggi
+ * Copyright (C) 2002 - 2005 Paolo Maggi
+ *
+ * This program 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.
+ *
+ * This program 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.
+ */
+
+/*
+ * Modified by the gedit Team, 1998-2005. See the AUTHORS file for a
+ * list of people on the gedit Team.
+ * See the ChangeLog files for a list of changes.
+ *
+ * $Id: gedit-debug.c 4809 2006-04-08 14:46:31Z pborelli $
+ */
+
+/* Modified by Evince Team */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+
+#include "ev-debug.h"
+
+#ifdef EV_ENABLE_DEBUG
+static EvDebugSection ev_debug = EV_NO_DEBUG;
+static EvProfileSection ev_profile = EV_NO_PROFILE;
+
+static GHashTable *timers = NULL;
+
+static void
+debug_init ()
+{
+ if (g_getenv ("EV_DEBUG") != NULL) {
+ /* enable all debugging */
+ ev_debug = ~EV_NO_DEBUG;
+ return;
+ }
+
+ if (g_getenv ("EV_DEBUG_JOBS") != NULL)
+ ev_debug |= EV_DEBUG_JOBS;
+}
+
+static void
+profile_init ()
+{
+ if (g_getenv ("EV_PROFILE") != NULL) {
+ /* enable all profiling */
+ ev_profile = ~EV_NO_PROFILE;
+ } else {
+ if (g_getenv ("EV_PROFILE_JOBS") != NULL)
+ ev_profile |= EV_PROFILE_JOBS;
+ }
+
+ if (ev_profile) {
+ timers = g_hash_table_new_full (g_str_hash,
+ g_str_equal,
+ (GDestroyNotify) g_free,
+ (GDestroyNotify) g_timer_destroy);
+ }
+}
+
+void
+_ev_debug_init ()
+{
+ debug_init ();
+ profile_init ();
+}
+
+void
+_ev_debug_shutdown ()
+{
+ if (timers) {
+ g_hash_table_destroy (timers);
+ timers = NULL;
+ }
+}
+
+void
+ev_debug_message (EvDebugSection section,
+ const gchar *file,
+ gint line,
+ const gchar *function,
+ const gchar *format, ...)
+{
+ if (G_UNLIKELY (ev_debug & section)) {
+ gchar *msg = NULL;
+
+ if (format) {
+ va_list args;
+
+ va_start (args, format);
+ msg = g_strdup_vprintf (format, args);
+ va_end (args);
+ }
+
+ g_print ("%s:%d (%s) %s\n", file, line, function, msg ? msg : "");
+
+ fflush (stdout);
+
+ g_free (msg);
+ }
+}
+
+void
+ev_profiler_start (EvProfileSection section,
+ const gchar *format, ...)
+{
+ if (G_UNLIKELY (ev_profile & section)) {
+ GTimer *timer;
+ gchar *name;
+ va_list args;
+
+ if (!format)
+ return;
+
+ va_start (args, format);
+ name = g_strdup_vprintf (format, args);
+ va_end (args);
+
+ timer = g_hash_table_lookup (timers, name);
+ if (!timer) {
+ timer = g_timer_new ();
+ g_hash_table_insert (timers, g_strdup (name), timer);
+ } else {
+ g_timer_start (timer);
+ }
+ }
+}
+
+void
+ev_profiler_stop (EvProfileSection section,
+ const gchar *format, ...)
+{
+ if (G_UNLIKELY (ev_profile & section)) {
+ GTimer *timer;
+ gchar *name;
+ va_list args;
+ gdouble seconds;
+
+ if (!format)
+ return;
+
+ va_start (args, format);
+ name = g_strdup_vprintf (format, args);
+ va_end (args);
+
+ timer = g_hash_table_lookup (timers, name);
+ if (!timer)
+ return;
+
+ g_timer_stop (timer);
+ seconds = g_timer_elapsed (timer, NULL);
+ g_print ("[ %s ] %f s elapsed\n", name, seconds);
+ fflush (stdout);
+ }
+}
+
+#endif /* EV_ENABLE_DEBUG */
diff --git a/libdocument/ev-debug.h b/libdocument/ev-debug.h
new file mode 100644
index 00000000..cf252431
--- /dev/null
+++ b/libdocument/ev-debug.h
@@ -0,0 +1,106 @@
+/*
+ * ev-debug.h
+ * This file is part of Evince
+ *
+ * Copyright (C) 1998, 1999 Alex Roberts, Evan Lawrence
+ * Copyright (C) 2000, 2001 Chema Celorio, Paolo Maggi
+ * Copyright (C) 2002 - 2005 Paolo Maggi
+ *
+ * This program 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.
+ *
+ * This program 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.
+ */
+
+/*
+ * Modified by the gedit Team, 1998-2005. See the AUTHORS file for a
+ * list of people on the gedit Team.
+ * See the ChangeLog files for a list of changes.
+ *
+ * $Id: gedit-debug.h 4809 2006-04-08 14:46:31Z pborelli $
+ */
+
+/* Modified by Evince Team */
+
+#if !defined (EVINCE_COMPILATION)
+#error "This is a private header."
+#endif
+
+#ifndef __EV_DEBUG_H__
+#define __EV_DEBUG_H__
+
+#include <glib-object.h>
+
+#define EV_GET_TYPE_NAME(instance) g_type_name_from_instance ((gpointer)instance)
+
+#ifndef EV_ENABLE_DEBUG
+
+#define _ev_debug_init()
+#define _ev_debug_shutdown()
+#if defined(G_HAVE_GNUC_VARARGS)
+#define ev_debug_message(section, format, args...) G_STMT_START { } G_STMT_END
+#define ev_profiler_start(format, args...) G_STMT_START { } G_STMT_END
+#define ev_profiler_stop(format, args...) G_STMT_START { } G_STMT_END
+#elif defined(G_HAVE_ISO_VARARGS)
+#define ev_debug_message(...) G_STMT_START { } G_STMT_END
+#define ev_profiler_start(...) G_STMT_START { } G_STMT_END
+#define ev_profiler_stop(...) G_STMT_START { } G_STMT_END
+#else /* no varargs macros */
+static void ev_debug_message(EvDebugSection section, const gchar *file, gint line, const gchar *function, const gchar *format, ...) {}
+static void ev_profiler_start(EvProfileSection section, const gchar *format, ...) {}
+static void ev_profiler_stop(EvProfileSection section, const gchar *format, ...) {}
+#endif
+
+#else /* ENABLE_DEBUG */
+
+G_BEGIN_DECLS
+
+/*
+ * Set an environmental var of the same name to turn on
+ * debugging output. Setting EV_DEBUG will turn on all
+ * sections.
+ */
+typedef enum {
+ EV_NO_DEBUG = 0,
+ EV_DEBUG_JOBS = 1 << 0
+} EvDebugSection;
+
+#define DEBUG_JOBS EV_DEBUG_JOBS, __FILE__, __LINE__, G_STRFUNC
+
+/*
+ * Set an environmental var of the same name to turn on
+ * profiling. Setting EV_PROFILE will turn on all
+ * sections.
+ */
+typedef enum {
+ EV_NO_PROFILE = 0,
+ EV_PROFILE_JOBS = 1 << 0
+} EvProfileSection;
+
+void _ev_debug_init (void);
+void _ev_debug_shutdown (void);
+
+void ev_debug_message (EvDebugSection section,
+ const gchar *file,
+ gint line,
+ const gchar *function,
+ const gchar *format, ...) G_GNUC_PRINTF(5, 6);
+void ev_profiler_start (EvProfileSection section,
+ const gchar *format, ...) G_GNUC_PRINTF(2, 3);
+void ev_profiler_stop (EvProfileSection section,
+ const gchar *format, ...) G_GNUC_PRINTF(2, 3);
+
+G_END_DECLS
+
+#endif /* EV_ENABLE_DEBUG */
+#endif /* __EV_DEBUG_H__ */
diff --git a/libdocument/ev-document-annotations.c b/libdocument/ev-document-annotations.c
new file mode 100644
index 00000000..f153f3eb
--- /dev/null
+++ b/libdocument/ev-document-annotations.c
@@ -0,0 +1,75 @@
+/* ev-document-annotations.c
+ * this file is part of evince, a mate document viewer
+ *
+ * Copyright (C) 2009 Carlos Garcia Campos <[email protected]>
+ * Copyright (C) 2007 Iñigo Martinez <[email protected]>
+ *
+ * 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 "ev-document-annotations.h"
+
+G_DEFINE_INTERFACE (EvDocumentAnnotations, ev_document_annotations, 0)
+
+static void
+ev_document_annotations_default_init (EvDocumentAnnotationsInterface *klass)
+{
+}
+
+EvMappingList *
+ev_document_annotations_get_annotations (EvDocumentAnnotations *document_annots,
+ EvPage *page)
+{
+ EvDocumentAnnotationsInterface *iface = EV_DOCUMENT_ANNOTATIONS_GET_IFACE (document_annots);
+
+ return iface->get_annotations (document_annots, page);
+}
+
+gboolean
+ev_document_annotations_document_is_modified (EvDocumentAnnotations *document_annots)
+{
+ EvDocumentAnnotationsInterface *iface = EV_DOCUMENT_ANNOTATIONS_GET_IFACE (document_annots);
+
+ return (iface->document_is_modified) ? iface->document_is_modified (document_annots) : FALSE;
+}
+
+void
+ev_document_annotations_save_annotation (EvDocumentAnnotations *document_annots,
+ EvAnnotation *annot,
+ EvAnnotationsSaveMask mask)
+{
+ EvDocumentAnnotationsInterface *iface = EV_DOCUMENT_ANNOTATIONS_GET_IFACE (document_annots);
+
+ iface->save_annotation (document_annots, annot, mask);
+}
+
+void
+ev_document_annotations_add_annotation (EvDocumentAnnotations *document_annots,
+ EvAnnotation *annot,
+ EvRectangle *rect)
+{
+ EvDocumentAnnotationsInterface *iface = EV_DOCUMENT_ANNOTATIONS_GET_IFACE (document_annots);
+
+ if (iface->add_annotation)
+ iface->add_annotation (document_annots, annot, rect);
+}
+
+gboolean
+ev_document_annotations_can_add_annotation (EvDocumentAnnotations *document_annots)
+{
+ EvDocumentAnnotationsInterface *iface = EV_DOCUMENT_ANNOTATIONS_GET_IFACE (document_annots);
+
+ return iface->add_annotation != NULL;
+}
diff --git a/libdocument/ev-document-annotations.h b/libdocument/ev-document-annotations.h
new file mode 100644
index 00000000..55f7c0c1
--- /dev/null
+++ b/libdocument/ev-document-annotations.h
@@ -0,0 +1,99 @@
+/* ev-document-annotations.h
+ * this file is part of evince, a mate document viewer
+ *
+ * Copyright (C) 2007 Iñigo Martinez <[email protected]>
+ *
+ * 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.
+ */
+
+#if !defined (__EV_EVINCE_DOCUMENT_H_INSIDE__) && !defined (EVINCE_COMPILATION)
+#error "Only <evince-document.h> can be included directly."
+#endif
+
+#ifndef EV_DOCUMENT_ANNOTATIONS_H
+#define EV_DOCUMENT_ANNOTATIONS_H
+
+#include <glib-object.h>
+
+#include "ev-document.h"
+#include "ev-annotation.h"
+#include "ev-mapping-list.h"
+
+G_BEGIN_DECLS
+
+#define EV_TYPE_DOCUMENT_ANNOTATIONS (ev_document_annotations_get_type ())
+#define EV_DOCUMENT_ANNOTATIONS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EV_TYPE_DOCUMENT_ANNOTATIONS, EvDocumentAnnotations))
+#define EV_DOCUMENT_ANNOTATIONS_IFACE(k) (G_TYPE_CHECK_CLASS_CAST((k), EV_TYPE_DOCUMENT_ANNOTATIONS, EvDocumentAnnotationsInterface))
+#define EV_IS_DOCUMENT_ANNOTATIONS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EV_TYPE_DOCUMENT_ANNOTATIONS))
+#define EV_IS_DOCUMENT_ANNOTATIONS_IFACE(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EV_TYPE_DOCUMENT_ANNOTATIONS))
+#define EV_DOCUMENT_ANNOTATIONS_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), EV_TYPE_DOCUMENT_ANNOTATIONS, EvDocumentAnnotationsInterface))
+
+typedef enum {
+ EV_ANNOTATIONS_SAVE_NONE = 0,
+ EV_ANNOTATIONS_SAVE_CONTENTS = 1 << 0,
+ EV_ANNOTATIONS_SAVE_COLOR = 1 << 1,
+
+ /* Markup Annotations */
+ EV_ANNOTATIONS_SAVE_LABEL = 1 << 2,
+ EV_ANNOTATIONS_SAVE_OPACITY = 1 << 3,
+ EV_ANNOTATIONS_SAVE_POPUP_RECT = 1 << 4,
+ EV_ANNOTATIONS_SAVE_POPUP_IS_OPEN = 1 << 5,
+
+ /* Text Annotations */
+ EV_ANNOTATIONS_SAVE_TEXT_IS_OPEN = 1 << 6,
+ EV_ANNOTATIONS_SAVE_TEXT_ICON = 1 << 7,
+
+ /* Attachment Annotations */
+ EV_ANNOTATIONS_SAVE_ATTACHMENT = 1 << 8,
+
+ /* Save all */
+ EV_ANNOTATIONS_SAVE_ALL = (1 << 9) - 1
+} EvAnnotationsSaveMask;
+
+typedef struct _EvDocumentAnnotations EvDocumentAnnotations;
+typedef struct _EvDocumentAnnotationsInterface EvDocumentAnnotationsInterface;
+
+struct _EvDocumentAnnotationsInterface
+{
+ GTypeInterface base_iface;
+
+ /* Methods */
+ EvMappingList *(* get_annotations) (EvDocumentAnnotations *document_annots,
+ EvPage *page);
+ gboolean (* document_is_modified) (EvDocumentAnnotations *document_annots);
+ void (* add_annotation) (EvDocumentAnnotations *document_annots,
+ EvAnnotation *annot,
+ EvRectangle *rect);
+ void (* save_annotation) (EvDocumentAnnotations *document_annots,
+ EvAnnotation *annot,
+ EvAnnotationsSaveMask mask);
+};
+
+GType ev_document_annotations_get_type (void) G_GNUC_CONST;
+EvMappingList *ev_document_annotations_get_annotations (EvDocumentAnnotations *document_annots,
+ EvPage *page);
+gboolean ev_document_annotations_document_is_modified (EvDocumentAnnotations *document_annots);
+void ev_document_annotations_add_annotation (EvDocumentAnnotations *document_annots,
+ EvAnnotation *annot,
+ EvRectangle *rect);
+void ev_document_annotations_save_annotation (EvDocumentAnnotations *document_annots,
+ EvAnnotation *annot,
+ EvAnnotationsSaveMask mask);
+gboolean ev_document_annotations_can_add_annotation (EvDocumentAnnotations *document_annots);
+
+G_END_DECLS
+
+#endif /* EV_DOCUMENT_ANNOTATIONS_H */
+
diff --git a/libdocument/ev-document-attachments.c b/libdocument/ev-document-attachments.c
new file mode 100644
index 00000000..bb3cb2ae
--- /dev/null
+++ b/libdocument/ev-document-attachments.c
@@ -0,0 +1,49 @@
+/* ev-document-attachments.c
+ * this file is part of evince, a mate document_links viewer
+ *
+ * Copyright (C) 2009 Carlos Garcia Campos <[email protected]>
+ *
+ * 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-attachments.h"
+#include "ev-document.h"
+
+G_DEFINE_INTERFACE (EvDocumentAttachments, ev_document_attachments, 0)
+
+static void
+ev_document_attachments_default_init (EvDocumentAttachmentsInterface *klass)
+{
+}
+
+gboolean
+ev_document_attachments_has_attachments (EvDocumentAttachments *document_attachments)
+{
+ EvDocumentAttachmentsInterface *iface = EV_DOCUMENT_ATTACHMENTS_GET_IFACE (document_attachments);
+
+ return iface->has_attachments (document_attachments);
+}
+
+GList *
+ev_document_attachments_get_attachments (EvDocumentAttachments *document_attachments)
+{
+ EvDocumentAttachmentsInterface *iface = EV_DOCUMENT_ATTACHMENTS_GET_IFACE (document_attachments);
+
+ return iface->get_attachments (document_attachments);
+}
+
+
diff --git a/libdocument/ev-document-attachments.h b/libdocument/ev-document-attachments.h
new file mode 100644
index 00000000..4b491495
--- /dev/null
+++ b/libdocument/ev-document-attachments.h
@@ -0,0 +1,59 @@
+/* ev-document-attachments.h
+ * this file is part of evince, a mate document viewer
+ *
+ * Copyright (C) 2009 Carlos Garcia Campos <[email protected]>
+ *
+ * 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.
+ */
+
+#if !defined (__EV_EVINCE_DOCUMENT_H_INSIDE__) && !defined (EVINCE_COMPILATION)
+#error "Only <evince-document.h> can be included directly."
+#endif
+
+#ifndef EV_DOCUMENT_ATTACHMENTS_H
+#define EV_DOCUMENT_ATTACHMENTS_H
+
+#include <glib-object.h>
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+#define EV_TYPE_DOCUMENT_ATTACHMENTS (ev_document_attachments_get_type ())
+#define EV_DOCUMENT_ATTACHMENTS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EV_TYPE_DOCUMENT_ATTACHMENTS, EvDocumentAttachments))
+#define EV_DOCUMENT_ATTACHMENTS_IFACE(k) (G_TYPE_CHECK_CLASS_CAST((k), EV_TYPE_DOCUMENT_ATTACHMENTS, EvDocumentAttachmentsInterface))
+#define EV_IS_DOCUMENT_ATTACHMENTS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EV_TYPE_DOCUMENT_ATTACHMENTS))
+#define EV_IS_DOCUMENT_ATTACHMENTS_IFACE(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EV_TYPE_DOCUMENT_ATTACHMENTS))
+#define EV_DOCUMENT_ATTACHMENTS_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), EV_TYPE_DOCUMENT_ATTACHMENTS, EvDocumentAttachmentsInterface))
+
+typedef struct _EvDocumentAttachments EvDocumentAttachments;
+typedef struct _EvDocumentAttachmentsInterface EvDocumentAttachmentsInterface;
+
+struct _EvDocumentAttachmentsInterface
+{
+ GTypeInterface base_iface;
+
+ /* Methods */
+ gboolean (* has_attachments) (EvDocumentAttachments *document_attachments);
+ GList *(* get_attachments) (EvDocumentAttachments *document_attachments);
+};
+
+GType ev_document_attachments_get_type (void) G_GNUC_CONST;
+
+gboolean ev_document_attachments_has_attachments (EvDocumentAttachments *document_attachments);
+GList *ev_document_attachments_get_attachments (EvDocumentAttachments *document_attachments);
+
+G_END_DECLS
+
+#endif /* EV_DOCUMENT_ATTACHMENTS_H */
diff --git a/libdocument/ev-document-factory.c b/libdocument/ev-document-factory.c
new file mode 100644
index 00000000..0ace5ec8
--- /dev/null
+++ b/libdocument/ev-document-factory.c
@@ -0,0 +1,397 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; c-indent-level: 8 -*- */
+/*
+ * Copyright (C) 2005, Red Hat, Inc.
+ *
+ * This program 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, or (at your option)
+ * any later version.
+ *
+ * This program 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.
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <string.h>
+
+#include <gio/gio.h>
+#include <glib/gstdio.h>
+#include <glib/gi18n-lib.h>
+#include <gtk/gtk.h>
+
+#include "ev-backends-manager.h"
+#include "ev-document-factory.h"
+#include "ev-file-helpers.h"
+
+#ifdef ENABLE_PIXBUF
+static GList*
+gdk_pixbuf_mime_type_list ()
+{
+ GSList *formats, *list;
+ GList *result = NULL;
+
+ formats = gdk_pixbuf_get_formats ();
+ for (list = formats; list != NULL; list = list->next) {
+ GdkPixbufFormat *format = list->data;
+ gchar **mime_types;
+
+ if (gdk_pixbuf_format_is_disabled (format))
+ continue;
+
+ mime_types = gdk_pixbuf_format_get_mime_types (format);
+ result = g_list_prepend (result, mime_types);
+ }
+ g_slist_free (formats);
+
+ return result;
+}
+
+/* Would be nice to have this in gdk-pixbuf */
+static gboolean
+mime_type_supported_by_gdk_pixbuf (const gchar *mime_type)
+{
+ GList *mime_types;
+ GList *list;
+ gboolean retval = FALSE;
+
+ mime_types = gdk_pixbuf_mime_type_list ();
+ for (list = mime_types; list; list = list->next) {
+ gchar **mtypes = (gchar **)list->data;
+ const gchar *mtype;
+ gint i = 0;
+
+ while ((mtype = mtypes[i++])) {
+ if (strcmp (mtype, mime_type) == 0) {
+ retval = TRUE;
+ break;
+ }
+ }
+ }
+
+ g_list_foreach (mime_types, (GFunc)g_strfreev, NULL);
+ g_list_free (mime_types);
+
+ return retval;
+}
+#endif /* ENABLE_PIXBUF */
+
+static EvCompressionType
+get_compression_from_mime_type (const gchar *mime_type)
+{
+ gchar type[3];
+ gchar *p;
+
+ if (!(p = g_strrstr (mime_type, "/")))
+ return EV_COMPRESSION_NONE;
+
+ if (sscanf (++p, "x-%2s%*s", type) == 1) {
+ if (g_ascii_strcasecmp (type, "gz") == 0)
+ return EV_COMPRESSION_GZIP;
+ else if (g_ascii_strcasecmp (type, "bz") == 0)
+ return EV_COMPRESSION_BZIP2;
+ }
+
+ return EV_COMPRESSION_NONE;
+}
+
+
+/*
+ * get_document_from_uri:
+ * @uri: the document URI
+ * @fast: whether to use fast MIME type detection
+ * @compression: a location to store the document's compression type
+ * @error: a #GError location to store an error, or %NULL
+ *
+ * Creates a #EvDocument instance for the document at @uri, using either
+ * fast or slow MIME type detection. If a document could be created,
+ * @compression is filled in with the document's compression type.
+ * On error, %NULL is returned and @error filled in.
+ *
+ * Returns: a new #EvDocument instance, or %NULL on error with @error filled in
+ */
+static EvDocument *
+get_document_from_uri (const char *uri,
+ gboolean fast,
+ EvCompressionType *compression,
+ GError **error)
+{
+ EvDocument *document = NULL;
+ gchar *mime_type = NULL;
+ GError *err = NULL;
+
+ *compression = EV_COMPRESSION_NONE;
+
+ mime_type = ev_file_get_mime_type (uri, fast, &err);
+
+ if (mime_type == NULL) {
+ g_free (mime_type);
+
+ if (err == NULL) {
+ g_set_error_literal (error,
+ EV_DOCUMENT_ERROR,
+ EV_DOCUMENT_ERROR_INVALID,
+ _("Unknown MIME Type"));
+ } else {
+ g_propagate_error (error, err);
+ }
+
+ return NULL;
+ }
+
+ document = ev_backends_manager_get_document (mime_type);
+
+#ifdef ENABLE_PIXBUF
+ if (!document && mime_type_supported_by_gdk_pixbuf (mime_type))
+ document = ev_backends_manager_get_document ("image/*");
+#endif /* ENABLE_PIXBUF */
+
+ if (document == NULL) {
+ gchar *content_type, *mime_desc = NULL;
+
+ content_type = g_content_type_from_mime_type (mime_type);
+ if (content_type)
+ mime_desc = g_content_type_get_description (content_type);
+
+ g_set_error (error,
+ EV_DOCUMENT_ERROR,
+ EV_DOCUMENT_ERROR_INVALID,
+ _("File type %s (%s) is not supported"),
+ mime_desc ? mime_desc : "-", mime_type);
+ g_free (mime_desc);
+ g_free (content_type);
+ g_free (mime_type);
+
+ return NULL;
+ }
+
+ *compression = get_compression_from_mime_type (mime_type);
+
+ g_free (mime_type);
+
+ return document;
+}
+
+static void
+free_uncompressed_uri (gchar *uri_unc)
+{
+ if (!uri_unc)
+ return;
+
+ ev_tmp_uri_unlink (uri_unc);
+ g_free (uri_unc);
+}
+
+/**
+ * ev_document_factory_get_document:
+ * @uri: an URI
+ * @error: a #GError location to store an error, or %NULL
+ *
+ * Creates a #EvDocument for the document at @uri; or, if no backend handling
+ * the document's type is found, or an error occurred on opening the document,
+ * returns %NULL and fills in @error.
+ * If the document is encrypted, it is returned but also @error is set to
+ * %EV_DOCUMENT_ERROR_ENCRYPTED.
+ *
+ * Returns: a new #EvDocument, or %NULL.
+ */
+EvDocument *
+ev_document_factory_get_document (const char *uri, GError **error)
+{
+ EvDocument *document;
+ int result;
+ EvCompressionType compression;
+ gchar *uri_unc = NULL;
+ GError *err = NULL;
+
+ g_return_val_if_fail (uri != NULL, NULL);
+
+ document = get_document_from_uri (uri, TRUE, &compression, &err);
+ g_assert (document != NULL || err != NULL);
+
+ if (document != NULL) {
+ uri_unc = ev_file_uncompress (uri, compression, &err);
+ if (uri_unc) {
+ g_object_set_data_full (G_OBJECT (document),
+ "uri-uncompressed",
+ uri_unc,
+ (GDestroyNotify) free_uncompressed_uri);
+ } else if (err != NULL) {
+ /* Error uncompressing file */
+ g_object_unref (document);
+ g_propagate_error (error, err);
+ return NULL;
+ }
+
+ result = ev_document_load (document, uri_unc ? uri_unc : uri, &err);
+
+ if (result == FALSE || err) {
+ if (err &&
+ g_error_matches (err, EV_DOCUMENT_ERROR, EV_DOCUMENT_ERROR_ENCRYPTED)) {
+ g_propagate_error (error, err);
+ return document;
+ }
+ /* else fall through to slow mime code section below */
+ } else {
+ return document;
+ }
+
+ g_object_unref (document);
+ document = NULL;
+ }
+
+ /* Try again with slow mime detection */
+ g_clear_error (&err);
+ uri_unc = NULL;
+
+ document = get_document_from_uri (uri, FALSE, &compression, &err);
+ if (document == NULL) {
+ g_assert (err != NULL);
+ g_propagate_error (error, err);
+ return NULL;
+ }
+
+ uri_unc = ev_file_uncompress (uri, compression, &err);
+ if (uri_unc) {
+ g_object_set_data_full (G_OBJECT (document),
+ "uri-uncompressed",
+ uri_unc,
+ (GDestroyNotify) free_uncompressed_uri);
+ } else if (err != NULL) {
+ /* Error uncompressing file */
+ g_propagate_error (error, err);
+
+ g_object_unref (document);
+ return NULL;
+ }
+
+ result = ev_document_load (document, uri_unc ? uri_unc : uri, &err);
+ if (result == FALSE) {
+ if (err == NULL) {
+ /* FIXME: this really should not happen; the backend should
+ * always return a meaningful error.
+ */
+ g_set_error_literal (&err,
+ EV_DOCUMENT_ERROR,
+ EV_DOCUMENT_ERROR_INVALID,
+ _("Unknown MIME Type"));
+ } else if (g_error_matches (err, EV_DOCUMENT_ERROR, EV_DOCUMENT_ERROR_ENCRYPTED)) {
+ g_propagate_error (error, err);
+ return document;
+ }
+
+ g_object_unref (document);
+ document = NULL;
+
+ g_propagate_error (error, err);
+ }
+
+ return document;
+}
+
+static void
+file_filter_add_mime_types (EvTypeInfo *info, GtkFileFilter *filter)
+{
+ const gchar *mime_type;
+ gint i = 0;
+
+#ifdef ENABLE_PIXBUF
+ if (g_ascii_strcasecmp (info->mime_types[0], "image/*") == 0) {
+ GList *pixbuf_types, *l;
+
+ pixbuf_types = gdk_pixbuf_mime_type_list ();
+ for (l = pixbuf_types; l; l = g_list_next (l)) {
+ gchar **mime_types = (gchar **)l->data;
+ gint j = 0;
+
+ while ((mime_type = mime_types[j++]))
+ gtk_file_filter_add_mime_type (filter, mime_type);
+
+ g_strfreev (mime_types);
+ }
+ g_list_free (pixbuf_types);
+
+ return;
+ }
+#endif /* ENABLE_PIXBUF */
+
+ while ((mime_type = info->mime_types[i++]))
+ gtk_file_filter_add_mime_type (filter, mime_type);
+}
+
+/**
+ * ev_document_factory_add_filters:
+ * @chooser: a #GtkFileChooser
+ * @document: a #EvDocument, or %NULL
+ *
+ * Adds some file filters to @chooser.
+
+ * Always add a "All documents" format.
+ *
+ * If @document is not %NULL, adds a #GtkFileFilter for @document's MIME type.
+ *
+ * If @document is %NULL, adds a #GtkFileFilter for each document type that evince
+ * can handle.
+ */
+void
+ev_document_factory_add_filters (GtkWidget *chooser, EvDocument *document)
+{
+ GList *all_types;
+ GtkFileFilter *filter;
+ GtkFileFilter *default_filter;
+ GtkFileFilter *document_filter;
+
+ g_return_if_fail (GTK_IS_FILE_CHOOSER (chooser));
+ g_return_if_fail (document == NULL || EV_IS_DOCUMENT (document));
+
+ all_types = ev_backends_manager_get_all_types_info ();
+
+ default_filter = document_filter = filter = gtk_file_filter_new ();
+ gtk_file_filter_set_name (filter, _("All Documents"));
+ g_list_foreach (all_types, (GFunc)file_filter_add_mime_types, filter);
+ gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (chooser), filter);
+
+ if (document) {
+ EvTypeInfo *info;
+
+ info = ev_backends_manager_get_document_type_info (document);
+ default_filter = filter = gtk_file_filter_new ();
+ gtk_file_filter_set_name (filter, info->desc);
+ file_filter_add_mime_types (info, filter);
+ g_free (info);
+ gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (chooser), filter);
+ } else {
+ GList *l;
+
+ for (l = all_types; l; l = g_list_next (l)){
+ EvTypeInfo *info;
+
+ info = (EvTypeInfo *)l->data;
+
+ default_filter = filter = gtk_file_filter_new ();
+ gtk_file_filter_set_name (filter, info->desc);
+ file_filter_add_mime_types (info, filter);
+ gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (chooser), filter);
+ }
+ }
+
+ g_list_foreach (all_types, (GFunc)g_free, NULL);
+ g_list_free (all_types);
+
+ filter = gtk_file_filter_new ();
+ gtk_file_filter_set_name (filter, _("All Files"));
+ gtk_file_filter_add_pattern (filter, "*");
+ gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (chooser), filter);
+
+ gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (chooser),
+ document == NULL ? document_filter : default_filter);
+}
diff --git a/libdocument/ev-document-factory.h b/libdocument/ev-document-factory.h
new file mode 100644
index 00000000..501eb2f3
--- /dev/null
+++ b/libdocument/ev-document-factory.h
@@ -0,0 +1,39 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; c-indent-level: 8 -*- */
+/*
+ * Copyright (C) 2005, Red Hat, Inc.
+ *
+ * This program 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, or (at your option)
+ * any later version.
+ *
+ * This program 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.
+ *
+ */
+
+#if !defined (__EV_EVINCE_DOCUMENT_H_INSIDE__) && !defined (EVINCE_COMPILATION)
+#error "Only <evince-document.h> can be included directly."
+#endif
+
+#ifndef EV_DOCUMENT_FACTORY_H
+#define EV_DOCUMENT_FACTORY_H
+
+#include <gtk/gtk.h>
+
+#include "ev-document.h"
+
+G_BEGIN_DECLS
+
+EvDocument* ev_document_factory_get_document (const char *uri, GError **error);
+void ev_document_factory_add_filters (GtkWidget *chooser, EvDocument *document);
+
+G_END_DECLS
+
+#endif
diff --git a/libdocument/ev-document-find.c b/libdocument/ev-document-find.c
new file mode 100644
index 00000000..0b5fac01
--- /dev/null
+++ b/libdocument/ev-document-find.c
@@ -0,0 +1,42 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; c-indent-level: 8 -*- */
+/*
+ * Copyright (C) 2004 Red Hat, Inc.
+ *
+ * This program 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, or (at your option)
+ * any later version.
+ *
+ * This program 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-find.h"
+
+G_DEFINE_INTERFACE (EvDocumentFind, ev_document_find, 0)
+
+static void
+ev_document_find_default_init (EvDocumentFindInterface *klass)
+{
+}
+
+GList *
+ev_document_find_find_text (EvDocumentFind *document_find,
+ EvPage *page,
+ const gchar *text,
+ gboolean case_sensitive)
+{
+ EvDocumentFindInterface *iface = EV_DOCUMENT_FIND_GET_IFACE (document_find);
+
+ return iface->find_text (document_find, page, text, case_sensitive);
+}
+
diff --git a/libdocument/ev-document-find.h b/libdocument/ev-document-find.h
new file mode 100644
index 00000000..dcc3438e
--- /dev/null
+++ b/libdocument/ev-document-find.h
@@ -0,0 +1,65 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; c-indent-level: 8 -*- */
+/*
+ * Copyright (C) 2004 Red Hat, Inc.
+ *
+ * This program 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, or (at your option)
+ * any later version.
+ *
+ * This program 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.
+ *
+ * $Id$
+ */
+
+#if !defined (__EV_EVINCE_DOCUMENT_H_INSIDE__) && !defined (EVINCE_COMPILATION)
+#error "Only <evince-document.h> can be included directly."
+#endif
+
+#ifndef EV_DOCUMENT_FIND_H
+#define EV_DOCUMENT_FIND_H
+
+#include <glib-object.h>
+#include <glib.h>
+
+#include "ev-document.h"
+
+G_BEGIN_DECLS
+
+#define EV_TYPE_DOCUMENT_FIND (ev_document_find_get_type ())
+#define EV_DOCUMENT_FIND(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EV_TYPE_DOCUMENT_FIND, EvDocumentFind))
+#define EV_DOCUMENT_FIND_IFACE(k) (G_TYPE_CHECK_CLASS_CAST((k), EV_TYPE_DOCUMENT_FIND, EvDocumentFindInterface))
+#define EV_IS_DOCUMENT_FIND(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EV_TYPE_DOCUMENT_FIND))
+#define EV_IS_DOCUMENT_FIND_IFACE(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EV_TYPE_DOCUMENT_FIND))
+#define EV_DOCUMENT_FIND_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), EV_TYPE_DOCUMENT_FIND, EvDocumentFindInterface))
+
+typedef struct _EvDocumentFind EvDocumentFind;
+typedef struct _EvDocumentFindInterface EvDocumentFindInterface;
+
+struct _EvDocumentFindInterface
+{
+ GTypeInterface base_iface;
+
+ /* Methods */
+ GList *(* find_text) (EvDocumentFind *document_find,
+ EvPage *page,
+ const gchar *text,
+ gboolean case_sensitive);
+};
+
+GType ev_document_find_get_type (void) G_GNUC_CONST;
+GList *ev_document_find_find_text (EvDocumentFind *document_find,
+ EvPage *page,
+ const gchar *text,
+ gboolean case_sensitive);
+
+G_END_DECLS
+
+#endif /* EV_DOCUMENT_FIND_H */
diff --git a/libdocument/ev-document-fonts.c b/libdocument/ev-document-fonts.c
new file mode 100644
index 00000000..ca019055
--- /dev/null
+++ b/libdocument/ev-document-fonts.c
@@ -0,0 +1,59 @@
+/* ev-document-fonts.h
+ * this file is part of evince, a mate document_fonts viewer
+ *
+ * Copyright (C) 2004 Red Hat, Inc.
+ *
+ * Author:
+ * Marco Pesenti Gritti <[email protected]>
+ *
+ * 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-fonts.h"
+
+G_DEFINE_INTERFACE (EvDocumentFonts, ev_document_fonts, 0)
+
+static void
+ev_document_fonts_default_init (EvDocumentFontsInterface *klass)
+{
+}
+
+double
+ev_document_fonts_get_progress (EvDocumentFonts *document_fonts)
+{
+ EvDocumentFontsInterface *iface = EV_DOCUMENT_FONTS_GET_IFACE (document_fonts);
+
+ return iface->get_progress (document_fonts);
+}
+
+gboolean
+ev_document_fonts_scan (EvDocumentFonts *document_fonts,
+ int n_pages)
+{
+ EvDocumentFontsInterface *iface = EV_DOCUMENT_FONTS_GET_IFACE (document_fonts);
+
+ return iface->scan (document_fonts, n_pages);
+}
+
+void
+ev_document_fonts_fill_model (EvDocumentFonts *document_fonts,
+ GtkTreeModel *model)
+{
+ EvDocumentFontsInterface *iface = EV_DOCUMENT_FONTS_GET_IFACE (document_fonts);
+
+ iface->fill_model (document_fonts, model);
+}
diff --git a/libdocument/ev-document-fonts.h b/libdocument/ev-document-fonts.h
new file mode 100644
index 00000000..81401c00
--- /dev/null
+++ b/libdocument/ev-document-fonts.h
@@ -0,0 +1,78 @@
+/* ev-document-fonts.h
+ * this file is part of evince, a mate document viewer
+ *
+ * Copyright (C) 2004 Red Hat, Inc.
+ *
+ * Author:
+ * Marco Pesenti Gritti <[email protected]>
+ *
+ * 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.
+ */
+
+#if !defined (__EV_EVINCE_DOCUMENT_H_INSIDE__) && !defined (EVINCE_COMPILATION)
+#error "Only <evince-document.h> can be included directly."
+#endif
+
+#ifndef EV_DOCUMENT_FONTS_H
+#define EV_DOCUMENT_FONTS_H
+
+#include <glib-object.h>
+#include <glib.h>
+#include <gtk/gtk.h>
+
+#include "ev-document.h"
+#include "ev-link.h"
+
+G_BEGIN_DECLS
+
+
+#define EV_TYPE_DOCUMENT_FONTS (ev_document_fonts_get_type ())
+#define EV_DOCUMENT_FONTS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EV_TYPE_DOCUMENT_FONTS, EvDocumentFonts))
+#define EV_DOCUMENT_FONTS_IFACE(k) (G_TYPE_CHECK_CLASS_CAST((k), EV_TYPE_DOCUMENT_FONTS, EvDocumentFontsInterface))
+#define EV_IS_DOCUMENT_FONTS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EV_TYPE_DOCUMENT_FONTS))
+#define EV_IS_DOCUMENT_FONTS_IFACE(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EV_TYPE_DOCUMENT_FONTS))
+#define EV_DOCUMENT_FONTS_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), EV_TYPE_DOCUMENT_FONTS, EvDocumentFontsInterface))
+
+typedef struct _EvDocumentFonts EvDocumentFonts;
+typedef struct _EvDocumentFontsInterface EvDocumentFontsInterface;
+
+enum {
+ EV_DOCUMENT_FONTS_COLUMN_NAME,
+ EV_DOCUMENT_FONTS_COLUMN_DETAILS,
+ EV_DOCUMENT_FONTS_COLUMN_NUM_COLUMNS
+};
+
+struct _EvDocumentFontsInterface
+{
+ GTypeInterface base_iface;
+
+ /* Methods */
+ gboolean (* scan) (EvDocumentFonts *document_fonts,
+ int n_pages);
+ double (* get_progress) (EvDocumentFonts *document_fonts);
+ void (* fill_model) (EvDocumentFonts *document_fonts,
+ GtkTreeModel *model);
+};
+
+GType ev_document_fonts_get_type (void);
+gboolean ev_document_fonts_scan (EvDocumentFonts *document_fonts,
+ int n_pages);
+double ev_document_fonts_get_progress (EvDocumentFonts *document_fonts);
+void ev_document_fonts_fill_model (EvDocumentFonts *document_fonts,
+ GtkTreeModel *model);
+
+G_END_DECLS
+
+#endif
diff --git a/libdocument/ev-document-forms.c b/libdocument/ev-document-forms.c
new file mode 100644
index 00000000..809cefb1
--- /dev/null
+++ b/libdocument/ev-document-forms.c
@@ -0,0 +1,161 @@
+/* ev-document-forms.c
+ * this file is part of evince, a mate document viewer
+ *
+ * Copyright (C) 2007 Carlos Garcia Campos <[email protected]>
+ *
+ * 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-forms.h"
+
+G_DEFINE_INTERFACE (EvDocumentForms, ev_document_forms, 0)
+
+static void
+ev_document_forms_default_init (EvDocumentFormsInterface *klass)
+{
+}
+
+EvMappingList *
+ev_document_forms_get_form_fields (EvDocumentForms *document_forms,
+ EvPage *page)
+{
+ EvDocumentFormsInterface *iface = EV_DOCUMENT_FORMS_GET_IFACE (document_forms);
+
+ return iface->get_form_fields (document_forms, page);
+}
+
+gboolean
+ev_document_forms_document_is_modified (EvDocumentForms *document_forms)
+{
+ EvDocumentFormsInterface *iface = EV_DOCUMENT_FORMS_GET_IFACE (document_forms);
+
+ return (iface->document_is_modified) ? iface->document_is_modified (document_forms) : FALSE;
+}
+
+gchar *
+ev_document_forms_form_field_text_get_text (EvDocumentForms *document_forms,
+ EvFormField *field)
+{
+ EvDocumentFormsInterface *iface = EV_DOCUMENT_FORMS_GET_IFACE (document_forms);
+
+ return iface->form_field_text_get_text (document_forms, field);
+}
+
+void
+ev_document_forms_form_field_text_set_text (EvDocumentForms *document_forms,
+ EvFormField *field,
+ const gchar *text)
+{
+ EvDocumentFormsInterface *iface = EV_DOCUMENT_FORMS_GET_IFACE (document_forms);
+
+ iface->form_field_text_set_text (document_forms, field, text);
+}
+
+gboolean
+ev_document_forms_form_field_button_get_state (EvDocumentForms *document_forms,
+ EvFormField *field)
+{
+ EvDocumentFormsInterface *iface = EV_DOCUMENT_FORMS_GET_IFACE (document_forms);
+
+ return iface->form_field_button_get_state (document_forms, field);
+}
+
+void
+ev_document_forms_form_field_button_set_state (EvDocumentForms *document_forms,
+ EvFormField *field,
+ gboolean state)
+{
+ EvDocumentFormsInterface *iface = EV_DOCUMENT_FORMS_GET_IFACE (document_forms);
+
+ iface->form_field_button_set_state (document_forms, field, state);
+}
+
+gchar *
+ev_document_forms_form_field_choice_get_item (EvDocumentForms *document_forms,
+ EvFormField *field,
+ gint index)
+{
+ EvDocumentFormsInterface *iface = EV_DOCUMENT_FORMS_GET_IFACE (document_forms);
+
+ return iface->form_field_choice_get_item (document_forms, field, index);
+}
+
+gint
+ev_document_forms_form_field_choice_get_n_items (EvDocumentForms *document_forms,
+ EvFormField *field)
+{
+ EvDocumentFormsInterface *iface = EV_DOCUMENT_FORMS_GET_IFACE (document_forms);
+
+ return iface->form_field_choice_get_n_items (document_forms, field);
+}
+
+gboolean
+ev_document_forms_form_field_choice_is_item_selected (EvDocumentForms *document_forms,
+ EvFormField *field,
+ gint index)
+{
+ EvDocumentFormsInterface *iface = EV_DOCUMENT_FORMS_GET_IFACE (document_forms);
+
+ return iface->form_field_choice_is_item_selected (document_forms, field, index);
+}
+
+void
+ev_document_forms_form_field_choice_select_item (EvDocumentForms *document_forms,
+ EvFormField *field,
+ gint index)
+{
+ EvDocumentFormsInterface *iface = EV_DOCUMENT_FORMS_GET_IFACE (document_forms);
+
+ iface->form_field_choice_select_item (document_forms, field, index);
+}
+
+void
+ev_document_forms_form_field_choice_toggle_item (EvDocumentForms *document_forms,
+ EvFormField *field,
+ gint index)
+{
+ EvDocumentFormsInterface *iface = EV_DOCUMENT_FORMS_GET_IFACE (document_forms);
+
+ iface->form_field_choice_toggle_item (document_forms, field, index);
+}
+
+void
+ev_document_forms_form_field_choice_unselect_all (EvDocumentForms *document_forms,
+ EvFormField *field)
+{
+ EvDocumentFormsInterface *iface = EV_DOCUMENT_FORMS_GET_IFACE (document_forms);
+
+ iface->form_field_choice_unselect_all (document_forms, field);
+}
+
+void
+ev_document_forms_form_field_choice_set_text (EvDocumentForms *document_forms,
+ EvFormField *field,
+ const gchar *text)
+{
+ EvDocumentFormsInterface *iface = EV_DOCUMENT_FORMS_GET_IFACE (document_forms);
+
+ iface->form_field_choice_set_text (document_forms, field, text);
+}
+
+gchar *
+ev_document_forms_form_field_choice_get_text (EvDocumentForms *document_forms,
+ EvFormField *field)
+{
+ EvDocumentFormsInterface *iface = EV_DOCUMENT_FORMS_GET_IFACE (document_forms);
+
+ return iface->form_field_choice_get_text (document_forms, field);
+}
diff --git a/libdocument/ev-document-forms.h b/libdocument/ev-document-forms.h
new file mode 100644
index 00000000..c47ff3f4
--- /dev/null
+++ b/libdocument/ev-document-forms.h
@@ -0,0 +1,128 @@
+/* ev-document-forms.h
+ * this file is part of evince, a mate document viewer
+ *
+ * Copyright (C) 2007 Carlos Garcia Campos <[email protected]>
+ *
+ * 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.
+ */
+
+#if !defined (__EV_EVINCE_DOCUMENT_H_INSIDE__) && !defined (EVINCE_COMPILATION)
+#error "Only <evince-document.h> can be included directly."
+#endif
+
+#ifndef EV_DOCUMENT_FORMS_H
+#define EV_DOCUMENT_FORMS_H
+
+#include <glib-object.h>
+
+#include "ev-document.h"
+#include "ev-form-field.h"
+#include "ev-mapping-list.h"
+
+G_BEGIN_DECLS
+
+#define EV_TYPE_DOCUMENT_FORMS (ev_document_forms_get_type ())
+#define EV_DOCUMENT_FORMS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EV_TYPE_DOCUMENT_FORMS, EvDocumentForms))
+#define EV_DOCUMENT_FORMS_IFACE(k) (G_TYPE_CHECK_CLASS_CAST((k), EV_TYPE_DOCUMENT_FORMS, EvDocumentFormsInterface))
+#define EV_IS_DOCUMENT_FORMS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EV_TYPE_DOCUMENT_FORMS))
+#define EV_IS_DOCUMENT_FORMS_IFACE(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EV_TYPE_DOCUMENT_FORMS))
+#define EV_DOCUMENT_FORMS_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), EV_TYPE_DOCUMENT_FORMS, EvDocumentFormsInterface))
+
+typedef struct _EvDocumentForms EvDocumentForms;
+typedef struct _EvDocumentFormsInterface EvDocumentFormsInterface;
+
+struct _EvDocumentFormsInterface
+{
+ GTypeInterface base_iface;
+
+ /* Methods */
+ EvMappingList *(* get_form_fields) (EvDocumentForms *document_forms,
+ EvPage *page);
+ gboolean (* document_is_modified) (EvDocumentForms *document_forms);
+ gchar *(* form_field_text_get_text) (EvDocumentForms *document_forms,
+ EvFormField *field);
+ void (* form_field_text_set_text) (EvDocumentForms *document_forms,
+ EvFormField *field,
+ const gchar *text);
+ gboolean (* form_field_button_get_state) (EvDocumentForms *document_forms,
+ EvFormField *field);
+ void (* form_field_button_set_state) (EvDocumentForms *document_forms,
+ EvFormField *field,
+ gboolean state);
+ gchar *(* form_field_choice_get_item) (EvDocumentForms *document_forms,
+ EvFormField *field,
+ gint index);
+ gint (* form_field_choice_get_n_items) (EvDocumentForms *document_forms,
+ EvFormField *field);
+ gboolean (* form_field_choice_is_item_selected) (EvDocumentForms *document_forms,
+ EvFormField *field,
+ gint index);
+ void (* form_field_choice_select_item) (EvDocumentForms *document_forms,
+ EvFormField *field,
+ gint index);
+ void (* form_field_choice_toggle_item) (EvDocumentForms *document_forms,
+ EvFormField *field,
+ gint index);
+ void (* form_field_choice_unselect_all) (EvDocumentForms *document_forms,
+ EvFormField *field);
+ void (* form_field_choice_set_text) (EvDocumentForms *document_forms,
+ EvFormField *field,
+ const gchar *text);
+ gchar *(* form_field_choice_get_text) (EvDocumentForms *document_forms,
+ EvFormField *field);
+};
+
+GType ev_document_forms_get_type (void) G_GNUC_CONST;
+EvMappingList *ev_document_forms_get_form_fields (EvDocumentForms *document_forms,
+ EvPage *page);
+gboolean ev_document_forms_document_is_modified (EvDocumentForms *document_forms);
+
+gchar *ev_document_forms_form_field_text_get_text (EvDocumentForms *document_forms,
+ EvFormField *field);
+void ev_document_forms_form_field_text_set_text (EvDocumentForms *document_forms,
+ EvFormField *field,
+ const gchar *text);
+
+gboolean ev_document_forms_form_field_button_get_state (EvDocumentForms *document_forms,
+ EvFormField *field);
+void ev_document_forms_form_field_button_set_state (EvDocumentForms *document_forms,
+ EvFormField *field,
+ gboolean state);
+
+gchar *ev_document_forms_form_field_choice_get_item (EvDocumentForms *document_forms,
+ EvFormField *field,
+ gint index);
+gint ev_document_forms_form_field_choice_get_n_items (EvDocumentForms *document_forms,
+ EvFormField *field);
+gboolean ev_document_forms_form_field_choice_is_item_selected (EvDocumentForms *document_forms,
+ EvFormField *field,
+ gint index);
+void ev_document_forms_form_field_choice_select_item (EvDocumentForms *document_forms,
+ EvFormField *field,
+ gint index);
+void ev_document_forms_form_field_choice_toggle_item (EvDocumentForms *document_forms,
+ EvFormField *field,
+ gint index);
+void ev_document_forms_form_field_choice_unselect_all (EvDocumentForms *document_forms,
+ EvFormField *field);
+void ev_document_forms_form_field_choice_set_text (EvDocumentForms *document_forms,
+ EvFormField *field,
+ const gchar *text);
+gchar *ev_document_forms_form_field_choice_get_text (EvDocumentForms *document_forms,
+ EvFormField *field);
+
+G_END_DECLS
+
+#endif /* EV_DOCUMENT_FORMS_H */
diff --git a/libdocument/ev-document-images.c b/libdocument/ev-document-images.c
new file mode 100644
index 00000000..09bf5dae
--- /dev/null
+++ b/libdocument/ev-document-images.c
@@ -0,0 +1,47 @@
+/* ev-document-images.c
+ * this file is part of evince, a mate document_links viewer
+ *
+ * Copyright (C) 2006 Carlos Garcia Campos <[email protected]>
+ *
+ * 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-images.h"
+
+G_DEFINE_INTERFACE (EvDocumentImages, ev_document_images, 0)
+
+static void
+ev_document_images_default_init (EvDocumentImagesInterface *klass)
+{
+}
+
+EvMappingList *
+ev_document_images_get_image_mapping (EvDocumentImages *document_images,
+ EvPage *page)
+{
+ EvDocumentImagesInterface *iface = EV_DOCUMENT_IMAGES_GET_IFACE (document_images);
+
+ return iface->get_image_mapping (document_images, page);
+}
+
+GdkPixbuf *
+ev_document_images_get_image (EvDocumentImages *document_images,
+ EvImage *image)
+{
+ EvDocumentImagesInterface *iface = EV_DOCUMENT_IMAGES_GET_IFACE (document_images);
+
+ return iface->get_image (document_images, image);
+}
diff --git a/libdocument/ev-document-images.h b/libdocument/ev-document-images.h
new file mode 100644
index 00000000..18fac92a
--- /dev/null
+++ b/libdocument/ev-document-images.h
@@ -0,0 +1,65 @@
+/* ev-document-images.h
+ * this file is part of evince, a mate document viewer
+ *
+ * Copyright (C) 2006 Carlos Garcia Campos <[email protected]>
+ *
+ * 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.
+ */
+
+#if !defined (__EV_EVINCE_DOCUMENT_H_INSIDE__) && !defined (EVINCE_COMPILATION)
+#error "Only <evince-document.h> can be included directly."
+#endif
+
+#ifndef EV_DOCUMENT_IMAGES_H
+#define EV_DOCUMENT_IMAGES_H
+
+#include <glib-object.h>
+#include <glib.h>
+
+#include "ev-document.h"
+#include "ev-image.h"
+#include "ev-mapping-list.h"
+
+G_BEGIN_DECLS
+
+#define EV_TYPE_DOCUMENT_IMAGES (ev_document_images_get_type ())
+#define EV_DOCUMENT_IMAGES(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EV_TYPE_DOCUMENT_IMAGES, EvDocumentImages))
+#define EV_DOCUMENT_IMAGES_IFACE(k) (G_TYPE_CHECK_CLASS_CAST((k), EV_TYPE_DOCUMENT_IMAGES, EvDocumentImagesInterface))
+#define EV_IS_DOCUMENT_IMAGES(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EV_TYPE_DOCUMENT_IMAGES))
+#define EV_IS_DOCUMENT_IMAGES_IFACE(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EV_TYPE_DOCUMENT_IMAGES))
+#define EV_DOCUMENT_IMAGES_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), EV_TYPE_DOCUMENT_IMAGES, EvDocumentImagesInterface))
+
+typedef struct _EvDocumentImages EvDocumentImages;
+typedef struct _EvDocumentImagesInterface EvDocumentImagesInterface;
+
+struct _EvDocumentImagesInterface {
+ GTypeInterface base_iface;
+
+ /* Methods */
+ EvMappingList *(* get_image_mapping) (EvDocumentImages *document_images,
+ EvPage *page);
+ GdkPixbuf *(* get_image) (EvDocumentImages *document_images,
+ EvImage *image);
+};
+
+GType ev_document_images_get_type (void) G_GNUC_CONST;
+EvMappingList *ev_document_images_get_image_mapping (EvDocumentImages *document_images,
+ EvPage *page);
+GdkPixbuf *ev_document_images_get_image (EvDocumentImages *document_images,
+ EvImage *image);
+
+G_END_DECLS
+
+#endif /* EV_DOCUMENT_IMAGES_H */
diff --git a/libdocument/ev-document-info.h b/libdocument/ev-document-info.h
new file mode 100644
index 00000000..0f55d212
--- /dev/null
+++ b/libdocument/ev-document-info.h
@@ -0,0 +1,154 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; c-indent-level: 8 -*- */
+/*
+ * Copyright (C) 2000-2003 Marco Pesenti Gritti
+ *
+ * This program 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, or (at your option)
+ * any later version.
+ *
+ * This program 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.
+ *
+ */
+
+#if !defined (__EV_EVINCE_DOCUMENT_H_INSIDE__) && !defined (EVINCE_COMPILATION)
+#error "Only <evince-document.h> can be included directly."
+#endif
+
+#ifndef EV_DOCUMENT_INFO_H
+#define EV_DOCUMENT_INFO_H
+
+#include <glib-object.h>
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+typedef struct _EvDocumentInfo EvDocumentInfo;
+typedef struct _EvDocumentLicense EvDocumentLicense;
+
+#define EV_TYPE_DOCUMENT_INFO (ev_document_info_get_type())
+
+typedef enum
+{
+ EV_DOCUMENT_LAYOUT_SINGLE_PAGE,
+ EV_DOCUMENT_LAYOUT_ONE_COLUMN,
+ EV_DOCUMENT_LAYOUT_TWO_COLUMN_LEFT,
+ EV_DOCUMENT_LAYOUT_TWO_COLUMN_RIGHT,
+ EV_DOCUMENT_LAYOUT_TWO_PAGE_LEFT,
+ EV_DOCUMENT_LAYOUT_TWO_PAGE_RIGHT
+} EvDocumentLayout;
+
+typedef enum
+{
+ EV_DOCUMENT_MODE_NONE,
+ EV_DOCUMENT_MODE_USE_OC,
+ EV_DOCUMENT_MODE_USE_THUMBS,
+ EV_DOCUMENT_MODE_FULL_SCREEN,
+ EV_DOCUMENT_MODE_USE_ATTACHMENTS,
+ EV_DOCUMENT_MODE_PRESENTATION = EV_DOCUMENT_MODE_FULL_SCREEN /* Will these be different? */
+} EvDocumentMode;
+
+typedef enum
+{
+ EV_DOCUMENT_UI_HINT_HIDE_TOOLBAR = 1 << 0,
+ EV_DOCUMENT_UI_HINT_HIDE_MENUBAR = 1 << 1,
+ EV_DOCUMENT_UI_HINT_HIDE_WINDOWUI = 1 << 2,
+ EV_DOCUMENT_UI_HINT_FIT_WINDOW = 1 << 3,
+ EV_DOCUMENT_UI_HINT_CENTER_WINDOW = 1 << 4,
+ EV_DOCUMENT_UI_HINT_DISPLAY_DOC_TITLE = 1 << 5,
+ EV_DOCUMENT_UI_HINT_DIRECTION_RTL = 1 << 6
+} EvDocumentUIHints;
+
+/* This define is needed because glib-mkenums chokes with multiple lines */
+#define PERMISSIONS_FULL (EV_DOCUMENT_PERMISSIONS_OK_TO_PRINT \
+ | EV_DOCUMENT_PERMISSIONS_OK_TO_MODIFY \
+ | EV_DOCUMENT_PERMISSIONS_OK_TO_COPY \
+ | EV_DOCUMENT_PERMISSIONS_OK_TO_ADD_NOTES)
+
+typedef enum
+{
+ EV_DOCUMENT_PERMISSIONS_OK_TO_PRINT = 1 << 0,
+ EV_DOCUMENT_PERMISSIONS_OK_TO_MODIFY = 1 << 1,
+ EV_DOCUMENT_PERMISSIONS_OK_TO_COPY = 1 << 2,
+ EV_DOCUMENT_PERMISSIONS_OK_TO_ADD_NOTES = 1 << 3,
+ EV_DOCUMENT_PERMISSIONS_FULL = PERMISSIONS_FULL
+} EvDocumentPermissions;
+
+typedef enum
+{
+ EV_DOCUMENT_INFO_TITLE = 1 << 0,
+ EV_DOCUMENT_INFO_FORMAT = 1 << 1,
+ EV_DOCUMENT_INFO_AUTHOR = 1 << 2,
+ EV_DOCUMENT_INFO_SUBJECT = 1 << 3,
+ EV_DOCUMENT_INFO_KEYWORDS = 1 << 4,
+ EV_DOCUMENT_INFO_LAYOUT = 1 << 5,
+ EV_DOCUMENT_INFO_CREATOR = 1 << 6,
+ EV_DOCUMENT_INFO_PRODUCER = 1 << 7,
+ EV_DOCUMENT_INFO_CREATION_DATE = 1 << 8,
+ EV_DOCUMENT_INFO_MOD_DATE = 1 << 9,
+ EV_DOCUMENT_INFO_LINEARIZED = 1 << 10,
+ EV_DOCUMENT_INFO_START_MODE = 1 << 11,
+ EV_DOCUMENT_INFO_UI_HINTS = 1 << 12,
+ EV_DOCUMENT_INFO_PERMISSIONS = 1 << 13,
+ EV_DOCUMENT_INFO_N_PAGES = 1 << 14,
+ EV_DOCUMENT_INFO_SECURITY = 1 << 15,
+ EV_DOCUMENT_INFO_PAPER_SIZE = 1 << 16,
+ EV_DOCUMENT_INFO_LICENSE = 1 << 17,
+
+} EvDocumentInfoFields;
+
+struct _EvDocumentInfo
+{
+ char *title;
+ char *format; /* eg, "pdf-1.5" */
+ char *author;
+ char *subject;
+ char *keywords;
+ char *creator;
+ char *producer;
+ char *linearized;
+ char *security;
+ GTime creation_date;
+ GTime modified_date;
+ EvDocumentLayout layout;
+ EvDocumentMode mode;
+ guint ui_hints;
+ guint permissions;
+ int n_pages;
+ double paper_height;
+ double paper_width;
+ EvDocumentLicense *license;
+
+ /* Mask of all the valid fields */
+ guint fields_mask;
+};
+
+GType ev_document_info_get_type (void) G_GNUC_CONST;
+EvDocumentInfo *ev_document_info_copy (EvDocumentInfo *info);
+void ev_document_info_free (EvDocumentInfo *info);
+
+/* EvDocumentLicense */
+#define EV_TYPE_DOCUMENT_LICENSE (ev_document_license_get_type())
+struct _EvDocumentLicense {
+ gchar *text;
+ gchar *uri;
+ gchar *web_statement;
+};
+GType ev_document_license_get_type (void) G_GNUC_CONST;
+EvDocumentLicense *ev_document_license_new (void);
+EvDocumentLicense *ev_document_license_copy (EvDocumentLicense *license);
+void ev_document_license_free (EvDocumentLicense *license);
+const gchar *ev_document_license_get_text (EvDocumentLicense *license);
+const gchar *ev_document_license_get_uri (EvDocumentLicense *license);
+const gchar *ev_document_license_get_web_statement (EvDocumentLicense *license);
+
+G_END_DECLS
+
+#endif /* EV_DOCUMENT_INFO_H */
diff --git a/libdocument/ev-document-layers.c b/libdocument/ev-document-layers.c
new file mode 100644
index 00000000..17684881
--- /dev/null
+++ b/libdocument/ev-document-layers.c
@@ -0,0 +1,74 @@
+/* ev-document-layers.c
+ * this file is part of evince, a mate document_links viewer
+ *
+ * Copyright (C) 2008 Carlos Garcia Campos <[email protected]>
+ *
+ * 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-layers.h"
+#include "ev-document.h"
+
+G_DEFINE_INTERFACE (EvDocumentLayers, ev_document_layers, 0)
+
+static void
+ev_document_layers_default_init (EvDocumentLayersInterface *klass)
+{
+}
+
+gboolean
+ev_document_layers_has_layers (EvDocumentLayers *document_layers)
+{
+ EvDocumentLayersInterface *iface = EV_DOCUMENT_LAYERS_GET_IFACE (document_layers);
+
+ return iface->has_layers (document_layers);
+}
+
+GtkTreeModel *
+ev_document_layers_get_layers (EvDocumentLayers *document_layers)
+{
+ EvDocumentLayersInterface *iface = EV_DOCUMENT_LAYERS_GET_IFACE (document_layers);
+
+ return iface->get_layers (document_layers);
+}
+
+void
+ev_document_layers_show_layer (EvDocumentLayers *document_layers,
+ EvLayer *layer)
+{
+ EvDocumentLayersInterface *iface = EV_DOCUMENT_LAYERS_GET_IFACE (document_layers);
+
+ iface->show_layer (document_layers, layer);
+}
+
+void
+ev_document_layers_hide_layer (EvDocumentLayers *document_layers,
+ EvLayer *layer)
+{
+ EvDocumentLayersInterface *iface = EV_DOCUMENT_LAYERS_GET_IFACE (document_layers);
+
+ iface->hide_layer (document_layers, layer);
+}
+
+gboolean
+ev_document_layers_layer_is_visible (EvDocumentLayers *document_layers,
+ EvLayer *layer)
+{
+ EvDocumentLayersInterface *iface = EV_DOCUMENT_LAYERS_GET_IFACE (document_layers);
+
+ return iface->layer_is_visible (document_layers, layer);
+}
diff --git a/libdocument/ev-document-layers.h b/libdocument/ev-document-layers.h
new file mode 100644
index 00000000..395a6130
--- /dev/null
+++ b/libdocument/ev-document-layers.h
@@ -0,0 +1,85 @@
+/* ev-document-layers.h
+ * this file is part of evince, a mate document viewer
+ *
+ * Copyright (C) 2008 Carlos Garcia Campos <[email protected]>
+ *
+ * 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.
+ */
+
+#if !defined (__EV_EVINCE_DOCUMENT_H_INSIDE__) && !defined (EVINCE_COMPILATION)
+#error "Only <evince-document.h> can be included directly."
+#endif
+
+#ifndef EV_DOCUMENT_LAYERS_H
+#define EV_DOCUMENT_LAYERS_H
+
+#include <glib-object.h>
+#include <glib.h>
+#include <gtk/gtk.h>
+
+#include "ev-layer.h"
+
+G_BEGIN_DECLS
+
+#define EV_TYPE_DOCUMENT_LAYERS (ev_document_layers_get_type ())
+#define EV_DOCUMENT_LAYERS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EV_TYPE_DOCUMENT_LAYERS, EvDocumentLayers))
+#define EV_DOCUMENT_LAYERS_IFACE(k) (G_TYPE_CHECK_CLASS_CAST((k), EV_TYPE_DOCUMENT_LAYERS, EvDocumentLayersInterface))
+#define EV_IS_DOCUMENT_LAYERS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EV_TYPE_DOCUMENT_LAYERS))
+#define EV_IS_DOCUMENT_LAYERS_IFACE(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EV_TYPE_DOCUMENT_LAYERS))
+#define EV_DOCUMENT_LAYERS_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), EV_TYPE_DOCUMENT_LAYERS, EvDocumentLayersInterface))
+
+typedef struct _EvDocumentLayers EvDocumentLayers;
+typedef struct _EvDocumentLayersInterface EvDocumentLayersInterface;
+
+enum {
+ EV_DOCUMENT_LAYERS_COLUMN_TITLE,
+ EV_DOCUMENT_LAYERS_COLUMN_LAYER,
+ EV_DOCUMENT_LAYERS_COLUMN_VISIBLE,
+ EV_DOCUMENT_LAYERS_COLUMN_ENABLED,
+ EV_DOCUMENT_LAYERS_COLUMN_SHOWTOGGLE,
+ EV_DOCUMENT_LAYERS_COLUMN_RBGROUP,
+ EV_DOCUMENT_LAYERS_N_COLUMNS
+};
+
+struct _EvDocumentLayersInterface
+{
+ GTypeInterface base_iface;
+
+ /* Methods */
+ gboolean (* has_layers) (EvDocumentLayers *document_layers);
+ GtkTreeModel *(* get_layers) (EvDocumentLayers *document_layers);
+
+ void (* show_layer) (EvDocumentLayers *document_layers,
+ EvLayer *layer);
+ void (* hide_layer) (EvDocumentLayers *document_layers,
+ EvLayer *layer);
+ gboolean (* layer_is_visible) (EvDocumentLayers *document_layers,
+ EvLayer *layer);
+};
+
+GType ev_document_layers_get_type (void) G_GNUC_CONST;
+
+gboolean ev_document_layers_has_layers (EvDocumentLayers *document_layers);
+GtkTreeModel *ev_document_layers_get_layers (EvDocumentLayers *document_layers);
+void ev_document_layers_show_layer (EvDocumentLayers *document_layers,
+ EvLayer *layer);
+void ev_document_layers_hide_layer (EvDocumentLayers *document_layers,
+ EvLayer *layer);
+gboolean ev_document_layers_layer_is_visible (EvDocumentLayers *document_layers,
+ EvLayer *layer);
+
+G_END_DECLS
+
+#endif /* EV_DOCUMENT_LAYERS_H */
diff --git a/libdocument/ev-document-links.c b/libdocument/ev-document-links.c
new file mode 100644
index 00000000..19a2b7e1
--- /dev/null
+++ b/libdocument/ev-document-links.c
@@ -0,0 +1,129 @@
+/* ev-document-links.h
+ * this file is part of evince, a mate document_links viewer
+ *
+ * Copyright (C) 2004 Red Hat, Inc.
+ *
+ * Author:
+ * Jonathan Blandford <[email protected]>
+ *
+ * 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-links.h"
+
+G_DEFINE_INTERFACE (EvDocumentLinks, ev_document_links, 0)
+
+static void
+ev_document_links_default_init (EvDocumentLinksInterface *klass)
+{
+}
+
+gboolean
+ev_document_links_has_document_links (EvDocumentLinks *document_links)
+{
+ EvDocumentLinksInterface *iface = EV_DOCUMENT_LINKS_GET_IFACE (document_links);
+ gboolean retval;
+
+ retval = iface->has_document_links (document_links);
+
+ return retval;
+}
+
+GtkTreeModel *
+ev_document_links_get_links_model (EvDocumentLinks *document_links)
+{
+ EvDocumentLinksInterface *iface = EV_DOCUMENT_LINKS_GET_IFACE (document_links);
+ GtkTreeModel *retval;
+
+ retval = iface->get_links_model (document_links);
+
+ return retval;
+}
+
+EvMappingList *
+ev_document_links_get_links (EvDocumentLinks *document_links,
+ EvPage *page)
+{
+ EvDocumentLinksInterface *iface = EV_DOCUMENT_LINKS_GET_IFACE (document_links);
+
+ return iface->get_links (document_links, page);
+}
+
+EvLinkDest *
+ev_document_links_find_link_dest (EvDocumentLinks *document_links,
+ const gchar *link_name)
+{
+ EvDocumentLinksInterface *iface = EV_DOCUMENT_LINKS_GET_IFACE (document_links);
+ EvLinkDest *retval;
+
+ ev_document_doc_mutex_lock ();
+ retval = iface->find_link_dest (document_links, link_name);
+ ev_document_doc_mutex_unlock ();
+
+ return retval;
+}
+
+/* Helper functions */
+gint
+ev_document_links_get_dest_page (EvDocumentLinks *document_links,
+ EvLinkDest *dest)
+{
+ gint page = -1;
+
+ switch (ev_link_dest_get_dest_type (dest)) {
+ case EV_LINK_DEST_TYPE_NAMED: {
+ EvLinkDest *dest2;
+
+ dest2 = ev_document_links_find_link_dest (document_links,
+ ev_link_dest_get_named_dest (dest));
+ if (dest2) {
+ page = ev_link_dest_get_page (dest2);
+ g_object_unref (dest2);
+ }
+ }
+ break;
+ case EV_LINK_DEST_TYPE_PAGE_LABEL:
+ ev_document_find_page_by_label (EV_DOCUMENT (document_links),
+ ev_link_dest_get_page_label (dest),
+ &page);
+ break;
+ default:
+ page = ev_link_dest_get_page (dest);
+ }
+
+ return page;
+}
+
+gchar *
+ev_document_links_get_dest_page_label (EvDocumentLinks *document_links,
+ EvLinkDest *dest)
+{
+ gchar *label = NULL;
+
+ if (ev_link_dest_get_dest_type (dest) == EV_LINK_DEST_TYPE_PAGE_LABEL) {
+ label = g_strdup (ev_link_dest_get_page_label (dest));
+ } else {
+ gint page;
+
+ page = ev_document_links_get_dest_page (document_links, dest);
+ if (page != -1)
+ label = ev_document_get_page_label (EV_DOCUMENT (document_links),
+ page);
+ }
+
+ return label;
+}
diff --git a/libdocument/ev-document-links.h b/libdocument/ev-document-links.h
new file mode 100644
index 00000000..3e28bfd6
--- /dev/null
+++ b/libdocument/ev-document-links.h
@@ -0,0 +1,87 @@
+/* ev-document-links.h
+ * this file is part of evince, a mate document viewer
+ *
+ * Copyright (C) 2004 Red Hat, Inc.
+ *
+ * Author:
+ * Jonathan Blandford <[email protected]>
+ *
+ * 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.
+ */
+
+#if !defined (__EV_EVINCE_DOCUMENT_H_INSIDE__) && !defined (EVINCE_COMPILATION)
+#error "Only <evince-document.h> can be included directly."
+#endif
+
+#ifndef EV_DOCUMENT_LINKS_H
+#define EV_DOCUMENT_LINKS_H
+
+#include <glib-object.h>
+#include <glib.h>
+#include <gtk/gtk.h>
+
+#include "ev-document.h"
+#include "ev-link.h"
+#include "ev-mapping-list.h"
+
+G_BEGIN_DECLS
+
+#define EV_TYPE_DOCUMENT_LINKS (ev_document_links_get_type ())
+#define EV_DOCUMENT_LINKS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EV_TYPE_DOCUMENT_LINKS, EvDocumentLinks))
+#define EV_DOCUMENT_LINKS_IFACE(k) (G_TYPE_CHECK_CLASS_CAST((k), EV_TYPE_DOCUMENT_LINKS, EvDocumentLinksInterface))
+#define EV_IS_DOCUMENT_LINKS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EV_TYPE_DOCUMENT_LINKS))
+#define EV_IS_DOCUMENT_LINKS_IFACE(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EV_TYPE_DOCUMENT_LINKS))
+#define EV_DOCUMENT_LINKS_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), EV_TYPE_DOCUMENT_LINKS, EvDocumentLinksInterface))
+
+typedef struct _EvDocumentLinks EvDocumentLinks;
+typedef struct _EvDocumentLinksInterface EvDocumentLinksInterface;
+
+enum {
+ EV_DOCUMENT_LINKS_COLUMN_MARKUP,
+ EV_DOCUMENT_LINKS_COLUMN_LINK,
+ EV_DOCUMENT_LINKS_COLUMN_EXPAND,
+ EV_DOCUMENT_LINKS_COLUMN_PAGE_LABEL,
+ EV_DOCUMENT_LINKS_COLUMN_NUM_COLUMNS
+};
+
+struct _EvDocumentLinksInterface
+{
+ GTypeInterface base_iface;
+
+ /* Methods */
+ gboolean (* has_document_links) (EvDocumentLinks *document_links);
+ GtkTreeModel *(* get_links_model) (EvDocumentLinks *document_links);
+ EvMappingList *(* get_links) (EvDocumentLinks *document_links,
+ EvPage *page);
+ EvLinkDest *(* find_link_dest) (EvDocumentLinks *document_links,
+ const gchar *link_name);
+};
+
+GType ev_document_links_get_type (void) G_GNUC_CONST;
+gboolean ev_document_links_has_document_links (EvDocumentLinks *document_links);
+GtkTreeModel *ev_document_links_get_links_model (EvDocumentLinks *document_links);
+
+EvMappingList *ev_document_links_get_links (EvDocumentLinks *document_links,
+ EvPage *page);
+EvLinkDest *ev_document_links_find_link_dest (EvDocumentLinks *document_links,
+ const gchar *link_name);
+gint ev_document_links_get_dest_page (EvDocumentLinks *document_links,
+ EvLinkDest *dest);
+gchar *ev_document_links_get_dest_page_label (EvDocumentLinks *document_links,
+ EvLinkDest *dest);
+
+G_END_DECLS
+
+#endif
diff --git a/libdocument/ev-document-misc.c b/libdocument/ev-document-misc.c
new file mode 100644
index 00000000..d597127f
--- /dev/null
+++ b/libdocument/ev-document-misc.c
@@ -0,0 +1,400 @@
+/*
+ * Copyright (C) 2009 Juanjo Marín <[email protected]>
+ * Copyright (c) 2007 Carlos Garcia Campos <[email protected]>
+ * Copyright (C) 2000-2003 Marco Pesenti Gritti
+ *
+ * This program 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, or (at your option)
+ * any later version.
+ *
+ * This program 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 <string.h>
+#include <math.h>
+
+#include <gtk/gtk.h>
+
+#include "ev-document-misc.h"
+
+/* Returns a new GdkPixbuf that is suitable for placing in the thumbnail view.
+ * It is four pixels wider and taller than the source. If source_pixbuf is not
+ * NULL, then it will fill the return pixbuf with the contents of
+ * source_pixbuf.
+ */
+static GdkPixbuf *
+create_thumbnail_frame (int width,
+ int height,
+ GdkPixbuf *source_pixbuf,
+ gboolean fill_bg)
+{
+ GdkPixbuf *retval;
+ guchar *data;
+ gint rowstride;
+ int i;
+ int width_r, height_r;
+
+ if (source_pixbuf)
+ g_return_val_if_fail (GDK_IS_PIXBUF (source_pixbuf), NULL);
+
+ if (source_pixbuf) {
+ width_r = gdk_pixbuf_get_width (source_pixbuf);
+ height_r = gdk_pixbuf_get_height (source_pixbuf);
+ } else {
+ width_r = width;
+ height_r = height;
+ }
+
+ /* make sure no one is passing us garbage */
+ g_assert (width_r >= 0 && height_r >= 0);
+
+ retval = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
+ TRUE, 8,
+ width_r + 4,
+ height_r + 4);
+
+ /* make it black and fill in the middle */
+ data = gdk_pixbuf_get_pixels (retval);
+ rowstride = gdk_pixbuf_get_rowstride (retval);
+
+ gdk_pixbuf_fill (retval, 0x000000ff);
+ if (fill_bg) {
+ for (i = 1; i < height_r + 1; i++)
+ memset (data + (rowstride * i) + 4, 0xffffffff, width_r * 4);
+ }
+
+ /* copy the source pixbuf */
+ if (source_pixbuf)
+ gdk_pixbuf_copy_area (source_pixbuf, 0, 0,
+ width_r,
+ height_r,
+ retval,
+ 1, 1);
+ /* Add the corner */
+ data [(width_r + 2) * 4 + 3] = 0;
+ data [(width_r + 3) * 4 + 3] = 0;
+ data [(width_r + 2) * 4 + (rowstride * 1) + 3] = 0;
+ data [(width_r + 3) * 4 + (rowstride * 1) + 3] = 0;
+
+ data [(height_r + 2) * rowstride + 3] = 0;
+ data [(height_r + 3) * rowstride + 3] = 0;
+ data [(height_r + 2) * rowstride + 4 + 3] = 0;
+ data [(height_r + 3) * rowstride + 4 + 3] = 0;
+
+ return retval;
+}
+
+GdkPixbuf *
+ev_document_misc_get_thumbnail_frame (int width,
+ int height,
+ GdkPixbuf *source_pixbuf)
+{
+ return create_thumbnail_frame (width, height, source_pixbuf, TRUE);
+}
+
+GdkPixbuf *
+ev_document_misc_get_loading_thumbnail (int width,
+ int height,
+ gboolean inverted_colors)
+{
+ return create_thumbnail_frame (width, height, NULL, !inverted_colors);
+}
+
+void
+ev_document_misc_get_page_border_size (gint page_width,
+ gint page_height,
+ GtkBorder *border)
+{
+ g_assert (border);
+
+ border->left = 1;
+ border->top = 1;
+ if (page_width < 100) {
+ border->right = 2;
+ border->bottom = 2;
+ } else if (page_width < 500) {
+ border->right = 3;
+ border->bottom = 3;
+ } else {
+ border->right = 4;
+ border->bottom = 4;
+ }
+}
+
+
+void
+ev_document_misc_paint_one_page (cairo_t *cr,
+ GtkWidget *widget,
+ GdkRectangle *area,
+ GtkBorder *border,
+ gboolean highlight,
+ gboolean inverted_colors)
+{
+ GtkStyle *style = gtk_widget_get_style (widget);
+ GtkStateType state = gtk_widget_get_state (widget);
+
+ gdk_cairo_set_source_color (cr, highlight ? &style->text[state] : &style->dark[state]);
+ gdk_cairo_rectangle (cr, area);
+ cairo_fill (cr);
+
+ if (inverted_colors)
+ cairo_set_source_rgb (cr, 0, 0, 0);
+ else
+ cairo_set_source_rgb (cr, 1, 1, 1);
+ cairo_rectangle (cr,
+ area->x + border->left,
+ area->y + border->top,
+ area->width - (border->left + border->right),
+ area->height - (border->top + border->bottom));
+ cairo_fill (cr);
+
+ gdk_cairo_set_source_color (cr, &style->mid[state]);
+ cairo_rectangle (cr,
+ area->x,
+ area->y + area->height - (border->bottom - border->top),
+ border->bottom - border->top,
+ border->bottom - border->top);
+ cairo_fill (cr);
+
+ cairo_rectangle (cr,
+ area->x + area->width - (border->right - border->left),
+ area->y,
+ border->right - border->left,
+ border->right - border->left);
+ cairo_fill (cr);
+}
+
+cairo_surface_t *
+ev_document_misc_surface_from_pixbuf (GdkPixbuf *pixbuf)
+{
+ cairo_surface_t *surface;
+ cairo_t *cr;
+
+ surface = cairo_image_surface_create (gdk_pixbuf_get_has_alpha (pixbuf) ?
+ CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24,
+ gdk_pixbuf_get_width (pixbuf),
+ gdk_pixbuf_get_height (pixbuf));
+ cr = cairo_create (surface);
+ gdk_cairo_set_source_pixbuf (cr, pixbuf, 0, 0);
+ cairo_paint (cr);
+ cairo_destroy (cr);
+
+ return surface;
+}
+
+GdkPixbuf *
+ev_document_misc_pixbuf_from_surface (cairo_surface_t *surface)
+{
+ GdkPixbuf *pixbuf;
+ cairo_surface_t *image;
+ cairo_t *cr;
+ gboolean has_alpha;
+ gint width, height;
+ cairo_format_t surface_format;
+ gint pixbuf_n_channels;
+ gint pixbuf_rowstride;
+ guchar *pixbuf_pixels;
+ gint x, y;
+
+ width = cairo_image_surface_get_width (surface);
+ height = cairo_image_surface_get_height (surface);
+
+ surface_format = cairo_image_surface_get_format (surface);
+ has_alpha = (surface_format == CAIRO_FORMAT_ARGB32);
+
+ pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB,
+ TRUE, 8,
+ width, height);
+ pixbuf_n_channels = gdk_pixbuf_get_n_channels (pixbuf);
+ pixbuf_rowstride = gdk_pixbuf_get_rowstride (pixbuf);
+ pixbuf_pixels = gdk_pixbuf_get_pixels (pixbuf);
+
+ image = cairo_image_surface_create_for_data (pixbuf_pixels,
+ surface_format,
+ width, height,
+ pixbuf_rowstride);
+ cr = cairo_create (image);
+ cairo_set_source_surface (cr, surface, 0, 0);
+
+ if (has_alpha)
+ cairo_mask_surface (cr, surface, 0, 0);
+ else
+ cairo_paint (cr);
+
+ cairo_destroy (cr);
+ cairo_surface_destroy (image);
+
+ for (y = 0; y < height; y++) {
+ guchar *p = pixbuf_pixels + y * pixbuf_rowstride;
+
+ for (x = 0; x < width; x++) {
+ guchar tmp;
+
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+ tmp = p[0];
+ p[0] = p[2];
+ p[2] = tmp;
+ p[3] = (has_alpha) ? p[3] : 0xff;
+#else
+ tmp = p[0];
+ p[0] = p[1];
+ p[1] = p[2];
+ p[2] = p[3];
+ p[3] = (has_alpha) ? tmp : 0xff;
+#endif
+ p += pixbuf_n_channels;
+ }
+ }
+
+ return pixbuf;
+}
+
+cairo_surface_t *
+ev_document_misc_surface_rotate_and_scale (cairo_surface_t *surface,
+ gint dest_width,
+ gint dest_height,
+ gint dest_rotation)
+{
+ cairo_surface_t *new_surface;
+ cairo_t *cr;
+ gint width, height;
+ gint new_width = dest_width;
+ gint new_height = dest_height;
+
+ width = cairo_image_surface_get_width (surface);
+ height = cairo_image_surface_get_height (surface);
+
+ if (dest_width == width &&
+ dest_height == height &&
+ dest_rotation == 0) {
+ return cairo_surface_reference (surface);
+ }
+
+ if (dest_rotation == 90 || dest_rotation == 270) {
+ new_width = dest_height;
+ new_height = dest_width;
+ }
+
+ new_surface = cairo_surface_create_similar (surface,
+ cairo_surface_get_content (surface),
+ new_width, new_height);
+
+ cr = cairo_create (new_surface);
+ switch (dest_rotation) {
+ case 90:
+ cairo_translate (cr, new_width, 0);
+ break;
+ case 180:
+ cairo_translate (cr, new_width, new_height);
+ break;
+ case 270:
+ cairo_translate (cr, 0, new_height);
+ break;
+ default:
+ cairo_translate (cr, 0, 0);
+ }
+
+ if (dest_width != width || dest_height != height) {
+ cairo_pattern_set_filter (cairo_get_source (cr), CAIRO_FILTER_BILINEAR);
+ cairo_scale (cr,
+ (gdouble)dest_width / width,
+ (gdouble)dest_height / height);
+ }
+
+ cairo_rotate (cr, dest_rotation * G_PI / 180.0);
+ cairo_set_source_surface (cr, surface, 0, 0);
+ cairo_paint (cr);
+ cairo_destroy (cr);
+
+ return new_surface;
+}
+
+void
+ev_document_misc_invert_surface (cairo_surface_t *surface) {
+ cairo_t *cr;
+
+ cr = cairo_create (surface);
+
+ /* white + DIFFERENCE -> invert */
+ cairo_set_operator (cr, CAIRO_OPERATOR_DIFFERENCE);
+ cairo_set_source_rgb (cr, 1., 1., 1.);
+ cairo_paint(cr);
+ cairo_destroy (cr);
+}
+
+void
+ev_document_misc_invert_pixbuf (GdkPixbuf *pixbuf)
+{
+ guchar *data, *p;
+ guint width, height, x, y, rowstride, n_channels;
+
+ n_channels = gdk_pixbuf_get_n_channels (pixbuf);
+ g_assert (gdk_pixbuf_get_colorspace (pixbuf) == GDK_COLORSPACE_RGB);
+ g_assert (gdk_pixbuf_get_bits_per_sample (pixbuf) == 8);
+
+ /* First grab a pointer to the raw pixel data. */
+ data = gdk_pixbuf_get_pixels (pixbuf);
+
+ /* Find the number of bytes per row (could be padded). */
+ rowstride = gdk_pixbuf_get_rowstride (pixbuf);
+
+ width = gdk_pixbuf_get_width (pixbuf);
+ height = gdk_pixbuf_get_height (pixbuf);
+ for (x = 0; x < width; x++) {
+ for (y = 0; y < height; y++) {
+ /* Calculate pixel's offset into the data array. */
+ p = data + x * n_channels + y * rowstride;
+ /* Change the RGB values*/
+ p[0] = 255 - p[0];
+ p[1] = 255 - p[1];
+ p[2] = 255 - p[2];
+ }
+ }
+}
+
+gdouble
+ev_document_misc_get_screen_dpi (GdkScreen *screen)
+{
+ gdouble dp, di;
+
+ /*diagonal in pixels*/
+ dp = hypot (gdk_screen_get_width (screen), gdk_screen_get_height (screen));
+
+ /*diagonal in inches*/
+ di = hypot (gdk_screen_get_width_mm(screen), gdk_screen_get_height_mm (screen)) / 25.4;
+
+ return (dp / di);
+}
+
+/* Returns a locale specific date and time representation */
+gchar *
+ev_document_misc_format_date (GTime utime)
+{
+ time_t time = (time_t) utime;
+ char s[256];
+ const char fmt_hack[] = "%c";
+ size_t len;
+#ifdef HAVE_LOCALTIME_R
+ struct tm t;
+ if (time == 0 || !localtime_r (&time, &t)) return NULL;
+ len = strftime (s, sizeof (s), fmt_hack, &t);
+#else
+ struct tm *t;
+ if (time == 0 || !(t = localtime (&time)) ) return NULL;
+ len = strftime (s, sizeof (s), fmt_hack, t);
+#endif
+
+ if (len == 0 || s[0] == '\0') return NULL;
+
+ return g_locale_to_utf8 (s, -1, NULL, NULL, NULL);
+}
diff --git a/libdocument/ev-document-misc.h b/libdocument/ev-document-misc.h
new file mode 100644
index 00000000..dfce2e2e
--- /dev/null
+++ b/libdocument/ev-document-misc.h
@@ -0,0 +1,67 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; c-indent-level: 8 -*- */
+/*
+ * Copyright (C) 2000-2003 Marco Pesenti Gritti
+ *
+ * This program 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, or (at your option)
+ * any later version.
+ *
+ * This program 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.
+ *
+ * $Id$
+ */
+
+#if !defined (__EV_EVINCE_DOCUMENT_H_INSIDE__) && !defined (EVINCE_COMPILATION)
+#error "Only <evince-document.h> can be included directly."
+#endif
+
+#ifndef EV_DOCUMENT_MISC_H
+#define EV_DOCUMENT_MISC_H
+
+#include <cairo.h>
+
+#include <gdk-pixbuf/gdk-pixbuf.h>
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+GdkPixbuf *ev_document_misc_get_thumbnail_frame (int width,
+ int height,
+ GdkPixbuf *source_pixbuf);
+GdkPixbuf *ev_document_misc_get_loading_thumbnail (int width,
+ int height,
+ gboolean inverted_colors);
+void ev_document_misc_get_page_border_size (gint page_width,
+ gint page_height,
+ GtkBorder *border);
+void ev_document_misc_paint_one_page (cairo_t *cr,
+ GtkWidget *widget,
+ GdkRectangle *area,
+ GtkBorder *border,
+ gboolean highlight,
+ gboolean inverted_colors);
+
+cairo_surface_t *ev_document_misc_surface_from_pixbuf (GdkPixbuf *pixbuf);
+GdkPixbuf *ev_document_misc_pixbuf_from_surface (cairo_surface_t *surface);
+cairo_surface_t *ev_document_misc_surface_rotate_and_scale (cairo_surface_t *surface,
+ gint dest_width,
+ gint dest_height,
+ gint dest_rotation);
+void ev_document_misc_invert_surface (cairo_surface_t *surface);
+void ev_document_misc_invert_pixbuf (GdkPixbuf *pixbuf);
+
+gdouble ev_document_misc_get_screen_dpi (GdkScreen *screen);
+
+gchar *ev_document_misc_format_date (GTime utime);
+
+G_END_DECLS
+
+#endif /* EV_DOCUMENT_MISC_H */
diff --git a/libdocument/ev-document-print.c b/libdocument/ev-document-print.c
new file mode 100644
index 00000000..185121c5
--- /dev/null
+++ b/libdocument/ev-document-print.c
@@ -0,0 +1,41 @@
+/* ev-document-print.c
+ * this file is part of evince, a mate document_links viewer
+ *
+ * Copyright (C) 2009 Carlos Garcia Campos <[email protected]>
+ *
+ * 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.h"
+#include "ev-document-print.h"
+
+G_DEFINE_INTERFACE (EvDocumentPrint, ev_document_print, 0)
+
+static void
+ev_document_print_default_init (EvDocumentPrintInterface *klass)
+{
+}
+
+void
+ev_document_print_print_page (EvDocumentPrint *document_print,
+ EvPage *page,
+ cairo_t *cr)
+{
+ EvDocumentPrintInterface *iface = EV_DOCUMENT_PRINT_GET_IFACE (document_print);
+
+ iface->print_page (document_print, page, cr);
+}
diff --git a/libdocument/ev-document-print.h b/libdocument/ev-document-print.h
new file mode 100644
index 00000000..319f557c
--- /dev/null
+++ b/libdocument/ev-document-print.h
@@ -0,0 +1,59 @@
+/* ev-document-print.h
+ * this file is part of evince, a mate document viewer
+ *
+ * Copyright (C) 2009 Carlos Garcia Campos <[email protected]>
+ *
+ * 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.
+ */
+
+#ifndef EV_DOCUMENT_PRINT_H
+#define EV_DOCUMENT_PRINT_H
+
+#include <glib-object.h>
+#include <cairo.h>
+
+#include "ev-page.h"
+
+G_BEGIN_DECLS
+
+#define EV_TYPE_DOCUMENT_PRINT (ev_document_print_get_type ())
+#define EV_DOCUMENT_PRINT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EV_TYPE_DOCUMENT_PRINT, EvDocumentPrint))
+#define EV_DOCUMENT_PRINT_IFACE(k) (G_TYPE_CHECK_CLASS_CAST((k), EV_TYPE_DOCUMENT_PRINT, EvDocumentPrintInterface))
+#define EV_IS_DOCUMENT_PRINT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EV_TYPE_DOCUMENT_PRINT))
+#define EV_IS_DOCUMENT_PRINT_IFACE(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EV_TYPE_DOCUMENT_PRINT))
+#define EV_DOCUMENT_PRINT_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), EV_TYPE_DOCUMENT_PRINT, EvDocumentPrintInterface))
+
+typedef struct _EvDocumentPrint EvDocumentPrint;
+typedef struct _EvDocumentPrintInterface EvDocumentPrintInterface;
+
+struct _EvDocumentPrintInterface
+{
+ GTypeInterface base_iface;
+
+ /* Methods */
+ void (* print_page) (EvDocumentPrint *document_print,
+ EvPage *page,
+ cairo_t *cr);
+};
+
+GType ev_document_print_get_type (void) G_GNUC_CONST;
+
+void ev_document_print_print_page (EvDocumentPrint *document_print,
+ EvPage *page,
+ cairo_t *cr);
+
+G_END_DECLS
+
+#endif /* EV_DOCUMENT_PRINT_H */
diff --git a/libdocument/ev-document-security.c b/libdocument/ev-document-security.c
new file mode 100644
index 00000000..0b8f552e
--- /dev/null
+++ b/libdocument/ev-document-security.c
@@ -0,0 +1,48 @@
+/* ev-document-links.h
+ * this file is part of evince, a mate document_links viewer
+ *
+ * Copyright (C) 2004 Red Hat, Inc.
+ *
+ * Author:
+ * Jonathan Blandford <[email protected]>
+ *
+ * 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-security.h"
+
+G_DEFINE_INTERFACE (EvDocumentSecurity, ev_document_security, 0)
+
+static void
+ev_document_security_default_init (EvDocumentSecurityInterface *klass)
+{
+}
+
+gboolean
+ev_document_security_has_document_security (EvDocumentSecurity *document_security)
+{
+ EvDocumentSecurityInterface *iface = EV_DOCUMENT_SECURITY_GET_IFACE (document_security);
+ return iface->has_document_security (document_security);
+}
+
+void
+ev_document_security_set_password (EvDocumentSecurity *document_security,
+ const char *password)
+{
+ EvDocumentSecurityInterface *iface = EV_DOCUMENT_SECURITY_GET_IFACE (document_security);
+ iface->set_password (document_security, password);
+}
diff --git a/libdocument/ev-document-security.h b/libdocument/ev-document-security.h
new file mode 100644
index 00000000..c64dc64b
--- /dev/null
+++ b/libdocument/ev-document-security.h
@@ -0,0 +1,67 @@
+/* ev-document-security.h
+ * this file is part of evince, a mate pdf viewer
+ *
+ * Copyright (C) 2005 Red Hat, Inc.
+ *
+ * Author:
+ * Jonathan Blandford <[email protected]>
+ *
+ * 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.
+ */
+
+#if !defined (__EV_EVINCE_DOCUMENT_H_INSIDE__) && !defined (EVINCE_COMPILATION)
+#error "Only <evince-document.h> can be included directly."
+#endif
+
+#ifndef EV_DOCUMENT_SECURITY_H
+#define EV_DOCUMENT_SECURITY_H
+
+#include <glib-object.h>
+#include <glib.h>
+#include <gdk/gdk.h>
+
+#include "ev-document.h"
+
+G_BEGIN_DECLS
+
+
+#define EV_TYPE_DOCUMENT_SECURITY (ev_document_security_get_type ())
+#define EV_DOCUMENT_SECURITY(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EV_TYPE_DOCUMENT_SECURITY, EvDocumentSecurity))
+#define EV_DOCUMENT_SECURITY_IFACE(k) (G_TYPE_CHECK_CLASS_CAST((k), EV_TYPE_DOCUMENT_SECURITY, EvDocumentSecurityInterface))
+#define EV_IS_DOCUMENT_SECURITY(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EV_TYPE_DOCUMENT_SECURITY))
+#define EV_IS_DOCUMENT_SECURITY_IFACE(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EV_TYPE_DOCUMENT_SECURITY))
+#define EV_DOCUMENT_SECURITY_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), EV_TYPE_DOCUMENT_SECURITY, EvDocumentSecurityInterface))
+
+typedef struct _EvDocumentSecurity EvDocumentSecurity;
+typedef struct _EvDocumentSecurityInterface EvDocumentSecurityInterface;
+
+struct _EvDocumentSecurityInterface
+{
+ GTypeInterface base_iface;
+
+ /* Methods */
+ gboolean (* has_document_security) (EvDocumentSecurity *document_security);
+ void (* set_password) (EvDocumentSecurity *document_security,
+ const char *password);
+};
+
+GType ev_document_security_get_type (void);
+gboolean ev_document_security_has_document_security (EvDocumentSecurity *document_security);
+void ev_document_security_set_password (EvDocumentSecurity *document_security,
+ const char *password);
+
+G_END_DECLS
+
+#endif
diff --git a/libdocument/ev-document-text.c b/libdocument/ev-document-text.c
new file mode 100644
index 00000000..56c1a563
--- /dev/null
+++ b/libdocument/ev-document-text.c
@@ -0,0 +1,70 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; c-indent-level: 8 -*- */
+/*
+ * Copyright (C) 2010 Yaco Sistemas, Daniel Garcia <[email protected]>
+ *
+ * This program 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, or (at your option)
+ * any later version.
+ *
+ * This program 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.
+ *
+ * $Id$
+ */
+
+#include "config.h"
+
+#include "ev-document-text.h"
+
+G_DEFINE_INTERFACE (EvDocumentText, ev_document_text, 0)
+
+static void
+ev_document_text_default_init (EvDocumentTextInterface *klass)
+{
+}
+
+gchar *
+ev_document_text_get_text (EvDocumentText *document_text,
+ EvPage *page)
+{
+ EvDocumentTextInterface *iface = EV_DOCUMENT_TEXT_GET_IFACE (document_text);
+
+ if (!iface->get_text)
+ return NULL;
+
+ return iface->get_text (document_text, page);
+}
+
+
+gboolean
+ev_document_text_get_text_layout (EvDocumentText *document_text,
+ EvPage *page,
+ EvRectangle **areas,
+ guint *n_areas)
+{
+ EvDocumentTextInterface *iface = EV_DOCUMENT_TEXT_GET_IFACE (document_text);
+
+ if (!iface->get_text_layout)
+ return FALSE;
+
+ return iface->get_text_layout (document_text, page, areas, n_areas);
+}
+
+cairo_region_t *
+ev_document_text_get_text_mapping (EvDocumentText *document_text,
+ EvPage *page)
+{
+ EvDocumentTextInterface *iface = EV_DOCUMENT_TEXT_GET_IFACE (document_text);
+
+ if (!iface->get_text_mapping)
+ return NULL;
+
+ return iface->get_text_mapping (document_text, page);
+}
diff --git a/libdocument/ev-document-text.h b/libdocument/ev-document-text.h
new file mode 100644
index 00000000..abf1cc76
--- /dev/null
+++ b/libdocument/ev-document-text.h
@@ -0,0 +1,75 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; c-indent-level: 8 -*- */
+/*
+ * Copyright (C) 2010 Yaco Sistemas, Daniel Garcia <[email protected]>
+ *
+ * This program 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, or (at your option)
+ * any later version.
+ *
+ * This program 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.
+ *
+ * $Id$
+ */
+
+#if !defined (__EV_EVINCE_DOCUMENT_H_INSIDE__) && !defined (EVINCE_COMPILATION)
+#error "Only <evince-document.h> can be included directly."
+#endif
+
+#ifndef EV_DOCUMENT_TEXT_H
+#define EV_DOCUMENT_TEXT_H
+
+#include <glib-object.h>
+#include <glib.h>
+#include <gdk/gdk.h>
+
+#include "ev-document.h"
+
+G_BEGIN_DECLS
+
+#define EV_TYPE_DOCUMENT_TEXT (ev_document_text_get_type ())
+#define EV_DOCUMENT_TEXT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EV_TYPE_DOCUMENT_TEXT, EvDocumentText))
+#define EV_DOCUMENT_TEXT_IFACE(k) (G_TYPE_CHECK_CLASS_CAST((k), EV_TYPE_DOCUMENT_TEXT, EvDocumentTextInterface))
+#define EV_IS_DOCUMENT_TEXT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EV_TYPE_DOCUMENT_TEXT))
+#define EV_IS_DOCUMENT_TEXT_IFACE(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EV_TYPE_DOCUMENT_TEXT))
+#define EV_DOCUMENT_TEXT_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), EV_TYPE_DOCUMENT_TEXT, EvDocumentTextInterface))
+
+typedef struct _EvDocumentText EvDocumentText;
+typedef struct _EvDocumentTextInterface EvDocumentTextInterface;
+
+struct _EvDocumentTextInterface
+{
+ GTypeInterface base_iface;
+
+ /* Methods */
+ cairo_region_t *(* get_text_mapping) (EvDocumentText *document_text,
+ EvPage *page);
+ gchar *(* get_text) (EvDocumentText *document_text,
+ EvPage *page);
+ gboolean (* get_text_layout) (EvDocumentText *document_text,
+ EvPage *page,
+ EvRectangle **areas,
+ guint *n_areas);
+};
+
+GType ev_document_text_get_type (void) G_GNUC_CONST;
+
+gchar *ev_document_text_get_text (EvDocumentText *document_text,
+ EvPage *page);
+gboolean ev_document_text_get_text_layout (EvDocumentText *document_text,
+ EvPage *page,
+ EvRectangle **areas,
+ guint *n_areas);
+cairo_region_t *ev_document_text_get_text_mapping (EvDocumentText *document_text,
+ EvPage *page);
+
+G_END_DECLS
+
+#endif /* EV_DOCUMENT_TEXT_H */
diff --git a/libdocument/ev-document-thumbnails.c b/libdocument/ev-document-thumbnails.c
new file mode 100644
index 00000000..9482e09e
--- /dev/null
+++ b/libdocument/ev-document-thumbnails.c
@@ -0,0 +1,63 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; c-indent-level: 8 -*- */
+/*
+ * Copyright (C) 2004 Anders Carlsson <[email protected]>
+ *
+ * This program 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, or (at your option)
+ * any later version.
+ *
+ * This program 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-thumbnails.h"
+#include "ev-document.h"
+
+G_DEFINE_INTERFACE (EvDocumentThumbnails, ev_document_thumbnails, 0)
+
+static void
+ev_document_thumbnails_default_init (EvDocumentThumbnailsInterface *klass)
+{
+}
+
+GdkPixbuf *
+ev_document_thumbnails_get_thumbnail (EvDocumentThumbnails *document,
+ EvRenderContext *rc,
+ gboolean border)
+{
+ EvDocumentThumbnailsInterface *iface;
+
+ g_return_val_if_fail (EV_IS_DOCUMENT_THUMBNAILS (document), NULL);
+ g_return_val_if_fail (EV_IS_RENDER_CONTEXT (rc), NULL);
+
+ iface = EV_DOCUMENT_THUMBNAILS_GET_IFACE (document);
+
+ return iface->get_thumbnail (document, rc, border);
+}
+
+void
+ev_document_thumbnails_get_dimensions (EvDocumentThumbnails *document,
+ EvRenderContext *rc,
+ gint *width,
+ gint *height)
+{
+ EvDocumentThumbnailsInterface *iface;
+
+ g_return_if_fail (EV_IS_DOCUMENT_THUMBNAILS (document));
+ g_return_if_fail (EV_IS_RENDER_CONTEXT (rc));
+ g_return_if_fail (width != NULL);
+ g_return_if_fail (height != NULL);
+
+ iface = EV_DOCUMENT_THUMBNAILS_GET_IFACE (document);
+ iface->get_dimensions (document, rc, width, height);
+}
+
diff --git a/libdocument/ev-document-thumbnails.h b/libdocument/ev-document-thumbnails.h
new file mode 100644
index 00000000..bf663eed
--- /dev/null
+++ b/libdocument/ev-document-thumbnails.h
@@ -0,0 +1,69 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; c-indent-level: 8 -*- */
+/*
+ * Copyright (C) 2004 Anders Carlsson
+ *
+ * This program 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, or (at your option)
+ * any later version.
+ *
+ * This program 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.
+ *
+ */
+
+#if !defined (__EV_EVINCE_DOCUMENT_H_INSIDE__) && !defined (EVINCE_COMPILATION)
+#error "Only <evince-document.h> can be included directly."
+#endif
+
+#ifndef EV_DOCUMENT_THUMBNAILS_H
+#define EV_DOCUMENT_THUMBNAILS_H
+
+#include <gdk-pixbuf/gdk-pixbuf.h>
+
+#include "ev-render-context.h"
+
+G_BEGIN_DECLS
+
+#define EV_TYPE_DOCUMENT_THUMBNAILS (ev_document_thumbnails_get_type ())
+#define EV_DOCUMENT_THUMBNAILS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EV_TYPE_DOCUMENT_THUMBNAILS, EvDocumentThumbnails))
+#define EV_DOCUMENT_THUMBNAILS_IFACE(k) (G_TYPE_CHECK_CLASS_CAST((k), EV_TYPE_DOCUMENT_THUMBNAILS, EvDocumentThumbnailsInterface))
+#define EV_IS_DOCUMENT_THUMBNAILS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EV_TYPE_DOCUMENT_THUMBNAILS))
+#define EV_IS_DOCUMENT_THUMBNAILS_IFACE(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EV_TYPE_DOCUMENT_THUMBNAILS))
+#define EV_DOCUMENT_THUMBNAILS_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), EV_TYPE_DOCUMENT_THUMBNAILS, EvDocumentThumbnailsInterface))
+
+typedef struct _EvDocumentThumbnails EvDocumentThumbnails;
+typedef struct _EvDocumentThumbnailsInterface EvDocumentThumbnailsInterface;
+
+struct _EvDocumentThumbnailsInterface {
+ GTypeInterface base_iface;
+
+ /* Methods */
+ GdkPixbuf * (* get_thumbnail) (EvDocumentThumbnails *document,
+ EvRenderContext *rc,
+ gboolean border);
+ void (* get_dimensions) (EvDocumentThumbnails *document,
+ EvRenderContext *rc,
+ gint *width,
+ gint *height);
+};
+
+GType ev_document_thumbnails_get_type (void) G_GNUC_CONST;
+
+GdkPixbuf *ev_document_thumbnails_get_thumbnail (EvDocumentThumbnails *document,
+ EvRenderContext *rc,
+ gboolean border);
+void ev_document_thumbnails_get_dimensions (EvDocumentThumbnails *document,
+ EvRenderContext *rc,
+ gint *width,
+ gint *height);
+
+G_END_DECLS
+
+#endif /* EV_DOCUMENT_THUMBNAILS_H */
diff --git a/libdocument/ev-document-transition.c b/libdocument/ev-document-transition.c
new file mode 100644
index 00000000..d8345f2c
--- /dev/null
+++ b/libdocument/ev-document-transition.c
@@ -0,0 +1,57 @@
+/* ev-document-transition.c
+ * this file is part of evince, a mate document viewer
+ *
+ * Copyright (C) 2006 Carlos Garcia Campos <[email protected]>
+ *
+ * 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-transition.h"
+
+G_DEFINE_INTERFACE (EvDocumentTransition, ev_document_transition, 0)
+
+static void
+ev_document_transition_default_init (EvDocumentTransitionInterface *klass)
+{
+}
+
+gdouble
+ev_document_transition_get_page_duration (EvDocumentTransition *document_trans,
+ gint page)
+{
+ EvDocumentTransitionInterface *iface = EV_DOCUMENT_TRANSITION_GET_IFACE (document_trans);
+
+ if (iface->get_page_duration)
+ return iface->get_page_duration (document_trans, page);
+
+ return -1;
+}
+
+EvTransitionEffect *
+ev_document_transition_get_effect (EvDocumentTransition *document_trans,
+ gint page)
+{
+ EvDocumentTransitionInterface *iface = EV_DOCUMENT_TRANSITION_GET_IFACE (document_trans);
+ EvTransitionEffect *effect = NULL;
+
+ if (iface->get_effect)
+ effect = iface->get_effect (document_trans, page);
+
+ if (!effect)
+ return ev_transition_effect_new (EV_TRANSITION_EFFECT_REPLACE, NULL);
+
+ return effect;
+}
diff --git a/libdocument/ev-document-transition.h b/libdocument/ev-document-transition.h
new file mode 100644
index 00000000..d7d3f1fd
--- /dev/null
+++ b/libdocument/ev-document-transition.h
@@ -0,0 +1,64 @@
+/* ev-document-transition.h
+ * this file is part of evince, a mate document viewer
+ *
+ * Copyright (C) 2006 Carlos Garcia Campos <[email protected]>
+ *
+ * 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.
+ */
+
+#if !defined (__EV_EVINCE_DOCUMENT_H_INSIDE__) && !defined (EVINCE_COMPILATION)
+#error "Only <evince-document.h> can be included directly."
+#endif
+
+#ifndef EV_DOCUMENT_TRANSITION_H
+#define EV_DOCUMENT_TRANSITION_H
+
+#include <glib-object.h>
+
+#include "ev-document.h"
+#include "ev-transition-effect.h"
+
+G_BEGIN_DECLS
+
+#define EV_TYPE_DOCUMENT_TRANSITION (ev_document_transition_get_type ())
+#define EV_DOCUMENT_TRANSITION(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EV_TYPE_DOCUMENT_TRANSITION, EvDocumentTransition))
+#define EV_DOCUMENT_TRANSITION_IFACE(k) (G_TYPE_CHECK_CLASS_CAST((k), EV_TYPE_DOCUMENT_TRANSITION, EvDocumentTransitionInterface))
+#define EV_IS_DOCUMENT_TRANSITION(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EV_TYPE_DOCUMENT_TRANSITION))
+#define EV_IS_DOCUMENT_TRANSITION_IFACE(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EV_TYPE_DOCUMENT_TRANSITION))
+#define EV_DOCUMENT_TRANSITION_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), EV_TYPE_DOCUMENT_TRANSITION, EvDocumentTransitionInterface))
+
+typedef struct _EvDocumentTransition EvDocumentTransition;
+typedef struct _EvDocumentTransitionInterface EvDocumentTransitionInterface;
+
+struct _EvDocumentTransitionInterface
+{
+ GTypeInterface base_iface;
+
+ /* Methods */
+ gdouble (* get_page_duration) (EvDocumentTransition *document_trans,
+ gint page);
+ EvTransitionEffect * (* get_effect) (EvDocumentTransition *document_trans,
+ gint page);
+};
+
+GType ev_document_transition_get_type (void) G_GNUC_CONST;
+gdouble ev_document_transition_get_page_duration (EvDocumentTransition *document_trans,
+ gint page);
+EvTransitionEffect * ev_document_transition_get_effect (EvDocumentTransition *document_trans,
+ gint page);
+
+G_END_DECLS
+
+#endif /* EV_DOCUMENT_TRANSITION_H */
diff --git a/libdocument/ev-document-type-builtins.c.template b/libdocument/ev-document-type-builtins.c.template
new file mode 100644
index 00000000..c355aff5
--- /dev/null
+++ b/libdocument/ev-document-type-builtins.c.template
@@ -0,0 +1,44 @@
+/*** BEGIN file-header ***/
+#include <config.h>
+
+#include "ev-document-type-builtins.h"
+
+/*** END file-header ***/
+
+/*** BEGIN file-production ***/
+/* enumerations from "@filename@" */
+#include "@filename@"
+/*** END file-production ***/
+
+
+/*** BEGIN value-header ***/
+GType
+@enum_name@_get_type (void)
+{
+ static volatile gsize g_define_type_id__volatile = 0;
+
+ if (g_once_init_enter (&g_define_type_id__volatile)) {
+ static const G@Type@Value values[] = {
+/*** END value-header ***/
+
+/*** BEGIN value-production ***/
+ { @VALUENAME@, "@VALUENAME@", "@valuenick@" },
+/*** END value-production ***/
+
+/*** BEGIN value-tail ***/
+ { 0, NULL, NULL }
+ };
+ GType g_define_type_id = \
+ g_@type@_register_static (g_intern_static_string ("@EnumName@"), values);
+
+ g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
+ }
+
+ return g_define_type_id__volatile;
+}
+
+/*** END value-tail ***/
+
+/*** BEGIN file-tail ***/
+
+/*** END file-tail ***/
diff --git a/libdocument/ev-document-type-builtins.h.template b/libdocument/ev-document-type-builtins.h.template
new file mode 100644
index 00000000..4b70c87c
--- /dev/null
+++ b/libdocument/ev-document-type-builtins.h.template
@@ -0,0 +1,29 @@
+/*** BEGIN file-header ***/
+
+#if !defined (__EV_EVINCE_DOCUMENT_H_INSIDE__) && !defined (EVINCE_COMPILATION)
+#error "Only <evince-document.h> can be included directly."
+#endif
+
+#ifndef EV_DOCUMENT_TYPE_BUILTINS_H
+#define EV_DOCUMENT_TYPE_BUILTINS_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+/*** END file-header ***/
+
+/*** BEGIN file-production ***/
+
+/* enumerations from "@filename@" */
+/*** END file-production ***/
+
+/*** BEGIN value-header ***/
+GType @enum_name@_get_type (void) G_GNUC_CONST;
+#define EV_TYPE_@ENUMSHORT@ (@enum_name@_get_type ())
+/*** END value-header ***/
+
+/*** BEGIN file-tail ***/
+G_END_DECLS
+
+#endif /* !EV_DOCUMENT_TYPE_BUILTINS_H */
+/*** END file-tail ***/
diff --git a/libdocument/ev-document.c b/libdocument/ev-document.c
new file mode 100644
index 00000000..70349dcb
--- /dev/null
+++ b/libdocument/ev-document.c
@@ -0,0 +1,867 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; c-indent-level: 8 -*- */
+/*
+ * Copyright (C) 2009 Carlos Garcia Campos
+ * Copyright (C) 2004 Marco Pesenti Gritti
+ *
+ * This program 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, or (at your option)
+ * any later version.
+ *
+ * This program 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 <stdlib.h>
+#include <string.h>
+
+#include "ev-document.h"
+#include "synctex_parser.h"
+
+#define EV_DOCUMENT_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EV_TYPE_DOCUMENT, EvDocumentPrivate))
+
+typedef struct _EvPageSize
+{
+ gdouble width;
+ gdouble height;
+} EvPageSize;
+
+struct _EvDocumentPrivate
+{
+ gchar *uri;
+
+ gint n_pages;
+
+ gboolean uniform;
+ gdouble uniform_width;
+ gdouble uniform_height;
+
+ gdouble max_width;
+ gdouble max_height;
+ gdouble min_width;
+ gdouble min_height;
+ gint max_label;
+
+ gchar **page_labels;
+ EvPageSize *page_sizes;
+ EvDocumentInfo *info;
+
+ synctex_scanner_t synctex_scanner;
+};
+
+static gint _ev_document_get_n_pages (EvDocument *document);
+static void _ev_document_get_page_size (EvDocument *document,
+ EvPage *page,
+ double *width,
+ double *height);
+static gchar *_ev_document_get_page_label (EvDocument *document,
+ EvPage *page);
+static EvDocumentInfo *_ev_document_get_info (EvDocument *document);
+static gboolean _ev_document_support_synctex (EvDocument *document);
+
+GMutex *ev_doc_mutex = NULL;
+GMutex *ev_fc_mutex = NULL;
+
+G_DEFINE_ABSTRACT_TYPE (EvDocument, ev_document, G_TYPE_OBJECT)
+
+GQuark
+ev_document_error_quark (void)
+{
+ static GQuark q = 0;
+ if (q == 0)
+ q = g_quark_from_static_string ("ev-document-error-quark");
+
+ return q;
+}
+
+static EvPage *
+ev_document_impl_get_page (EvDocument *document,
+ gint index)
+{
+ return ev_page_new (index);
+}
+
+static EvDocumentInfo *
+ev_document_impl_get_info (EvDocument *document)
+{
+ return g_new0 (EvDocumentInfo, 1);
+}
+
+static void
+ev_document_finalize (GObject *object)
+{
+ EvDocument *document = EV_DOCUMENT (object);
+
+ if (document->priv->uri) {
+ g_free (document->priv->uri);
+ document->priv->uri = NULL;
+ }
+
+ if (document->priv->page_sizes) {
+ g_free (document->priv->page_sizes);
+ document->priv->page_sizes = NULL;
+ }
+
+ if (document->priv->page_labels) {
+ gint i;
+
+ for (i = 0; i < document->priv->n_pages; i++) {
+ g_free (document->priv->page_labels[i]);
+ }
+ g_free (document->priv->page_labels);
+ document->priv->page_labels = NULL;
+ }
+
+ if (document->priv->info) {
+ ev_document_info_free (document->priv->info);
+ document->priv->info = NULL;
+ }
+
+ if (document->priv->synctex_scanner) {
+ synctex_scanner_free (document->priv->synctex_scanner);
+ document->priv->synctex_scanner = NULL;
+ }
+
+ G_OBJECT_CLASS (ev_document_parent_class)->finalize (object);
+}
+
+static void
+ev_document_init (EvDocument *document)
+{
+ document->priv = EV_DOCUMENT_GET_PRIVATE (document);
+
+ /* Assume all pages are the same size until proven otherwise */
+ document->priv->uniform = TRUE;
+}
+
+static void
+ev_document_class_init (EvDocumentClass *klass)
+{
+ GObjectClass *g_object_class = G_OBJECT_CLASS (klass);
+
+ g_type_class_add_private (g_object_class, sizeof (EvDocumentPrivate));
+
+ klass->get_page = ev_document_impl_get_page;
+ klass->get_info = ev_document_impl_get_info;
+ klass->get_backend_info = NULL;
+
+ g_object_class->finalize = ev_document_finalize;
+}
+
+GMutex *
+ev_document_get_doc_mutex (void)
+{
+ if (ev_doc_mutex == NULL) {
+ ev_doc_mutex = g_mutex_new ();
+ }
+ return ev_doc_mutex;
+}
+
+void
+ev_document_doc_mutex_lock (void)
+{
+ g_mutex_lock (ev_document_get_doc_mutex ());
+}
+
+void
+ev_document_doc_mutex_unlock (void)
+{
+ g_mutex_unlock (ev_document_get_doc_mutex ());
+}
+
+gboolean
+ev_document_doc_mutex_trylock (void)
+{
+ return g_mutex_trylock (ev_document_get_doc_mutex ());
+}
+
+GMutex *
+ev_document_get_fc_mutex (void)
+{
+ if (ev_fc_mutex == NULL) {
+ ev_fc_mutex = g_mutex_new ();
+ }
+ return ev_fc_mutex;
+}
+
+void
+ev_document_fc_mutex_lock (void)
+{
+ g_mutex_lock (ev_document_get_fc_mutex ());
+}
+
+void
+ev_document_fc_mutex_unlock (void)
+{
+ g_mutex_unlock (ev_document_get_fc_mutex ());
+}
+
+gboolean
+ev_document_fc_mutex_trylock (void)
+{
+ return g_mutex_trylock (ev_document_get_fc_mutex ());
+}
+
+/**
+ * ev_document_load:
+ * @document: a #EvDocument
+ * @uri: the document's URI
+ * @error: a #GError location to store an error, or %NULL
+ *
+ * Loads @document from @uri.
+ *
+ * On failure, %FALSE is returned and @error is filled in.
+ * If the document is encrypted, EV_DEFINE_ERROR_ENCRYPTED is returned.
+ * If the backend cannot load the specific document, EV_DOCUMENT_ERROR_INVALID
+ * is returned. Other errors are possible too, depending on the backend
+ * used to load the document and the URI, e.g. #GIOError, #GFileError, and
+ * #GConvertError.
+ *
+ * Returns: %TRUE on success, or %FALSE on failure.
+ */
+gboolean
+ev_document_load (EvDocument *document,
+ const char *uri,
+ GError **error)
+{
+ EvDocumentClass *klass = EV_DOCUMENT_GET_CLASS (document);
+ gboolean retval;
+ GError *err = NULL;
+
+ retval = klass->load (document, uri, &err);
+ if (!retval) {
+ if (err) {
+ g_propagate_error (error, err);
+ } else {
+ g_warning ("%s::EvDocument::load returned FALSE but did not fill in @error; fix the backend!\n",
+ G_OBJECT_TYPE_NAME (document));
+
+ /* So upper layers don't crash */
+ g_set_error_literal (error,
+ EV_DOCUMENT_ERROR,
+ EV_DOCUMENT_ERROR_INVALID,
+ "Internal error in backend");
+ }
+ } else {
+ gint i;
+ EvDocumentPrivate *priv = document->priv;
+
+ /* Cache some info about the document to avoid
+ * going to the backends since it requires locks
+ */
+ priv->uri = g_strdup (uri);
+ priv->n_pages = _ev_document_get_n_pages (document);
+
+ for (i = 0; i < priv->n_pages; i++) {
+ EvPage *page = ev_document_get_page (document, i);
+ gdouble page_width = 0;
+ gdouble page_height = 0;
+ EvPageSize *page_size;
+ gchar *page_label;
+
+ _ev_document_get_page_size (document, page, &page_width, &page_height);
+
+ if (i == 0) {
+ priv->uniform_width = page_width;
+ priv->uniform_height = page_height;
+ priv->max_width = priv->uniform_width;
+ priv->max_height = priv->uniform_height;
+ priv->min_width = priv->uniform_width;
+ priv->min_height = priv->uniform_height;
+ } else if (priv->uniform &&
+ (priv->uniform_width != page_width ||
+ priv->uniform_height != page_height)) {
+ /* It's a different page size. Backfill the array. */
+ int j;
+
+ priv->page_sizes = g_new0 (EvPageSize, priv->n_pages);
+
+ for (j = 0; j < i; j++) {
+ page_size = &(priv->page_sizes[j]);
+ page_size->width = priv->uniform_width;
+ page_size->height = priv->uniform_height;
+ }
+ priv->uniform = FALSE;
+ }
+ if (!priv->uniform) {
+ page_size = &(priv->page_sizes[i]);
+
+ page_size->width = page_width;
+ page_size->height = page_height;
+
+ if (page_width > priv->max_width)
+ priv->max_width = page_width;
+ if (page_width < priv->min_width)
+ priv->min_width = page_width;
+
+ if (page_height > priv->max_height)
+ priv->max_height = page_height;
+ if (page_height < priv->min_height)
+ priv->min_height = page_height;
+ }
+
+ page_label = _ev_document_get_page_label (document, page);
+ if (page_label) {
+ if (!priv->page_labels)
+ priv->page_labels = g_new0 (gchar *, priv->n_pages);
+
+ priv->page_labels[i] = page_label;
+ priv->max_label = MAX (priv->max_label,
+ g_utf8_strlen (page_label, 256));
+ }
+
+ g_object_unref (page);
+ }
+
+ priv->info = _ev_document_get_info (document);
+ if (_ev_document_support_synctex (document)) {
+ gchar *filename;
+
+ filename = g_filename_from_uri (uri, NULL, NULL);
+ if (filename != NULL) {
+ priv->synctex_scanner =
+ synctex_scanner_new_with_output_file (filename, NULL, 1);
+ g_free (filename);
+ }
+ }
+ }
+
+ return retval;
+}
+
+/**
+ * ev_document_save:
+ * @document:
+ * @uri: the target URI
+ * @error: a #GError location to store an error, or %NULL
+ *
+ * Saves @document to @uri.
+ *
+ * Returns: %TRUE on success, or %FALSE on error with @error filled in
+ */
+gboolean
+ev_document_save (EvDocument *document,
+ const char *uri,
+ GError **error)
+{
+ EvDocumentClass *klass = EV_DOCUMENT_GET_CLASS (document);
+
+ return klass->save (document, uri, error);
+}
+
+EvPage *
+ev_document_get_page (EvDocument *document,
+ gint index)
+{
+ EvDocumentClass *klass = EV_DOCUMENT_GET_CLASS (document);
+
+ return klass->get_page (document, index);
+}
+
+static gboolean
+_ev_document_support_synctex (EvDocument *document)
+{
+ EvDocumentClass *klass = EV_DOCUMENT_GET_CLASS (document);
+
+ return klass->support_synctex ? klass->support_synctex (document) : FALSE;
+}
+
+gboolean
+ev_document_has_synctex (EvDocument *document)
+{
+ g_return_val_if_fail (EV_IS_DOCUMENT (document), FALSE);
+
+ return document->priv->synctex_scanner != NULL;
+}
+
+/**
+ * ev_document_synctex_backward_search:
+ * @document:
+ * @page: the target page
+ * @x:
+ * @y:
+ *
+ * Peforms a Synctex backward search to obtain the TeX input file, line and
+ * (possibly) column corresponding to the position (@x,@y) (in 72dpi
+ * coordinates) in the @page of @document.
+ *
+ * Returns: A pointer to the EvSourceLink structure that holds the result. @NULL if synctex
+ * is not enabled for the document or no result is found.
+ * The EvSourceLink pointer should be freed with g_free after it is used.
+ */
+EvSourceLink *
+ev_document_synctex_backward_search (EvDocument *document,
+ gint page_index,
+ gfloat x,
+ gfloat y)
+{
+ EvSourceLink *result = NULL;
+ synctex_scanner_t scanner;
+
+ g_return_val_if_fail (EV_IS_DOCUMENT (document), NULL);
+
+ scanner = document->priv->synctex_scanner;
+ if (!scanner)
+ return NULL;
+
+ if (synctex_edit_query (scanner, page_index + 1, x, y) > 0) {
+ synctex_node_t node;
+
+ /* We assume that a backward search returns either zero or one result_node */
+ node = synctex_next_result (scanner);
+ if (node != NULL) {
+ result = g_new (EvSourceLink, 1);
+ result->filename = synctex_scanner_get_name (scanner,
+ synctex_node_tag (node));
+ result->line = synctex_node_line (node);
+ result->col = synctex_node_column (node);
+ }
+ }
+
+ return result;
+}
+
+/**
+ * ev_document_synctex_forward_search:
+ * @document:
+ * @source_link:
+ *
+ * Peforms a Synctex forward search to obtain the area in the document
+ * corresponding to the position @line and @column number in the source Tex file
+ *
+ * Returns: An EvMapping with the page number and area corresponfing to
+ * the given line in the source file. It must be free with g_free when done
+ */
+EvMapping *
+ev_document_synctex_forward_search (EvDocument *document,
+ EvSourceLink *link)
+{
+ EvMapping *result = NULL;
+ synctex_scanner_t scanner;
+
+ g_return_val_if_fail (EV_IS_DOCUMENT (document), NULL);
+
+ scanner = document->priv->synctex_scanner;
+ if (!scanner)
+ return NULL;
+
+ if (synctex_display_query (scanner, link->filename, link->line, link->col) > 0) {
+ synctex_node_t node;
+ gint page;
+
+ if ((node = synctex_next_result (scanner))) {
+ result = g_new (EvMapping, 1);
+
+ page = synctex_node_page (node) - 1;
+ result->data = GINT_TO_POINTER (page);
+
+ result->area.x1 = synctex_node_box_visible_h (node);
+ result->area.y1 = synctex_node_box_visible_v (node) -
+ synctex_node_box_visible_height (node);
+ result->area.x2 = synctex_node_box_visible_width (node) + result->area.x1;
+ result->area.y2 = synctex_node_box_visible_depth (node) +
+ synctex_node_box_visible_height (node) + result->area.y1;
+ }
+ }
+
+ return result;
+}
+
+static gint
+_ev_document_get_n_pages (EvDocument *document)
+{
+ EvDocumentClass *klass = EV_DOCUMENT_GET_CLASS (document);
+
+ return klass->get_n_pages (document);
+}
+
+gint
+ev_document_get_n_pages (EvDocument *document)
+{
+ g_return_val_if_fail (EV_IS_DOCUMENT (document), 0);
+
+ return document->priv->n_pages;
+}
+
+static void
+_ev_document_get_page_size (EvDocument *document,
+ EvPage *page,
+ double *width,
+ double *height)
+{
+ EvDocumentClass *klass = EV_DOCUMENT_GET_CLASS (document);
+
+ klass->get_page_size (document, page, width, height);
+}
+
+void
+ev_document_get_page_size (EvDocument *document,
+ gint page_index,
+ double *width,
+ double *height)
+{
+ g_return_if_fail (EV_IS_DOCUMENT (document));
+ g_return_if_fail (page_index >= 0 || page_index < document->priv->n_pages);
+
+ if (width)
+ *width = document->priv->uniform ?
+ document->priv->uniform_width :
+ document->priv->page_sizes[page_index].width;
+ if (height)
+ *height = document->priv->uniform ?
+ document->priv->uniform_height :
+ document->priv->page_sizes[page_index].height;
+}
+
+static gchar *
+_ev_document_get_page_label (EvDocument *document,
+ EvPage *page)
+{
+ EvDocumentClass *klass = EV_DOCUMENT_GET_CLASS (document);
+
+ return klass->get_page_label ?
+ klass->get_page_label (document, page) : NULL;
+}
+
+gchar *
+ev_document_get_page_label (EvDocument *document,
+ gint page_index)
+{
+ g_return_val_if_fail (EV_IS_DOCUMENT (document), NULL);
+ g_return_val_if_fail (page_index >= 0 || page_index < document->priv->n_pages, NULL);
+
+ return (document->priv->page_labels && document->priv->page_labels[page_index]) ?
+ g_strdup (document->priv->page_labels[page_index]) :
+ g_strdup_printf ("%d", page_index + 1);
+}
+
+static EvDocumentInfo *
+_ev_document_get_info (EvDocument *document)
+{
+ EvDocumentClass *klass = EV_DOCUMENT_GET_CLASS (document);
+
+ return klass->get_info (document);
+}
+
+EvDocumentInfo *
+ev_document_get_info (EvDocument *document)
+{
+ g_return_val_if_fail (EV_IS_DOCUMENT (document), NULL);
+
+ return document->priv->info;
+}
+
+gboolean
+ev_document_get_backend_info (EvDocument *document, EvDocumentBackendInfo *info)
+{
+ g_return_val_if_fail (EV_IS_DOCUMENT (document), FALSE);
+
+ EvDocumentClass *klass = EV_DOCUMENT_GET_CLASS (document);
+ if (klass->get_backend_info == NULL)
+ return FALSE;
+
+ return klass->get_backend_info (document, info);
+}
+
+cairo_surface_t *
+ev_document_render (EvDocument *document,
+ EvRenderContext *rc)
+{
+ EvDocumentClass *klass = EV_DOCUMENT_GET_CLASS (document);
+
+ return klass->render (document, rc);
+}
+
+const gchar *
+ev_document_get_uri (EvDocument *document)
+{
+ g_return_val_if_fail (EV_IS_DOCUMENT (document), NULL);
+
+ return document->priv->uri;
+}
+
+const gchar *
+ev_document_get_title (EvDocument *document)
+{
+ g_return_val_if_fail (EV_IS_DOCUMENT (document), NULL);
+
+ return (document->priv->info->fields_mask & EV_DOCUMENT_INFO_TITLE) ?
+ document->priv->info->title : NULL;
+}
+
+gboolean
+ev_document_is_page_size_uniform (EvDocument *document)
+{
+ g_return_val_if_fail (EV_IS_DOCUMENT (document), TRUE);
+
+ return document->priv->uniform;
+}
+
+void
+ev_document_get_max_page_size (EvDocument *document,
+ gdouble *width,
+ gdouble *height)
+{
+ g_return_if_fail (EV_IS_DOCUMENT (document));
+
+ if (width)
+ *width = document->priv->max_width;
+ if (height)
+ *height = document->priv->max_height;
+}
+
+void
+ev_document_get_min_page_size (EvDocument *document,
+ gdouble *width,
+ gdouble *height)
+{
+ g_return_if_fail (EV_IS_DOCUMENT (document));
+
+ if (width)
+ *width = document->priv->min_width;
+ if (height)
+ *height = document->priv->min_height;
+}
+
+gboolean
+ev_document_check_dimensions (EvDocument *document)
+{
+ g_return_val_if_fail (EV_IS_DOCUMENT (document), FALSE);
+
+ return (document->priv->max_width > 0 && document->priv->max_height > 0);
+}
+
+gint
+ev_document_get_max_label_len (EvDocument *document)
+{
+ g_return_val_if_fail (EV_IS_DOCUMENT (document), -1);
+
+ return document->priv->max_label;
+}
+
+gboolean
+ev_document_has_text_page_labels (EvDocument *document)
+{
+ g_return_val_if_fail (EV_IS_DOCUMENT (document), FALSE);
+
+ return document->priv->page_labels != NULL;
+}
+
+gboolean
+ev_document_find_page_by_label (EvDocument *document,
+ const gchar *page_label,
+ gint *page_index)
+{
+ gint i, page;
+ glong value;
+ gchar *endptr = NULL;
+ EvDocumentPrivate *priv = document->priv;
+
+ g_return_val_if_fail (EV_IS_DOCUMENT (document), FALSE);
+ g_return_val_if_fail (page_label != NULL, FALSE);
+ g_return_val_if_fail (page_index != NULL, FALSE);
+
+ /* First, look for a literal label match */
+ for (i = 0; priv->page_labels && i < priv->n_pages; i ++) {
+ if (priv->page_labels[i] != NULL &&
+ ! strcmp (page_label, priv->page_labels[i])) {
+ *page_index = i;
+ return TRUE;
+ }
+ }
+
+ /* Second, look for a match with case insensitively */
+ for (i = 0; priv->page_labels && i < priv->n_pages; i++) {
+ if (priv->page_labels[i] != NULL &&
+ ! strcasecmp (page_label, priv->page_labels[i])) {
+ *page_index = i;
+ return TRUE;
+ }
+ }
+
+ /* Next, parse the label, and see if the number fits */
+ value = strtol (page_label, &endptr, 10);
+ if (endptr[0] == '\0') {
+ /* Page number is an integer */
+ page = MIN (G_MAXINT, value);
+
+ /* convert from a page label to a page offset */
+ page --;
+ if (page >= 0 && page < priv->n_pages) {
+ *page_index = page;
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+/* EvDocumentInfo */
+EV_DEFINE_BOXED_TYPE (EvDocumentInfo, ev_document_info, ev_document_info_copy, ev_document_info_free)
+
+EvDocumentInfo *
+ev_document_info_copy (EvDocumentInfo *info)
+{
+ EvDocumentInfo *copy;
+
+ g_return_val_if_fail (info != NULL, NULL);
+
+ copy = g_new0 (EvDocumentInfo, 1);
+ copy->title = g_strdup (info->title);
+ copy->format = g_strdup (info->format);
+ copy->author = g_strdup (info->author);
+ copy->subject = g_strdup (info->subject);
+ copy->keywords = g_strdup (info->keywords);
+ copy->security = g_strdup (info->security);
+ copy->creator = g_strdup (info->creator);
+ copy->producer = g_strdup (info->producer);
+ copy->linearized = g_strdup (info->linearized);
+
+ copy->creation_date = info->creation_date;
+ copy->modified_date = info->modified_date;
+ copy->layout = info->layout;
+ copy->mode = info->mode;
+ copy->ui_hints = info->ui_hints;
+ copy->permissions = info->permissions;
+ copy->n_pages = info->n_pages;
+ copy->license = ev_document_license_copy (info->license);
+
+ copy->fields_mask = info->fields_mask;
+
+ return copy;
+}
+
+void
+ev_document_info_free (EvDocumentInfo *info)
+{
+ if (info == NULL)
+ return;
+
+ g_free (info->title);
+ g_free (info->format);
+ g_free (info->author);
+ g_free (info->subject);
+ g_free (info->keywords);
+ g_free (info->creator);
+ g_free (info->producer);
+ g_free (info->linearized);
+ g_free (info->security);
+ ev_document_license_free (info->license);
+
+ g_free (info);
+}
+
+/* EvDocumentLicense */
+EV_DEFINE_BOXED_TYPE (EvDocumentLicense, ev_document_license, ev_document_license_copy, ev_document_license_free)
+
+EvDocumentLicense *
+ev_document_license_new (void)
+{
+ return g_new0 (EvDocumentLicense, 1);
+}
+
+EvDocumentLicense *
+ev_document_license_copy (EvDocumentLicense *license)
+{
+ EvDocumentLicense *new_license;
+
+ if (!license)
+ return NULL;
+
+ new_license = ev_document_license_new ();
+
+ if (license->text)
+ new_license->text = g_strdup (license->text);
+ if (license->uri)
+ new_license->uri = g_strdup (license->uri);
+ if (license->web_statement)
+ new_license->web_statement = g_strdup (license->web_statement);
+
+ return new_license;
+}
+
+void
+ev_document_license_free (EvDocumentLicense *license)
+{
+ if (!license)
+ return;
+
+ g_free (license->text);
+ g_free (license->uri);
+ g_free (license->web_statement);
+
+ g_free (license);
+}
+
+const gchar *
+ev_document_license_get_text (EvDocumentLicense *license)
+{
+ return license->text;
+}
+
+const gchar *
+ev_document_license_get_uri (EvDocumentLicense *license)
+{
+ return license->uri;
+}
+
+const gchar *
+ev_document_license_get_web_statement (EvDocumentLicense *license)
+{
+ return license->web_statement;
+}
+
+/* EvRectangle */
+EV_DEFINE_BOXED_TYPE (EvRectangle, ev_rectangle, ev_rectangle_copy, ev_rectangle_free)
+
+EvRectangle *
+ev_rectangle_new (void)
+{
+ return g_new0 (EvRectangle, 1);
+}
+
+EvRectangle *
+ev_rectangle_copy (EvRectangle *rectangle)
+{
+ EvRectangle *new_rectangle;
+
+ g_return_val_if_fail (rectangle != NULL, NULL);
+
+ new_rectangle = g_new (EvRectangle, 1);
+ *new_rectangle = *rectangle;
+
+ return new_rectangle;
+}
+
+void
+ev_rectangle_free (EvRectangle *rectangle)
+{
+ g_free (rectangle);
+}
+
+/* Compares two rects. returns 0 if they're equal */
+#define EPSILON 0.0000001
+
+gint
+ev_rect_cmp (EvRectangle *a,
+ EvRectangle *b)
+{
+ if (a == b)
+ return 0;
+ if (a == NULL || b == NULL)
+ return 1;
+
+ return ! ((ABS (a->x1 - b->x1) < EPSILON) &&
+ (ABS (a->y1 - b->y1) < EPSILON) &&
+ (ABS (a->x2 - b->x2) < EPSILON) &&
+ (ABS (a->y2 - b->y2) < EPSILON));
+}
diff --git a/libdocument/ev-document.h b/libdocument/ev-document.h
new file mode 100644
index 00000000..a3fe0727
--- /dev/null
+++ b/libdocument/ev-document.h
@@ -0,0 +1,303 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; c-indent-level: 8 -*- */
+/*
+ * Copyright (C) 2009 Carlos Garcia Campos
+ * Copyright (C) 2000-2003 Marco Pesenti Gritti
+ *
+ * This program 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, or (at your option)
+ * any later version.
+ *
+ * This program 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.
+ *
+ * $Id$
+ */
+
+#if !defined (__EV_EVINCE_DOCUMENT_H_INSIDE__) && !defined (EVINCE_COMPILATION)
+#error "Only <evince-document.h> can be included directly."
+#endif
+
+#ifndef EV_DOCUMENT_H
+#define EV_DOCUMENT_H
+
+#include <glib-object.h>
+#include <glib.h>
+#include <gdk/gdk.h>
+#include <cairo.h>
+
+#include "ev-document-info.h"
+#include "ev-page.h"
+#include "ev-render-context.h"
+
+G_BEGIN_DECLS
+
+#define EV_TYPE_DOCUMENT (ev_document_get_type ())
+#define EV_DOCUMENT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EV_TYPE_DOCUMENT, EvDocument))
+#define EV_DOCUMENT_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), EV_TYPE_DOCUMENT, EvDocumentClass))
+#define EV_IS_DOCUMENT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EV_TYPE_DOCUMENT))
+#define EV_IS_DOCUMENT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EV_TYPE_DOCUMENT))
+#define EV_DOCUMENT_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), EV_TYPE_DOCUMENT, EvDocumentClass))
+
+typedef struct _EvDocument EvDocument;
+typedef struct _EvDocumentClass EvDocumentClass;
+typedef struct _EvDocumentPrivate EvDocumentPrivate;
+
+#define EV_DOCUMENT_ERROR ev_document_error_quark ()
+#define EV_DOC_MUTEX_LOCK (ev_document_doc_mutex_lock ())
+#define EV_DOC_MUTEX_UNLOCK (ev_document_doc_mutex_unlock ())
+
+typedef enum
+{
+ EV_DOCUMENT_ERROR_INVALID,
+ EV_DOCUMENT_ERROR_ENCRYPTED
+} EvDocumentError;
+
+typedef struct {
+ double x;
+ double y;
+} EvPoint;
+
+typedef struct _EvRectangle EvRectangle;
+typedef struct _EvMapping EvMapping;
+
+typedef struct _EvDocumentBackendInfo EvDocumentBackendInfo;
+struct _EvDocumentBackendInfo
+{
+ const gchar *name;
+ const gchar *version;
+};
+
+typedef struct {
+ const gchar *filename;
+ gint line;
+ gint col;
+} EvSourceLink;
+
+struct _EvDocument
+{
+ GObject base;
+
+ EvDocumentPrivate *priv;
+};
+
+struct _EvDocumentClass
+{
+ GObjectClass base_class;
+
+ /* Virtual Methods */
+ gboolean (* load) (EvDocument *document,
+ const char *uri,
+ GError **error);
+ gboolean (* save) (EvDocument *document,
+ const char *uri,
+ GError **error);
+ gint (* get_n_pages) (EvDocument *document);
+ EvPage * (* get_page) (EvDocument *document,
+ gint index);
+ void (* get_page_size) (EvDocument *document,
+ EvPage *page,
+ double *width,
+ double *height);
+ gchar * (* get_page_label) (EvDocument *document,
+ EvPage *page);
+ cairo_surface_t * (* render) (EvDocument *document,
+ EvRenderContext *rc);
+ EvDocumentInfo * (* get_info) (EvDocument *document);
+ gboolean (* get_backend_info)(EvDocument *document,
+ EvDocumentBackendInfo *info);
+ gboolean (* support_synctex) (EvDocument *document);
+};
+
+GType ev_document_get_type (void) G_GNUC_CONST;
+GQuark ev_document_error_quark (void);
+
+/* Document mutex */
+GMutex *ev_document_get_doc_mutex (void);
+void ev_document_doc_mutex_lock (void);
+void ev_document_doc_mutex_unlock (void);
+gboolean ev_document_doc_mutex_trylock (void);
+
+/* FontConfig mutex */
+GMutex *ev_document_get_fc_mutex (void);
+void ev_document_fc_mutex_lock (void);
+void ev_document_fc_mutex_unlock (void);
+gboolean ev_document_fc_mutex_trylock (void);
+
+EvDocumentInfo *ev_document_get_info (EvDocument *document);
+gboolean ev_document_get_backend_info (EvDocument *document,
+ EvDocumentBackendInfo *info);
+gboolean ev_document_load (EvDocument *document,
+ const char *uri,
+ GError **error);
+gboolean ev_document_save (EvDocument *document,
+ const char *uri,
+ GError **error);
+gint ev_document_get_n_pages (EvDocument *document);
+EvPage *ev_document_get_page (EvDocument *document,
+ gint index);
+void ev_document_get_page_size (EvDocument *document,
+ gint page_index,
+ double *width,
+ double *height);
+gchar *ev_document_get_page_label (EvDocument *document,
+ gint page_index);
+cairo_surface_t *ev_document_render (EvDocument *document,
+ EvRenderContext *rc);
+const gchar *ev_document_get_uri (EvDocument *document);
+const gchar *ev_document_get_title (EvDocument *document);
+gboolean ev_document_is_page_size_uniform (EvDocument *document);
+void ev_document_get_max_page_size (EvDocument *document,
+ gdouble *width,
+ gdouble *height);
+void ev_document_get_min_page_size (EvDocument *document,
+ gdouble *width,
+ gdouble *height);
+gboolean ev_document_check_dimensions (EvDocument *document);
+gint ev_document_get_max_label_len (EvDocument *document);
+gboolean ev_document_has_text_page_labels (EvDocument *document);
+gboolean ev_document_find_page_by_label (EvDocument *document,
+ const gchar *page_label,
+ gint *page_index);
+gboolean ev_document_has_synctex (EvDocument *document);
+
+EvSourceLink *ev_document_synctex_backward_search
+ (EvDocument *document,
+ gint page_index,
+ gfloat x,
+ gfloat y);
+
+EvMapping *ev_document_synctex_forward_search
+ (EvDocument *document,
+ EvSourceLink *source_link);
+
+gint ev_rect_cmp (EvRectangle *a,
+ EvRectangle *b);
+
+#define EV_TYPE_RECTANGLE (ev_rectangle_get_type ())
+struct _EvRectangle
+{
+ gdouble x1;
+ gdouble y1;
+ gdouble x2;
+ gdouble y2;
+};
+
+GType ev_rectangle_get_type (void) G_GNUC_CONST;
+EvRectangle *ev_rectangle_new (void);
+EvRectangle *ev_rectangle_copy (EvRectangle *ev_rect);
+void ev_rectangle_free (EvRectangle *ev_rect);
+
+struct _EvMapping {
+ EvRectangle area;
+ gpointer data;
+};
+
+/* convenience macro to ease interface addition in the CODE
+ * section of EV_BACKEND_REGISTER_WITH_CODE (this macro relies on
+ * the g_define_type_id present within EV_BACKEND_REGISTER_WITH_CODE()).
+ * usage example:
+ * EV_BACKEND_REGISTER_WITH_CODE (PdfDocument, pdf_document,
+ * EV_BACKEND_IMPLEMENT_INTERFACE (EV_TYPE_DOCUMENT_THUMBNAILS,
+ * pdf_document_document_thumbnails_iface_init));
+ */
+#define EV_BACKEND_IMPLEMENT_INTERFACE(TYPE_IFACE, iface_init) { \
+ const GInterfaceInfo g_implement_interface_info = { \
+ (GInterfaceInitFunc) iface_init, NULL, NULL \
+ }; \
+ g_type_module_add_interface (module, \
+ g_define_type_id, \
+ TYPE_IFACE, \
+ &g_implement_interface_info); \
+}
+
+/*
+ * Utility macro used to register backends
+ *
+ * use: EV_BACKEND_REGISTER_WITH_CODE(BackendName, backend_name, CODE)
+ */
+#define EV_BACKEND_REGISTER_WITH_CODE(BackendName, backend_name, CODE) \
+ \
+static GType g_define_type_id = 0; \
+ \
+GType \
+backend_name##_get_type (void) \
+{ \
+ return g_define_type_id; \
+} \
+ \
+static void backend_name##_init (BackendName *self); \
+static void backend_name##_class_init (BackendName##Class *klass); \
+static gpointer backend_name##_parent_class = NULL; \
+static void backend_name##_class_intern_init (gpointer klass) \
+{ \
+ backend_name##_parent_class = g_type_class_peek_parent (klass); \
+ backend_name##_class_init ((BackendName##Class *) klass); \
+} \
+ \
+G_MODULE_EXPORT GType \
+register_evince_backend (GTypeModule *module) \
+{ \
+ const GTypeInfo our_info = { \
+ sizeof (BackendName##Class), \
+ NULL, /* base_init */ \
+ NULL, /* base_finalize */ \
+ (GClassInitFunc) backend_name##_class_intern_init, \
+ NULL, \
+ NULL, /* class_data */ \
+ sizeof (BackendName), \
+ 0, /* n_preallocs */ \
+ (GInstanceInitFunc) backend_name##_init \
+ }; \
+ \
+ /* Initialise the i18n stuff */ \
+ bindtextdomain (GETTEXT_PACKAGE, MATELOCALEDIR); \
+ bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); \
+ \
+ g_define_type_id = g_type_module_register_type (module, \
+ EV_TYPE_DOCUMENT, \
+ #BackendName, \
+ &our_info, \
+ (GTypeFlags)0); \
+ \
+ CODE \
+ \
+ return g_define_type_id; \
+}
+
+/*
+ * Utility macro used to register backend
+ *
+ * use: EV_BACKEND_REGISTER(BackendName, backend_name)
+ */
+#define EV_BACKEND_REGISTER(BackendName, backend_name) \
+ EV_BACKEND_REGISTER_WITH_CODE(BackendName, backend_name, ;)
+
+/*
+ * A convenience macro for boxed type implementations, which defines a
+ * type_name_get_type() function registering the boxed type.
+ */
+#define EV_DEFINE_BOXED_TYPE(TypeName, type_name, copy_func, free_func) \
+GType \
+type_name##_get_type (void) \
+{ \
+ static volatile gsize g_define_type_id__volatile = 0; \
+ if (g_once_init_enter (&g_define_type_id__volatile)) { \
+ GType g_define_type_id = \
+ g_boxed_type_register_static (g_intern_static_string (#TypeName), \
+ (GBoxedCopyFunc) copy_func, \
+ (GBoxedFreeFunc) free_func); \
+ g_once_init_leave (&g_define_type_id__volatile, g_define_type_id); \
+ } \
+ return g_define_type_id__volatile; \
+}
+
+G_END_DECLS
+
+#endif /* EV_DOCUMENT_H */
diff --git a/libdocument/ev-file-exporter.c b/libdocument/ev-file-exporter.c
new file mode 100644
index 00000000..c6ca7e12
--- /dev/null
+++ b/libdocument/ev-file-exporter.c
@@ -0,0 +1,84 @@
+/* this file is part of evince, a mate document viewer
+ *
+ * Copyright (C) 2004 Martin Kretzschmar
+ *
+ * Author:
+ * Martin Kretzschmar <[email protected]>
+ *
+ * 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-file-exporter.h"
+#include "ev-document.h"
+
+G_DEFINE_INTERFACE (EvFileExporter, ev_file_exporter, 0)
+
+static void
+ev_file_exporter_default_init (EvFileExporterInterface *klass)
+{
+}
+
+void
+ev_file_exporter_begin (EvFileExporter *exporter,
+ EvFileExporterContext *fc)
+{
+ EvFileExporterInterface *iface = EV_FILE_EXPORTER_GET_IFACE (exporter);
+
+ iface->begin (exporter, fc);
+}
+
+void
+ev_file_exporter_begin_page (EvFileExporter *exporter)
+{
+ EvFileExporterInterface *iface = EV_FILE_EXPORTER_GET_IFACE (exporter);
+
+ if (iface->begin_page)
+ iface->begin_page (exporter);
+}
+
+void
+ev_file_exporter_do_page (EvFileExporter *exporter,
+ EvRenderContext *rc)
+{
+ EvFileExporterInterface *iface = EV_FILE_EXPORTER_GET_IFACE (exporter);
+
+ iface->do_page (exporter, rc);
+}
+
+void
+ev_file_exporter_end_page (EvFileExporter *exporter)
+{
+ EvFileExporterInterface *iface = EV_FILE_EXPORTER_GET_IFACE (exporter);
+
+ if (iface->end_page)
+ iface->end_page (exporter);
+}
+
+void
+ev_file_exporter_end (EvFileExporter *exporter)
+{
+ EvFileExporterInterface *iface = EV_FILE_EXPORTER_GET_IFACE (exporter);
+
+ iface->end (exporter);
+}
+
+EvFileExporterCapabilities
+ev_file_exporter_get_capabilities (EvFileExporter *exporter)
+{
+ EvFileExporterInterface *iface = EV_FILE_EXPORTER_GET_IFACE (exporter);
+
+ return iface->get_capabilities (exporter);
+}
diff --git a/libdocument/ev-file-exporter.h b/libdocument/ev-file-exporter.h
new file mode 100644
index 00000000..b1434e4d
--- /dev/null
+++ b/libdocument/ev-file-exporter.h
@@ -0,0 +1,101 @@
+/* this file is part of evince, a mate document viewer
+ *
+ * Copyright (C) 2004 Martin Kretzschmar
+ *
+ * Author:
+ * Martin Kretzschmar <[email protected]>
+ *
+ * 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.
+ */
+
+#if !defined (__EV_EVINCE_DOCUMENT_H_INSIDE__) && !defined (EVINCE_COMPILATION)
+#error "Only <evince-document.h> can be included directly."
+#endif
+
+#ifndef EV_FILE_EXPORTER_H
+#define EV_FILE_EXPORTER_H
+
+#include <glib-object.h>
+
+#include "ev-render-context.h"
+
+G_BEGIN_DECLS
+
+typedef enum {
+ EV_FILE_FORMAT_UNKNOWN,
+ EV_FILE_FORMAT_PS,
+ EV_FILE_FORMAT_PDF
+} EvFileExporterFormat;
+
+typedef enum {
+ EV_FILE_EXPORTER_CAN_PAGE_SET = 1 << 0,
+ EV_FILE_EXPORTER_CAN_COPIES = 1 << 1,
+ EV_FILE_EXPORTER_CAN_COLLATE = 1 << 2,
+ EV_FILE_EXPORTER_CAN_REVERSE = 1 << 3,
+ EV_FILE_EXPORTER_CAN_SCALE = 1 << 4,
+ EV_FILE_EXPORTER_CAN_GENERATE_PDF = 1 << 5,
+ EV_FILE_EXPORTER_CAN_GENERATE_PS = 1 << 6,
+ EV_FILE_EXPORTER_CAN_PREVIEW = 1 << 7,
+ EV_FILE_EXPORTER_CAN_NUMBER_UP = 1 << 8
+} EvFileExporterCapabilities;
+
+typedef struct {
+ EvFileExporterFormat format;
+ const gchar *filename;
+ gint first_page;
+ gint last_page;
+ gdouble paper_width;
+ gdouble paper_height;
+ gboolean duplex;
+ gint pages_per_sheet;
+} EvFileExporterContext;
+
+#define EV_TYPE_FILE_EXPORTER (ev_file_exporter_get_type ())
+#define EV_FILE_EXPORTER(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EV_TYPE_FILE_EXPORTER, EvFileExporter))
+#define EV_FILE_EXPORTER_IFACE(k) (G_TYPE_CHECK_CLASS_CAST((k), EV_TYPE_FILE_EXPORTER, EvFileExporterInterface))
+#define EV_IS_FILE_EXPORTER(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EV_TYPE_FILE_EXPORTER))
+#define EV_IS_FILE_EXPORTER_IFACE(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EV_TYPE_FILE_EXPORTER))
+#define EV_FILE_EXPORTER_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), EV_TYPE_FILE_EXPORTER, EvFileExporterInterface))
+
+typedef struct _EvFileExporter EvFileExporter;
+typedef struct _EvFileExporterInterface EvFileExporterInterface;
+
+struct _EvFileExporterInterface {
+ GTypeInterface base_iface;
+
+ /* Methods */
+ void (* begin) (EvFileExporter *exporter,
+ EvFileExporterContext *fc);
+ void (* begin_page) (EvFileExporter *exporter);
+ void (* do_page) (EvFileExporter *exporter,
+ EvRenderContext *rc);
+ void (* end_page) (EvFileExporter *exporter);
+ void (* end) (EvFileExporter *exporter);
+ EvFileExporterCapabilities (* get_capabilities) (EvFileExporter *exporter);
+};
+
+GType ev_file_exporter_get_type (void) G_GNUC_CONST;
+void ev_file_exporter_begin (EvFileExporter *exporter,
+ EvFileExporterContext *fc);
+void ev_file_exporter_begin_page (EvFileExporter *exporter);
+void ev_file_exporter_do_page (EvFileExporter *exporter,
+ EvRenderContext *rc);
+void ev_file_exporter_end_page (EvFileExporter *exporter);
+void ev_file_exporter_end (EvFileExporter *exporter);
+EvFileExporterCapabilities ev_file_exporter_get_capabilities (EvFileExporter *exporter);
+
+G_END_DECLS
+
+#endif
diff --git a/libdocument/ev-file-helpers.c b/libdocument/ev-file-helpers.c
new file mode 100644
index 00000000..b6ecb244
--- /dev/null
+++ b/libdocument/ev-file-helpers.c
@@ -0,0 +1,683 @@
+/*
+ * Copyright (C) 2002 Jorn Baayen
+ * Copyright © 2009 Christian Persch
+ *
+ * This program 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, or (at your option)
+ * any later version.
+ *
+ * This program 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 <stdlib.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+
+#include <glib.h>
+#include <glib/gstdio.h>
+#include <glib/gi18n-lib.h>
+
+#include "ev-file-helpers.h"
+
+static gchar *tmp_dir = NULL;
+
+/*
+ * ev_dir_ensure_exists:
+ * @dir: the directory name
+ * @mode: permissions to use when creating the directory
+ * @error: a location to store a #GError
+ *
+ * Create @dir recursively with permissions @mode.
+ *
+ * Returns: %TRUE on success, or %FALSE on error with @error filled in
+ */
+static gboolean
+_ev_dir_ensure_exists (const gchar *dir,
+ int mode,
+ GError **error)
+{
+ int errsv;
+ char *display_name;
+
+ g_return_val_if_fail (dir != NULL, FALSE);
+
+ errno = 0;
+ if (g_mkdir_with_parents (dir, mode) == 0)
+ return TRUE;
+
+ errsv = errno;
+ if (errsv == EEXIST && g_file_test (dir, G_FILE_TEST_IS_DIR))
+ return TRUE;
+
+ display_name = g_filename_display_name (dir);
+ g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv),
+ "Failed to create directory '%s': %s",
+ display_name, g_strerror (errsv));
+ g_free (display_name);
+
+ return FALSE;
+}
+
+/*
+ * _ev_tmp_dir:
+ * @error: a location to store a #GError
+ *
+ * Returns the tmp directory.
+ *
+ * Returns: the tmp directory, or %NULL with @error filled in if the
+ * directory could not be created
+ */
+static const char *
+_ev_tmp_dir (GError **error)
+{
+
+ if (tmp_dir == NULL) {
+ gchar *dirname, *prgname;
+
+ prgname = g_get_prgname ();
+ dirname = g_strdup_printf ("%s-%u", prgname ? prgname : "unknown", getpid ());
+ tmp_dir = g_build_filename (g_get_tmp_dir (), dirname, NULL);
+ g_free (dirname);
+ }
+
+ if (!_ev_dir_ensure_exists (tmp_dir, 0700, error))
+ return NULL;
+
+ return tmp_dir;
+}
+
+void
+_ev_file_helpers_init (void)
+{
+}
+
+void
+_ev_file_helpers_shutdown (void)
+{
+ if (tmp_dir != NULL)
+ g_rmdir (tmp_dir);
+
+ g_free (tmp_dir);
+ tmp_dir = NULL;
+}
+
+/**
+ * ev_mkstemp:
+ * @template: a template string; must contain 'XXXXXX', but not necessarily as a suffix
+ * @file_name: a location to store the filename of the temp file
+ * @error: a location to store a #GError
+ *
+ * Creates a temp file in the evince temp directory.
+ *
+ * Returns: a file descriptor to the newly created temp file name, or %-1
+ * on error with @error filled in
+ */
+int
+ev_mkstemp (const char *template,
+ char **file_name,
+ GError **error)
+{
+ const char *tmp;
+ char *name;
+ int fd;
+
+ if ((tmp = _ev_tmp_dir (error)) == NULL)
+ return -1;
+
+ name = g_build_filename (tmp, template, NULL);
+ fd = g_mkstemp (name);
+
+ if (fd == -1) {
+ int errsv = errno;
+
+ g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv),
+ _("Failed to create a temporary file: %s"),
+ g_strerror (errsv));
+
+ g_free (name);
+ return -1;
+ }
+
+ if (file_name)
+ *file_name = name;
+
+ return fd;
+}
+
+static void
+close_fd_cb (gpointer fdptr)
+{
+ int fd = GPOINTER_TO_INT (fdptr);
+
+ close (fd);
+}
+
+/**
+ * ev_mkstemp_file:
+ * @template: a template string; must contain 'XXXXXX', but not necessarily as a suffix
+ * @error: a location to store a #GError
+ *
+ * Creates a temp #GFile in the evince temp directory. See ev_mkstemp() for more information.
+ *
+ * Returns: a newly allocated #GFile for the newly created temp file name, or %NULL
+ * on error with @error filled in
+ */
+GFile *
+ev_mkstemp_file (const char *template,
+ GError **error)
+{
+ char *file_name;
+ int fd;
+ GFile *file;
+
+ fd = ev_mkstemp (template, &file_name, error);
+ if (fd == -1)
+ return NULL;
+
+ file = g_file_new_for_path (file_name);
+ g_free (file_name);
+
+ g_object_set_data_full (G_OBJECT (file), "ev-mkstemp-fd",
+ GINT_TO_POINTER (fd), (GDestroyNotify) close_fd_cb);
+
+ return file;
+}
+
+/**
+ * This function is copied from
+ * http://bugzilla.mate.org/show_bug.cgi?id=524831
+ * and renamed from g_mkdtemp to _ev_g_mkdtemp.
+ *
+ * If/when this function gets added to glib, it can be removed from
+ * evince' sources.
+ *
+ *
+ * g_mkdtemp:
+ * @tmpl: template directory name
+ *
+ * Creates a temporary directory. See the mkdtemp() documentation
+ * on most UNIX-like systems.
+ *
+ * The parameter is a string that should follow the rules for
+ * mkdtemp() templates, i.e. contain the string "XXXXXX". g_mkdtemp()
+ * is slightly more flexible than mkdtemp() in that the sequence does
+ * not have to occur at the very end of the template. The X string
+ * will be modified to form the name of a directory that didn't
+ * already exist. The string should be in the GLib file name
+ * encoding. Most importantly, on Windows it should be in UTF-8.
+ *
+ * Return value: If a temporary directory was successfully created,
+ * @tmpl will be returned with the XXXXXX string modified in such a
+ * way as to make the path unique. In case of errors, %NULL is
+ * returned.
+ */
+static gchar *
+_ev_g_mkdtemp (gchar *tmpl)
+{
+ static const char letters[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+ static const int NLETTERS = sizeof (letters) - 1;
+ static int counter = 0;
+ char *XXXXXX;
+ GTimeVal tv;
+ glong value;
+ int count;
+
+ /* find the last occurrence of "XXXXXX" */
+ XXXXXX = g_strrstr (tmpl, "XXXXXX");
+
+ if (!XXXXXX || strncmp (XXXXXX, "XXXXXX", 6))
+ {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ /* Get some more or less random data. */
+ g_get_current_time (&tv);
+ value = (tv.tv_usec ^ tv.tv_sec) + counter++;
+
+ for (count = 0; count < 100; value += 7777, ++count)
+ {
+ glong v = value;
+
+ /* Fill in the random bits. */
+ XXXXXX[0] = letters[v % NLETTERS];
+ v /= NLETTERS;
+ XXXXXX[1] = letters[v % NLETTERS];
+ v /= NLETTERS;
+ XXXXXX[2] = letters[v % NLETTERS];
+ v /= NLETTERS;
+ XXXXXX[3] = letters[v % NLETTERS];
+ v /= NLETTERS;
+ XXXXXX[4] = letters[v % NLETTERS];
+ v /= NLETTERS;
+ XXXXXX[5] = letters[v % NLETTERS];
+
+ /* tmpl is in UTF-8 on Windows, thus use g_mkdir() */
+ if (g_mkdir (tmpl, 0700) == 0)
+ return tmpl;
+
+ if (errno != EEXIST)
+ /* Any other error will apply also to other names we might
+ * try, and there are 2^32 or so of them, so give up now.
+ */
+ return NULL;
+ }
+
+ /* We got out of the loop because we ran out of combinations to try. */
+ errno = EEXIST;
+ return NULL;
+}
+
+/**
+ * ev_mkdtemp:
+ * @template: a template string; must end in 'XXXXXX'
+ * @error: a location to store a #GError
+ *
+ * Creates a temp directory in the evince temp directory.
+ *
+ * Returns: a newly allocated string with the temp directory name, or %NULL
+ * on error with @error filled in
+ */
+gchar *
+ev_mkdtemp (const char *template,
+ GError **error)
+{
+ const char *tmp;
+ char *name;
+
+ if ((tmp = _ev_tmp_dir (error)) == NULL)
+ return NULL;
+
+ name = g_build_filename (tmp, template, NULL);
+ if (_ev_g_mkdtemp (name) == NULL) {
+ int errsv = errno;
+
+ g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errsv),
+ _("Failed to create a temporary directory: %s"),
+ g_strerror (errsv));
+
+ g_free (name);
+ return NULL;
+ }
+
+ return name;
+}
+
+/* Remove a local temp file created by evince */
+void
+ev_tmp_filename_unlink (const gchar *filename)
+{
+ if (!filename)
+ return;
+
+ if (!tmp_dir)
+ return;
+
+ if (g_str_has_prefix (filename, tmp_dir)) {
+ g_unlink (filename);
+ }
+}
+
+void
+ev_tmp_file_unlink (GFile *file)
+{
+ gboolean res;
+ GError *error = NULL;
+
+ if (!file)
+ return;
+
+ res = g_file_delete (file, NULL, &error);
+ if (!res) {
+ char *uri;
+
+ uri = g_file_get_uri (file);
+ g_warning ("Unable to delete temp file %s: %s\n", uri, error->message);
+ g_free (uri);
+ g_error_free (error);
+ }
+}
+
+void
+ev_tmp_uri_unlink (const gchar *uri)
+{
+ GFile *file;
+
+ if (!uri)
+ return;
+
+ file = g_file_new_for_uri (uri);
+ if (!g_file_is_native (file)) {
+ g_warning ("Attempting to delete non native uri: %s\n", uri);
+ g_object_unref (file);
+ return;
+ }
+
+ ev_tmp_file_unlink (file);
+ g_object_unref (file);
+}
+
+gboolean
+ev_file_is_temp (GFile *file)
+{
+ gchar *path;
+ gboolean retval;
+
+ if (!g_file_is_native (file))
+ return FALSE;
+
+ path = g_file_get_path (file);
+ if (!path)
+ return FALSE;
+
+ retval = g_str_has_prefix (path, g_get_tmp_dir ());
+ g_free (path);
+
+ return retval;
+}
+
+/**
+ * ev_xfer_uri_simple:
+ * @from: the source URI
+ * @to: the target URI
+ * @error: a #GError location to store an error, or %NULL
+ *
+ * Performs a g_file_copy() from @from to @to.
+ *
+ * Returns: %TRUE on success, or %FALSE on error with @error filled in
+ */
+gboolean
+ev_xfer_uri_simple (const char *from,
+ const char *to,
+ GError **error)
+{
+ GFile *source_file;
+ GFile *target_file;
+ gboolean result;
+
+ if (!from)
+ return TRUE;
+
+ g_return_val_if_fail (to != NULL, TRUE);
+
+ source_file = g_file_new_for_uri (from);
+ target_file = g_file_new_for_uri (to);
+
+ result = g_file_copy (source_file, target_file,
+ G_FILE_COPY_TARGET_DEFAULT_PERMS |
+ G_FILE_COPY_OVERWRITE,
+ NULL, NULL, NULL, error);
+
+ g_object_unref (target_file);
+ g_object_unref (source_file);
+
+ return result;
+}
+
+static gchar *
+get_mime_type_from_uri (const gchar *uri, GError **error)
+{
+ GFile *file;
+ GFileInfo *file_info;
+ const gchar *content_type;
+ gchar *mime_type = NULL;
+
+ file = g_file_new_for_uri (uri);
+ file_info = g_file_query_info (file,
+ G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
+ 0, NULL, error);
+ g_object_unref (file);
+
+ if (file_info == NULL)
+ return NULL;
+
+ content_type = g_file_info_get_content_type (file_info);
+ if (content_type) {
+ mime_type = g_content_type_get_mime_type (content_type);
+ }
+
+ g_object_unref (file_info);
+ return mime_type;
+}
+
+static gchar *
+get_mime_type_from_data (const gchar *uri, GError **error)
+{
+#ifndef G_OS_WIN32
+ GFile *file;
+ GFileInputStream *input_stream;
+ gssize size_read;
+ guchar buffer[1024];
+ gboolean retval;
+ gchar *content_type, *mime_type;
+
+ file = g_file_new_for_uri (uri);
+
+ input_stream = g_file_read (file, NULL, error);
+ if (!input_stream) {
+ g_object_unref (file);
+ return NULL;
+ }
+
+ size_read = g_input_stream_read (G_INPUT_STREAM (input_stream),
+ buffer, sizeof (buffer), NULL, error);
+ if (size_read == -1) {
+ g_object_unref (input_stream);
+ g_object_unref (file);
+ return NULL;
+ }
+
+ retval = g_input_stream_close (G_INPUT_STREAM (input_stream), NULL, error);
+
+ g_object_unref (input_stream);
+ g_object_unref (file);
+ if (!retval)
+ return NULL;
+
+ content_type = g_content_type_guess (NULL, /* no filename */
+ buffer, size_read,
+ NULL);
+ if (!content_type)
+ return NULL;
+
+ mime_type = g_content_type_get_mime_type (content_type);
+ g_free (content_type);
+ return mime_type;
+#else
+ /*
+ * On Windows, the implementation of g_content_type_guess() is too limited at the moment, so we do not
+ * use it and fall back to get_mime_type_from_uri()
+ */
+ return get_mime_type_from_uri (uri, error);
+#endif /* G_OS_WIN32 */
+}
+
+/**
+ * ev_file_get_mime_type:
+ * @uri: the URI
+ * @fast: whether to use fast MIME type detection
+ * @error: a #GError location to store an error, or %NULL
+ *
+ * Note: on unknown MIME types, this may return NULL without @error
+ * being filled in.
+ *
+ * Returns: a newly allocated string with the MIME type of the file at
+ * @uri, or %NULL on error or if the MIME type could not be determined
+ */
+gchar *
+ev_file_get_mime_type (const gchar *uri,
+ gboolean fast,
+ GError **error)
+{
+ return fast ? get_mime_type_from_uri (uri, error) : get_mime_type_from_data (uri, error);
+}
+
+/* Compressed files support */
+#define BZIPCOMMAND "bzip2"
+#define GZIPCOMMAND "gzip"
+#define N_ARGS 4
+#define BUFFER_SIZE 1024
+
+static gchar *
+compression_run (const gchar *uri,
+ EvCompressionType type,
+ gboolean compress,
+ GError **error)
+{
+ gchar *argv[N_ARGS];
+ gchar *uri_dst = NULL;
+ gchar *filename, *filename_dst = NULL;
+ gchar *cmd;
+ gint fd, pout;
+ GError *err = NULL;
+
+ if (type == EV_COMPRESSION_NONE)
+ return NULL;
+
+ cmd = g_find_program_in_path ((type == EV_COMPRESSION_BZIP2) ? BZIPCOMMAND : GZIPCOMMAND);
+ if (!cmd) {
+ /* FIXME: better error codes! */
+ /* FIXME: i18n later */
+ g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
+ "Failed to find the \"%s\" command in the search path.",
+ type == EV_COMPRESSION_BZIP2 ? BZIPCOMMAND : GZIPCOMMAND);
+ return NULL;
+ }
+
+ filename = g_filename_from_uri (uri, NULL, error);
+ if (!filename) {
+ g_free (cmd);
+ return NULL;
+ }
+
+ fd = ev_mkstemp ("comp.XXXXXX", &filename_dst, error);
+ if (fd == -1) {
+ g_free (cmd);
+ g_free (filename);
+
+ return NULL;
+ }
+
+ argv[0] = cmd;
+ argv[1] = compress ? "-c" : "-cd";
+ argv[2] = filename;
+ argv[3] = NULL;
+
+ if (g_spawn_async_with_pipes (NULL, argv, NULL,
+ G_SPAWN_STDERR_TO_DEV_NULL,
+ NULL, NULL, NULL,
+ NULL, &pout, NULL, &err)) {
+ GIOChannel *in, *out;
+ gchar buf[BUFFER_SIZE];
+ GIOStatus read_st, write_st;
+ gsize bytes_read, bytes_written;
+
+ in = g_io_channel_unix_new (pout);
+ g_io_channel_set_encoding (in, NULL, NULL);
+ out = g_io_channel_unix_new (fd);
+ g_io_channel_set_encoding (out, NULL, NULL);
+
+ do {
+ read_st = g_io_channel_read_chars (in, buf,
+ BUFFER_SIZE,
+ &bytes_read,
+ error);
+ if (read_st == G_IO_STATUS_NORMAL) {
+ write_st = g_io_channel_write_chars (out, buf,
+ bytes_read,
+ &bytes_written,
+ error);
+ if (write_st == G_IO_STATUS_ERROR)
+ break;
+ } else if (read_st == G_IO_STATUS_ERROR) {
+ break;
+ }
+ } while (bytes_read > 0);
+
+ g_io_channel_unref (in);
+ g_io_channel_unref (out);
+ }
+
+ close (fd);
+
+ if (err) {
+ g_propagate_error (error, err);
+ } else {
+ uri_dst = g_filename_to_uri (filename_dst, NULL, error);
+ }
+
+ g_free (cmd);
+ g_free (filename);
+ g_free (filename_dst);
+
+ return uri_dst;
+}
+
+/**
+ * ev_file_uncompress:
+ * @uri: a file URI
+ * @type: the compression type
+ * @error: a #GError location to store an error, or %NULL
+ *
+ * Uncompresses the file at @uri.
+ *
+ * If @type is %EV_COMPRESSION_NONE, it does nothing and returns %NULL.
+ *
+ * Otherwise, it returns the filename of a
+ * temporary file containing the decompressed data from the file at @uri.
+ * On error it returns %NULL and fills in @error.
+ *
+ * It is the caller's responsibility to unlink the temp file after use.
+ *
+ * Returns: a newly allocated string URI, or %NULL on error
+ */
+gchar *
+ev_file_uncompress (const gchar *uri,
+ EvCompressionType type,
+ GError **error)
+{
+ g_return_val_if_fail (uri != NULL, NULL);
+
+ return compression_run (uri, type, FALSE, error);
+}
+
+/**
+ * ev_file_compress:
+ * @uri: a file URI
+ * @type: the compression type
+ * @error: a #GError location to store an error, or %NULL
+ *
+ * Compresses the file at @uri.
+
+ * If @type is %EV_COMPRESSION_NONE, it does nothing and returns %NULL.
+ *
+ * Otherwise, it returns the filename of a
+ * temporary file containing the compressed data from the file at @uri.
+ *
+ * On error it returns %NULL and fills in @error.
+ *
+ * It is the caller's responsibility to unlink the temp file after use.
+ *
+ * Returns: a newly allocated string URI, or %NULL on error
+ */
+gchar *
+ev_file_compress (const gchar *uri,
+ EvCompressionType type,
+ GError **error)
+{
+ g_return_val_if_fail (uri != NULL, NULL);
+
+ return compression_run (uri, type, TRUE, error);
+}
diff --git a/libdocument/ev-file-helpers.h b/libdocument/ev-file-helpers.h
new file mode 100644
index 00000000..fffae03f
--- /dev/null
+++ b/libdocument/ev-file-helpers.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2002 Jorn Baayen
+ *
+ * This program 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, or (at your option)
+ * any later version.
+ *
+ * This program 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.
+ *
+ */
+
+#if !defined (__EV_EVINCE_DOCUMENT_H_INSIDE__) && !defined (EVINCE_COMPILATION)
+#error "Only <evince-document.h> can be included directly."
+#endif
+
+#ifndef EV_FILE_HELPERS_H
+#define EV_FILE_HELPERS_H
+
+#include <glib.h>
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+typedef enum {
+ EV_COMPRESSION_NONE,
+ EV_COMPRESSION_BZIP2,
+ EV_COMPRESSION_GZIP
+} EvCompressionType;
+
+void _ev_file_helpers_init (void);
+
+void _ev_file_helpers_shutdown (void);
+
+int ev_mkstemp (const char *template,
+ char **file_name,
+ GError **error);
+GFile *ev_mkstemp_file (const char *template,
+ GError **error);
+gchar *ev_mkdtemp (const char *template,
+ GError **error);
+void ev_tmp_filename_unlink (const gchar *filename);
+void ev_tmp_file_unlink (GFile *file);
+void ev_tmp_uri_unlink (const gchar *uri);
+gboolean ev_file_is_temp (GFile *file);
+gboolean ev_xfer_uri_simple (const char *from,
+ const char *to,
+ GError **error);
+
+gchar *ev_file_get_mime_type (const gchar *uri,
+ gboolean fast,
+ GError **error);
+
+gchar *ev_file_uncompress (const gchar *uri,
+ EvCompressionType type,
+ GError **error);
+gchar *ev_file_compress (const gchar *uri,
+ EvCompressionType type,
+ GError **error);
+
+
+G_END_DECLS
+
+#endif /* EV_FILE_HELPERS_H */
diff --git a/libdocument/ev-form-field.c b/libdocument/ev-form-field.c
new file mode 100644
index 00000000..7bea0035
--- /dev/null
+++ b/libdocument/ev-form-field.c
@@ -0,0 +1,209 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; c-indent-level: 8 -*- */
+/* this file is part of evince, a mate document viewer
+ *
+ * Copyright (C) 2007 Carlos Garcia Campos <[email protected]>
+ * Copyright (C) 2006 Julien Rebetez
+ *
+ * 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-form-field.h"
+
+static void ev_form_field_init (EvFormField *field);
+static void ev_form_field_class_init (EvFormFieldClass *klass);
+static void ev_form_field_text_init (EvFormFieldText *field_text);
+static void ev_form_field_text_class_init (EvFormFieldTextClass *klass);
+static void ev_form_field_button_init (EvFormFieldButton *field_button);
+static void ev_form_field_button_class_init (EvFormFieldButtonClass *klass);
+static void ev_form_field_choice_init (EvFormFieldChoice *field_choice);
+static void ev_form_field_choice_class_init (EvFormFieldChoiceClass *klass);
+static void ev_form_field_signature_init (EvFormFieldSignature *field_choice);
+static void ev_form_field_signature_class_init (EvFormFieldSignatureClass *klass);
+
+G_DEFINE_ABSTRACT_TYPE (EvFormField, ev_form_field, G_TYPE_OBJECT)
+G_DEFINE_TYPE (EvFormFieldText, ev_form_field_text, EV_TYPE_FORM_FIELD)
+G_DEFINE_TYPE (EvFormFieldButton, ev_form_field_button, EV_TYPE_FORM_FIELD)
+G_DEFINE_TYPE (EvFormFieldChoice, ev_form_field_choice, EV_TYPE_FORM_FIELD)
+G_DEFINE_TYPE (EvFormFieldSignature, ev_form_field_signature, EV_TYPE_FORM_FIELD)
+
+static void
+ev_form_field_init (EvFormField *field)
+{
+ field->page = NULL;
+ field->changed = FALSE;
+ field->is_read_only = FALSE;
+}
+
+static void
+ev_form_field_finalize (GObject *object)
+{
+ EvFormField *field = EV_FORM_FIELD (object);
+
+ g_object_unref (field->page);
+ field->page = NULL;
+
+ (* G_OBJECT_CLASS (ev_form_field_parent_class)->finalize) (object);
+}
+
+static void
+ev_form_field_class_init (EvFormFieldClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = ev_form_field_finalize;
+}
+
+static void
+ev_form_field_text_finalize (GObject *object)
+{
+ EvFormFieldText *field_text = EV_FORM_FIELD_TEXT (object);
+
+ if (field_text->text) {
+ g_free (field_text->text);
+ field_text->text = NULL;
+ }
+
+ (* G_OBJECT_CLASS (ev_form_field_text_parent_class)->finalize) (object);
+}
+
+static void
+ev_form_field_text_init (EvFormFieldText *field_text)
+{
+}
+
+static void
+ev_form_field_text_class_init (EvFormFieldTextClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = ev_form_field_text_finalize;
+}
+
+static void
+ev_form_field_button_init (EvFormFieldButton *field_button)
+{
+}
+
+static void
+ev_form_field_button_class_init (EvFormFieldButtonClass *klass)
+{
+}
+
+static void
+ev_form_field_choice_finalize (GObject *object)
+{
+ EvFormFieldChoice *field_choice = EV_FORM_FIELD_CHOICE (object);
+
+ if (field_choice->selected_items) {
+ g_list_free (field_choice->selected_items);
+ field_choice->selected_items = NULL;
+ }
+
+ if (field_choice->text) {
+ g_free (field_choice->text);
+ field_choice->text = NULL;
+ }
+
+ (* G_OBJECT_CLASS (ev_form_field_choice_parent_class)->finalize) (object);
+}
+
+static void
+ev_form_field_choice_init (EvFormFieldChoice *field_choice)
+{
+}
+
+static void
+ev_form_field_choice_class_init (EvFormFieldChoiceClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = ev_form_field_choice_finalize;
+}
+
+static void
+ev_form_field_signature_init (EvFormFieldSignature *field_signature)
+{
+}
+
+static void
+ev_form_field_signature_class_init (EvFormFieldSignatureClass *klass)
+{
+}
+
+EvFormField *
+ev_form_field_text_new (gint id,
+ EvFormFieldTextType type)
+{
+ EvFormField *field;
+
+ g_return_val_if_fail (id >= 0, NULL);
+ g_return_val_if_fail (type >= EV_FORM_FIELD_TEXT_NORMAL &&
+ type <= EV_FORM_FIELD_TEXT_FILE_SELECT, NULL);
+
+ field = EV_FORM_FIELD (g_object_new (EV_TYPE_FORM_FIELD_TEXT, NULL));
+ field->id = id;
+ EV_FORM_FIELD_TEXT (field)->type = type;
+
+ return field;
+}
+
+EvFormField *
+ev_form_field_button_new (gint id,
+ EvFormFieldButtonType type)
+{
+ EvFormField *field;
+
+ g_return_val_if_fail (id >= 0, NULL);
+ g_return_val_if_fail (type >= EV_FORM_FIELD_BUTTON_PUSH &&
+ type <= EV_FORM_FIELD_BUTTON_RADIO, NULL);
+
+ field = EV_FORM_FIELD (g_object_new (EV_TYPE_FORM_FIELD_BUTTON, NULL));
+ field->id = id;
+ EV_FORM_FIELD_BUTTON (field)->type = type;
+
+ return field;
+}
+
+EvFormField *
+ev_form_field_choice_new (gint id,
+ EvFormFieldChoiceType type)
+{
+ EvFormField *field;
+
+ g_return_val_if_fail (id >= 0, NULL);
+ g_return_val_if_fail (type >= EV_FORM_FIELD_CHOICE_COMBO &&
+ type <= EV_FORM_FIELD_CHOICE_LIST, NULL);
+
+ field = EV_FORM_FIELD (g_object_new (EV_TYPE_FORM_FIELD_CHOICE, NULL));
+ field->id = id;
+ EV_FORM_FIELD_CHOICE (field)->type = type;
+
+ return field;
+}
+
+EvFormField *
+ev_form_field_signature_new (gint id)
+{
+ EvFormField *field;
+
+ g_return_val_if_fail (id >= 0, NULL);
+
+ field = EV_FORM_FIELD (g_object_new (EV_TYPE_FORM_FIELD_SIGNATURE, NULL));
+ field->id = id;
+
+ return field;
+}
+
diff --git a/libdocument/ev-form-field.h b/libdocument/ev-form-field.h
new file mode 100644
index 00000000..06948dc1
--- /dev/null
+++ b/libdocument/ev-form-field.h
@@ -0,0 +1,214 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; c-indent-level: 8 -*- */
+/* this file is part of evince, a mate document viewer
+ *
+ * Copyright (C) 2006 Julien Rebetez
+ *
+ * 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.
+ */
+
+#if !defined (__EV_EVINCE_DOCUMENT_H_INSIDE__) && !defined (EVINCE_COMPILATION)
+#error "Only <evince-document.h> can be included directly."
+#endif
+
+#ifndef EV_FORM_FIELD_H
+#define EV_FORM_FIELD_H
+
+#include <glib-object.h>
+
+#include "ev-document.h"
+
+G_BEGIN_DECLS
+
+#define EV_TYPE_FORM_FIELD (ev_form_field_get_type())
+#define EV_FORM_FIELD(object) (G_TYPE_CHECK_INSTANCE_CAST((object), EV_TYPE_FORM_FIELD, EvFormField))
+#define EV_FORM_FIELD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), EV_TYPE_FORM_FIELD, EvFormFieldClass))
+#define EV_IS_FORM_FIELD(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), EV_TYPE_FORM_FIELD))
+#define EV_IS_FORM_FIELD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), EV_TYPE_FORM_FIELD))
+#define EV_FORM_FIELD_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS((object), EV_TYPE_FORM_FIELD, EvFormFieldClass))
+
+#define EV_TYPE_FORM_FIELD_TEXT (ev_form_field_text_get_type())
+#define EV_FORM_FIELD_TEXT(object) (G_TYPE_CHECK_INSTANCE_CAST((object), EV_TYPE_FORM_FIELD_TEXT, EvFormFieldText))
+#define EV_FORM_FIELD_TEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), EV_TYPE_FORM_FIELD_TEXT, EvFormFieldTextClass))
+#define EV_IS_FORM_FIELD_TEXT(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), EV_TYPE_FORM_FIELD_TEXT))
+#define EV_IS_FORM_FIELD_TEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), EV_TYPE_FORM_FIELD_TEXT))
+#define EV_FORM_FIELD_TEXT_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS((object), EV_TYPE_FORM_FIELD_TEXT, EvFormFieldTextClass))
+
+#define EV_TYPE_FORM_FIELD_BUTTON (ev_form_field_button_get_type())
+#define EV_FORM_FIELD_BUTTON(object) (G_TYPE_CHECK_INSTANCE_CAST((object), EV_TYPE_FORM_FIELD_BUTTON, EvFormFieldButton))
+#define EV_FORM_FIELD_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), EV_TYPE_FORM_FIELD_BUTTON, EvFormFieldButtonClass))
+#define EV_IS_FORM_FIELD_BUTTON(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), EV_TYPE_FORM_FIELD_BUTTON))
+#define EV_IS_FORM_FIELD_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), EV_TYPE_FORM_FIELD_BUTTON))
+#define EV_FORM_FIELD_BUTTON_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS((object), EV_TYPE_FORM_FIELD_BUTTON, EvFormFieldButtonClass))
+
+#define EV_TYPE_FORM_FIELD_CHOICE (ev_form_field_choice_get_type())
+#define EV_FORM_FIELD_CHOICE(object) (G_TYPE_CHECK_INSTANCE_CAST((object), EV_TYPE_FORM_FIELD_CHOICE, EvFormFieldChoice))
+#define EV_FORM_FIELD_CHOICE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), EV_TYPE_FORM_FIELD_CHOICE, EvFormFieldChoiceClass))
+#define EV_IS_FORM_FIELD_CHOICE(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), EV_TYPE_FORM_FIELD_CHOICE))
+#define EV_IS_FORM_FIELD_CHOICE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), EV_TYPE_FORM_FIELD_CHOICE))
+#define EV_FORM_FIELD_CHOICE_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS((object), EV_TYPE_FORM_FIELD_CHOICE, EvFormFieldChoiceClass))
+
+#define EV_TYPE_FORM_FIELD_SIGNATURE (ev_form_field_signature_get_type())
+#define EV_FORM_FIELD_SIGNATURE(object) (G_TYPE_CHECK_INSTANCE_CAST((object), EV_TYPE_FORM_FIELD_SIGNATURE, EvFormFieldSignature))
+#define EV_FORM_FIELD_SIGNATURE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), EV_TYPE_FORM_FIELD_SIGNATURE, EvFormFieldSignatureClass))
+#define EV_IS_FORM_FIELD_SIGNATURE(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), EV_TYPE_FORM_FIELD_SIGNATURE))
+#define EV_IS_FORM_FIELD_SIGNATURE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), EV_TYPE_FORM_FIELD_SIGNATURE))
+#define EV_FORM_FIELD_SIGNATURE_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS((object), EV_TYPE_FORM_FIELD_SIGNATURE, EvFormFieldSignatureClass))
+
+typedef struct _EvFormField EvFormField;
+typedef struct _EvFormFieldClass EvFormFieldClass;
+
+typedef struct _EvFormFieldText EvFormFieldText;
+typedef struct _EvFormFieldTextClass EvFormFieldTextClass;
+
+typedef struct _EvFormFieldButton EvFormFieldButton;
+typedef struct _EvFormFieldButtonClass EvFormFieldButtonClass;
+
+typedef struct _EvFormFieldChoice EvFormFieldChoice;
+typedef struct _EvFormFieldChoiceClass EvFormFieldChoiceClass;
+
+typedef struct _EvFormFieldSignature EvFormFieldSignature;
+typedef struct _EvFormFieldSignatureClass EvFormFieldSignatureClass;
+
+typedef enum
+{
+ EV_FORM_FIELD_TEXT_NORMAL,
+ EV_FORM_FIELD_TEXT_MULTILINE,
+ EV_FORM_FIELD_TEXT_FILE_SELECT
+} EvFormFieldTextType;
+
+typedef enum
+{
+ EV_FORM_FIELD_BUTTON_PUSH,
+ EV_FORM_FIELD_BUTTON_CHECK,
+ EV_FORM_FIELD_BUTTON_RADIO
+} EvFormFieldButtonType;
+
+typedef enum
+{
+ EV_FORM_FIELD_CHOICE_COMBO,
+ EV_FORM_FIELD_CHOICE_LIST
+} EvFormFieldChoiceType;
+
+struct _EvFormField
+{
+ GObject parent;
+
+ gint id;
+ gboolean is_read_only;
+ gdouble font_size;
+
+ EvPage *page;
+ gboolean changed;
+};
+
+struct _EvFormFieldClass
+{
+ GObjectClass parent_class;
+};
+
+struct _EvFormFieldText
+{
+ EvFormField partent;
+
+ EvFormFieldTextType type;
+
+ gboolean do_spell_check : 1;
+ gboolean do_scroll : 1;
+ gboolean comb : 1;
+ gboolean is_rich_text : 1;
+ gboolean is_password;
+
+ gint max_len;
+ gchar *text;
+};
+
+struct _EvFormFieldTextClass
+{
+ EvFormFieldClass partent_class;
+};
+
+struct _EvFormFieldButton
+{
+ EvFormField partent;
+
+ EvFormFieldButtonType type;
+
+ gboolean state;
+};
+
+struct _EvFormFieldButtonClass
+{
+ EvFormFieldClass partent_class;
+};
+
+struct _EvFormFieldChoice
+{
+ EvFormField partent;
+
+ EvFormFieldChoiceType type;
+
+ gboolean multi_select : 1;
+ gboolean is_editable : 1;
+ gboolean do_spell_check : 1;
+ gboolean commit_on_sel_change : 1;
+
+ GList *selected_items;
+ gchar *text;
+};
+
+struct _EvFormFieldChoiceClass
+{
+ EvFormFieldClass partent_class;
+};
+
+struct _EvFormFieldSignature
+{
+ EvFormField partent;
+
+ /* TODO */
+};
+
+struct _EvFormFieldSignatureClass
+{
+ EvFormFieldClass partent_class;
+};
+
+/* EvFormField base class */
+GType ev_form_field_get_type (void) G_GNUC_CONST;
+
+/* EvFormFieldText */
+GType ev_form_field_text_get_type (void) G_GNUC_CONST;
+EvFormField *ev_form_field_text_new (gint id,
+ EvFormFieldTextType type);
+
+/* EvFormFieldButton */
+GType ev_form_field_button_get_type (void) G_GNUC_CONST;
+EvFormField *ev_form_field_button_new (gint id,
+ EvFormFieldButtonType type);
+
+/* EvFormFieldChoice */
+GType ev_form_field_choice_get_type (void) G_GNUC_CONST;
+EvFormField *ev_form_field_choice_new (gint id,
+ EvFormFieldChoiceType type);
+
+/* EvFormFieldSignature */
+GType ev_form_field_signature_get_type (void) G_GNUC_CONST;
+EvFormField *ev_form_field_signature_new (gint id);
+
+
+G_END_DECLS
+
+#endif /* !EV_FORM_FIELD_H */
+
diff --git a/libdocument/ev-image.c b/libdocument/ev-image.c
new file mode 100644
index 00000000..19ffed51
--- /dev/null
+++ b/libdocument/ev-image.c
@@ -0,0 +1,181 @@
+/* this file is part of evince, a mate document viewer
+ *
+ * Copyright (C) 2006 Carlos Garcia Campos <[email protected]>
+ *
+ * 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 <glib/gstdio.h>
+#include <unistd.h>
+
+#include "ev-document-misc.h"
+#include "ev-file-helpers.h"
+#include "ev-image.h"
+
+struct _EvImagePrivate {
+ gint page;
+ gint id;
+ GdkPixbuf *pixbuf;
+ gchar *tmp_uri;
+};
+
+#define EV_IMAGE_GET_PRIVATE(object) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((object), EV_TYPE_IMAGE, EvImagePrivate))
+
+G_DEFINE_TYPE (EvImage, ev_image, G_TYPE_OBJECT)
+
+static void
+ev_image_finalize (GObject *object)
+{
+ EvImage *image = EV_IMAGE (object);
+
+ if (image->priv->pixbuf) {
+ g_object_unref (image->priv->pixbuf);
+ image->priv->pixbuf = NULL;
+ }
+
+ if (image->priv->tmp_uri) {
+ gchar *filename;
+
+ filename = g_filename_from_uri (image->priv->tmp_uri, NULL, NULL);
+ ev_tmp_filename_unlink (filename);
+ g_free (filename);
+ g_free (image->priv->tmp_uri);
+ image->priv->tmp_uri = NULL;
+ }
+
+ (* G_OBJECT_CLASS (ev_image_parent_class)->finalize) (object);
+}
+
+static void
+ev_image_class_init (EvImageClass *klass)
+{
+ GObjectClass *g_object_class;
+
+ g_object_class = G_OBJECT_CLASS (klass);
+
+ g_type_class_add_private (g_object_class, sizeof (EvImagePrivate));
+
+ g_object_class->finalize = ev_image_finalize;
+}
+
+static void
+ev_image_init (EvImage *image)
+{
+ image->priv = EV_IMAGE_GET_PRIVATE (image);
+}
+
+EvImage *
+ev_image_new (gint page,
+ gint img_id)
+{
+ EvImage *image;
+
+ image = EV_IMAGE (g_object_new (EV_TYPE_IMAGE, NULL));
+ image->priv->page = page;
+ image->priv->id = img_id;
+
+ return image;
+}
+
+EvImage *
+ev_image_new_from_pixbuf (GdkPixbuf *pixbuf)
+{
+ EvImage *image;
+
+ g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), NULL);
+
+ image = EV_IMAGE (g_object_new (EV_TYPE_IMAGE, NULL));
+ image->priv->pixbuf = g_object_ref (pixbuf);
+
+ return image;
+}
+
+gint
+ev_image_get_page (EvImage *image)
+{
+ g_return_val_if_fail (EV_IS_IMAGE (image), -1);
+
+ return image->priv->page;
+}
+
+gint
+ev_image_get_id (EvImage *image)
+{
+ g_return_val_if_fail (EV_IS_IMAGE (image), -1);
+
+ return image->priv->id;
+}
+
+GdkPixbuf *
+ev_image_get_pixbuf (EvImage *image)
+{
+ g_return_val_if_fail (EV_IS_IMAGE (image), NULL);
+ g_return_val_if_fail (GDK_IS_PIXBUF (image->priv->pixbuf), NULL);
+
+ return image->priv->pixbuf;
+}
+
+const gchar *
+ev_image_save_tmp (EvImage *image,
+ GdkPixbuf *pixbuf)
+{
+ GError *error = NULL;
+ gchar *filename = NULL;
+ int fd;
+
+ g_return_val_if_fail (EV_IS_IMAGE (image), NULL);
+ g_return_val_if_fail (GDK_IS_PIXBUF (pixbuf), NULL);
+
+ if (image->priv->tmp_uri)
+ return image->priv->tmp_uri;
+
+ if ((fd = ev_mkstemp ("image.XXXXXX", &filename, &error)) == -1)
+ goto had_error;
+
+ gdk_pixbuf_save (pixbuf, filename,
+ "png", &error,
+ "compression", "3", NULL);
+ close (fd);
+
+ if (!error) {
+ image->priv->tmp_uri = g_filename_to_uri (filename, NULL, &error);
+ if (image->priv->tmp_uri == NULL)
+ goto had_error;
+
+ g_free (filename);
+
+ return image->priv->tmp_uri;
+ }
+
+ had_error:
+
+ /* Erro saving image */
+ g_warning ("Error saving image: %s", error->message);
+ g_error_free (error);
+ g_free (filename);
+
+ return NULL;
+}
+
+const gchar *
+ev_image_get_tmp_uri (EvImage *image)
+{
+ g_return_val_if_fail (EV_IS_IMAGE (image), NULL);
+
+ return image->priv->tmp_uri;
+}
diff --git a/libdocument/ev-image.h b/libdocument/ev-image.h
new file mode 100644
index 00000000..c3227c96
--- /dev/null
+++ b/libdocument/ev-image.h
@@ -0,0 +1,68 @@
+/* this file is part of evince, a mate document viewer
+ *
+ * Copyright (C) 2006 Carlos Garcia Campos <[email protected]>
+ *
+ * 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.
+ */
+
+#if !defined (__EV_EVINCE_DOCUMENT_H_INSIDE__) && !defined (EVINCE_COMPILATION)
+#error "Only <evince-document.h> can be included directly."
+#endif
+
+#ifndef __EV_IMAGE_H__
+#define __EV_IMAGE_H__
+
+#include <glib-object.h>
+#include <gdk/gdk.h>
+
+G_BEGIN_DECLS
+
+typedef struct _EvImage EvImage;
+typedef struct _EvImageClass EvImageClass;
+typedef struct _EvImagePrivate EvImagePrivate;
+
+#define EV_TYPE_IMAGE (ev_image_get_type())
+#define EV_IMAGE(object) (G_TYPE_CHECK_INSTANCE_CAST((object), EV_TYPE_IMAGE, EvImage))
+#define EV_IMAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), EV_TYPE_IMAGE, EvImageClass))
+#define EV_IS_IMAGE(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), EV_TYPE_IMAGE))
+#define EV_IS_IMAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), EV_TYPE_IMAGE))
+#define EV_IMAGE_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS((object), EV_TYPE_IMAGE, EvImageClass))
+
+struct _EvImage {
+ GObject base_instance;
+
+ EvImagePrivate *priv;
+};
+
+struct _EvImageClass {
+ GObjectClass base_class;
+};
+
+GType ev_image_get_type (void) G_GNUC_CONST;
+EvImage *ev_image_new (gint page,
+ gint img_id);
+EvImage *ev_image_new_from_pixbuf (GdkPixbuf *pixbuf);
+
+gint ev_image_get_id (EvImage *image);
+gint ev_image_get_page (EvImage *image);
+GdkPixbuf *ev_image_get_pixbuf (EvImage *image);
+const gchar *ev_image_save_tmp (EvImage *image,
+ GdkPixbuf *pixbuf);
+const gchar *ev_image_get_tmp_uri (EvImage *image);
+
+
+G_END_DECLS
+
+#endif /* __EV_IMAGE_H__ */
diff --git a/libdocument/ev-init.c b/libdocument/ev-init.c
new file mode 100644
index 00000000..31863357
--- /dev/null
+++ b/libdocument/ev-init.c
@@ -0,0 +1,154 @@
+/* this file is part of evince, a mate document viewer
+ *
+ * Copyright © 2009 Christian Persch
+ *
+ * Evince is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 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 Lesser
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser 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 <glib.h>
+#include <glib/gi18n-lib.h>
+#ifdef G_OS_WIN32
+#include <windows.h>
+#endif
+
+#include "ev-init.h"
+#include "ev-backends-manager.h"
+#include "ev-debug.h"
+#include "ev-file-helpers.h"
+
+static int ev_init_count;
+
+#ifdef G_OS_WIN32
+
+static HMODULE evdocument_dll = NULL;
+static gchar *locale_dir = NULL;
+
+#ifdef DLL_EXPORT
+BOOL WINAPI
+DllMain (HINSTANCE hinstDLL,
+ DWORD fdwReason,
+ LPVOID lpvReserved)
+{
+ if (fdwReason == DLL_PROCESS_ATTACH)
+ evdocument_dll = hinstDLL;
+
+ return TRUE;
+}
+#endif
+
+static const gchar *
+_ev_win32_get_locale_dir (HMODULE module)
+{
+ if (locale_dir)
+ return locale_dir;
+
+ gchar *install_dir = NULL, *utf8_locale_dir;
+ gchar *retval = NULL;
+
+ if (evdocument_dll != NULL)
+ install_dir =
+ g_win32_get_package_installation_directory_of_module (module);
+
+ if (install_dir) {
+ utf8_locale_dir = g_build_filename (install_dir,
+ "share", "locale", NULL);
+
+ locale_dir = g_win32_locale_filename_from_utf8 (utf8_locale_dir);
+
+ g_free (install_dir);
+ g_free (utf8_locale_dir);
+ }
+
+ if (!locale_dir)
+ locale_dir = g_strdup ("");
+}
+
+#endif
+
+const gchar *
+ev_get_locale_dir (void)
+{
+#ifdef G_OS_WIN32
+ return _ev_win32_get_locale_dir (evdocument_dll);
+#else
+ return MATELOCALEDIR;
+#endif
+}
+
+/**
+ * ev_init:
+ *
+ * Initializes the evince document library, and binds the evince
+ * gettext domain.
+ *
+ * You must call this before calling any other function in the evince
+ * document library.
+ *
+ * Returns: %TRUE if any backends were found; %FALSE otherwise
+ */
+gboolean
+ev_init (void)
+{
+ static gboolean have_backends;
+
+ if (ev_init_count++ > 0)
+ return have_backends;
+
+ /* set up translation catalog */
+ bindtextdomain (GETTEXT_PACKAGE, ev_get_locale_dir ());
+ bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+
+ _ev_debug_init ();
+ _ev_file_helpers_init ();
+ have_backends = _ev_backends_manager_init ();
+
+ return have_backends;
+}
+
+/**
+ * ev_shutdown:
+ *
+ * Shuts the evince document library down.
+ */
+void
+ev_shutdown (void)
+{
+ g_assert (_ev_is_initialized ());
+
+ if (--ev_init_count > 0)
+ return;
+
+#ifdef G_OS_WIN32
+ if (locale_dir != NULL)
+ g_free(locale_dir);
+#endif
+
+ _ev_backends_manager_shutdown ();
+ _ev_file_helpers_shutdown ();
+ _ev_debug_shutdown ();
+}
+
+/*
+ * _ev_is_initialized:
+ *
+ * Returns: %TRUE if the evince document library has been initialized
+ */
+gboolean
+_ev_is_initialized (void)
+{
+ return ev_init_count > 0;
+}
diff --git a/libdocument/ev-init.h b/libdocument/ev-init.h
new file mode 100644
index 00000000..b9cddf4f
--- /dev/null
+++ b/libdocument/ev-init.h
@@ -0,0 +1,41 @@
+/* this file is part of evince, a mate document viewer
+ *
+ * Copyright © 2009 Christian Persch
+ *
+ * Evince is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 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 Lesser
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser 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.
+ */
+
+#if !defined (__EV_EVINCE_DOCUMENT_H_INSIDE__) && !defined (EVINCE_COMPILATION)
+#error "Only <evince-document.h> can be included directly."
+#endif
+
+#ifndef EV_INIT_H
+#define EV_INIT_H
+
+#include <glib.h>
+
+G_BEGIN_DECLS
+
+const gchar* ev_get_locale_dir (void);
+
+gboolean ev_init (void);
+
+void ev_shutdown (void);
+
+gboolean _ev_is_initialized (void);
+
+G_END_DECLS
+
+#endif /* EV_INIT_H */
diff --git a/libdocument/ev-layer.c b/libdocument/ev-layer.c
new file mode 100644
index 00000000..935268c1
--- /dev/null
+++ b/libdocument/ev-layer.c
@@ -0,0 +1,86 @@
+/* this file is part of evince, a mate document viewer
+ *
+ * Copyright (C) 2008 Carlos Garcia Campos <[email protected]>
+ *
+ * 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-layer.h"
+
+struct _EvLayerPrivate {
+ guint id;
+ gboolean is_parent;
+ gint rb_group;
+};
+
+#define EV_LAYER_GET_PRIVATE(object) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((object), EV_TYPE_LAYER, EvLayerPrivate))
+
+G_DEFINE_TYPE (EvLayer, ev_layer, G_TYPE_OBJECT)
+
+static void
+ev_layer_class_init (EvLayerClass *klass)
+{
+ GObjectClass *g_object_class = G_OBJECT_CLASS (klass);
+
+ g_type_class_add_private (g_object_class, sizeof (EvLayerPrivate));
+}
+
+static void
+ev_layer_init (EvLayer *layer)
+{
+ layer->priv = EV_LAYER_GET_PRIVATE (layer);
+}
+
+EvLayer *
+ev_layer_new (guint layer_id,
+ gboolean is_parent,
+ gint rb_group)
+{
+ EvLayer *layer;
+
+ layer = EV_LAYER (g_object_new (EV_TYPE_LAYER, NULL));
+ layer->priv->id = layer_id;
+ layer->priv->is_parent = is_parent;
+ layer->priv->rb_group = rb_group;
+
+ return layer;
+}
+
+guint
+ev_layer_get_id (EvLayer *layer)
+{
+ g_return_val_if_fail (EV_IS_LAYER (layer), 0);
+
+ return layer->priv->id;
+}
+
+gboolean
+ev_layer_is_parent (EvLayer *layer)
+{
+ g_return_val_if_fail (EV_IS_LAYER (layer), FALSE);
+
+ return layer->priv->is_parent;
+}
+
+gint
+ev_layer_get_rb_group (EvLayer *layer)
+{
+ g_return_val_if_fail (EV_IS_LAYER (layer), 0);
+
+ return layer->priv->rb_group;
+}
diff --git a/libdocument/ev-layer.h b/libdocument/ev-layer.h
new file mode 100644
index 00000000..809c4701
--- /dev/null
+++ b/libdocument/ev-layer.h
@@ -0,0 +1,62 @@
+/* this file is part of evince, a mate document viewer
+ *
+ * Copyright (C) 2008 Carlos Garcia Campos <[email protected]>
+ *
+ * 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.
+ */
+
+#if !defined (__EV_EVINCE_DOCUMENT_H_INSIDE__) && !defined (EVINCE_COMPILATION)
+#error "Only <evince-document.h> can be included directly."
+#endif
+
+#ifndef __EV_LAYER_H__
+#define __EV_LAYER_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+typedef struct _EvLayer EvLayer;
+typedef struct _EvLayerClass EvLayerClass;
+typedef struct _EvLayerPrivate EvLayerPrivate;
+
+#define EV_TYPE_LAYER (ev_layer_get_type())
+#define EV_LAYER(object) (G_TYPE_CHECK_INSTANCE_CAST((object), EV_TYPE_LAYER, EvLayer))
+#define EV_LAYER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), EV_TYPE_LAYER, EvLayerClass))
+#define EV_IS_LAYER(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), EV_TYPE_LAYER))
+#define EV_IS_LAYER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), EV_TYPE_LAYER))
+#define EV_LAYER_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS((object), EV_TYPE_LAYER, EvLayerClass))
+
+struct _EvLayer {
+ GObject base_instance;
+
+ EvLayerPrivate *priv;
+};
+
+struct _EvLayerClass {
+ GObjectClass base_class;
+};
+
+GType ev_layer_get_type (void) G_GNUC_CONST;
+EvLayer *ev_layer_new (guint layer_id,
+ gboolean is_parent,
+ gint rb_group);
+guint ev_layer_get_id (EvLayer *layer);
+gboolean ev_layer_is_parent (EvLayer *layer);
+gint ev_layer_get_rb_group (EvLayer *layer);
+
+G_END_DECLS
+
+#endif /* __EV_LAYER_H__ */
diff --git a/libdocument/ev-link-action.c b/libdocument/ev-link-action.c
new file mode 100644
index 00000000..9ebc9a30
--- /dev/null
+++ b/libdocument/ev-link-action.c
@@ -0,0 +1,341 @@
+/* this file is part of evince, a mate document viewer
+ *
+ * Copyright (C) 2006 Carlos Garcia Campos <[email protected]>
+ * 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-link-action.h"
+#include "ev-document-type-builtins.h"
+
+enum {
+ PROP_0,
+ PROP_TYPE,
+ PROP_DEST,
+ PROP_URI,
+ PROP_FILENAME,
+ PROP_PARAMS,
+ PROP_NAME
+};
+
+struct _EvLinkAction {
+ GObject base_instance;
+
+ EvLinkActionPrivate *priv;
+};
+
+struct _EvLinkActionClass {
+ GObjectClass base_class;
+};
+
+struct _EvLinkActionPrivate {
+ EvLinkActionType type;
+ EvLinkDest *dest;
+ gchar *uri;
+ gchar *filename;
+ gchar *params;
+ gchar *name;
+};
+
+G_DEFINE_TYPE (EvLinkAction, ev_link_action, G_TYPE_OBJECT)
+
+#define EV_LINK_ACTION_GET_PRIVATE(object) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((object), EV_TYPE_LINK_ACTION, EvLinkActionPrivate))
+
+EvLinkActionType
+ev_link_action_get_action_type (EvLinkAction *self)
+{
+ g_return_val_if_fail (EV_IS_LINK_ACTION (self), 0);
+
+ return self->priv->type;
+}
+
+EvLinkDest *
+ev_link_action_get_dest (EvLinkAction *self)
+{
+ g_return_val_if_fail (EV_IS_LINK_ACTION (self), NULL);
+
+ return self->priv->dest;
+}
+
+const gchar *
+ev_link_action_get_uri (EvLinkAction *self)
+{
+ g_return_val_if_fail (EV_IS_LINK_ACTION (self), NULL);
+
+ return self->priv->uri;
+}
+
+const gchar *
+ev_link_action_get_filename (EvLinkAction *self)
+{
+ g_return_val_if_fail (EV_IS_LINK_ACTION (self), NULL);
+
+ return self->priv->filename;
+}
+
+const gchar *
+ev_link_action_get_params (EvLinkAction *self)
+{
+ g_return_val_if_fail (EV_IS_LINK_ACTION (self), NULL);
+
+ return self->priv->params;
+}
+
+const gchar *
+ev_link_action_get_name (EvLinkAction *self)
+{
+ g_return_val_if_fail (EV_IS_LINK_ACTION (self), NULL);
+
+ return self->priv->name;
+}
+
+static void
+ev_link_action_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *param_spec)
+{
+ EvLinkAction *self;
+
+ self = EV_LINK_ACTION (object);
+
+ switch (prop_id) {
+ case PROP_TYPE:
+ g_value_set_enum (value, self->priv->type);
+ break;
+ case PROP_DEST:
+ g_value_set_pointer (value, self->priv->dest);
+ break;
+ case PROP_URI:
+ g_value_set_string (value, self->priv->uri);
+ break;
+ case PROP_FILENAME:
+ g_value_set_string (value, self->priv->filename);
+ break;
+ case PROP_PARAMS:
+ g_value_set_string (value, self->priv->params);
+ break;
+ case PROP_NAME:
+ g_value_set_string (value, self->priv->name);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object,
+ prop_id,
+ param_spec);
+ break;
+ }
+}
+
+static void
+ev_link_action_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *param_spec)
+{
+ EvLinkAction *self = EV_LINK_ACTION (object);
+
+ switch (prop_id) {
+ case PROP_TYPE:
+ self->priv->type = g_value_get_enum (value);
+ break;
+ case PROP_DEST:
+ self->priv->dest = g_value_get_pointer (value);
+ break;
+ case PROP_URI:
+ g_free (self->priv->uri);
+ self->priv->uri = g_value_dup_string (value);
+ break;
+ case PROP_FILENAME:
+ g_free (self->priv->filename);
+ self->priv->filename = g_value_dup_string (value);
+ break;
+ case PROP_PARAMS:
+ g_free (self->priv->params);
+ self->priv->params = g_value_dup_string (value);
+ break;
+ case PROP_NAME:
+ g_free (self->priv->name);
+ self->priv->name = g_value_dup_string (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object,
+ prop_id,
+ param_spec);
+ break;
+ }
+}
+
+static void
+ev_link_action_finalize (GObject *object)
+{
+ EvLinkActionPrivate *priv;
+
+ priv = EV_LINK_ACTION (object)->priv;
+
+ if (priv->dest) {
+ g_object_unref (priv->dest);
+ priv->dest = NULL;
+ }
+
+ if (priv->uri) {
+ g_free (priv->uri);
+ priv->uri = NULL;
+ }
+
+ if (priv->filename) {
+ g_free (priv->filename);
+ priv->filename = NULL;
+ }
+
+ if (priv->params) {
+ g_free (priv->params);
+ priv->params = NULL;
+ }
+
+ if (priv->name) {
+ g_free (priv->name);
+ priv->name = NULL;
+ }
+
+ G_OBJECT_CLASS (ev_link_action_parent_class)->finalize (object);
+}
+
+static void
+ev_link_action_init (EvLinkAction *ev_link_action)
+{
+ ev_link_action->priv = EV_LINK_ACTION_GET_PRIVATE (ev_link_action);
+
+ ev_link_action->priv->dest = NULL;
+ ev_link_action->priv->uri = NULL;
+ ev_link_action->priv->filename = NULL;
+ ev_link_action->priv->params = NULL;
+ ev_link_action->priv->name = NULL;
+}
+
+static void
+ev_link_action_class_init (EvLinkActionClass *ev_link_action_class)
+{
+ GObjectClass *g_object_class;
+
+ g_object_class = G_OBJECT_CLASS (ev_link_action_class);
+
+ g_object_class->set_property = ev_link_action_set_property;
+ g_object_class->get_property = ev_link_action_get_property;
+
+ g_object_class->finalize = ev_link_action_finalize;
+
+ g_type_class_add_private (g_object_class, sizeof (EvLinkActionPrivate));
+
+ g_object_class_install_property (g_object_class,
+ PROP_TYPE,
+ g_param_spec_enum ("type",
+ "Action Type",
+ "The link action type",
+ EV_TYPE_LINK_ACTION_TYPE,
+ EV_LINK_ACTION_TYPE_GOTO_DEST,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+ g_object_class_install_property (g_object_class,
+ PROP_DEST,
+ g_param_spec_pointer ("dest",
+ "Action destination",
+ "The link action destination",
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+ g_object_class_install_property (g_object_class,
+ PROP_URI,
+ g_param_spec_string ("uri",
+ "Link Action URI",
+ "The link action URI",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+ g_object_class_install_property (g_object_class,
+ PROP_FILENAME,
+ g_param_spec_string ("filename",
+ "Filename",
+ "The link action filename",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+ g_object_class_install_property (g_object_class,
+ PROP_PARAMS,
+ g_param_spec_string ("params",
+ "Params",
+ "The link action params",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+ g_object_class_install_property (g_object_class,
+ PROP_NAME,
+ g_param_spec_string ("name",
+ "Name",
+ "The link action name",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+}
+
+EvLinkAction *
+ev_link_action_new_dest (EvLinkDest *dest)
+{
+ return EV_LINK_ACTION (g_object_new (EV_TYPE_LINK_ACTION,
+ "dest", dest,
+ "type", EV_LINK_ACTION_TYPE_GOTO_DEST,
+ NULL));
+}
+
+EvLinkAction *
+ev_link_action_new_remote (EvLinkDest *dest,
+ const gchar *filename)
+{
+ return EV_LINK_ACTION (g_object_new (EV_TYPE_LINK_ACTION,
+ "dest", dest,
+ "filename", filename,
+ "type", EV_LINK_ACTION_TYPE_GOTO_REMOTE,
+ NULL));
+}
+
+EvLinkAction *
+ev_link_action_new_external_uri (const gchar *uri)
+{
+ return EV_LINK_ACTION (g_object_new (EV_TYPE_LINK_ACTION,
+ "uri", uri,
+ "type", EV_LINK_ACTION_TYPE_EXTERNAL_URI,
+ NULL));
+}
+
+EvLinkAction *
+ev_link_action_new_launch (const gchar *filename,
+ const gchar *params)
+{
+ return EV_LINK_ACTION (g_object_new (EV_TYPE_LINK_ACTION,
+ "filename", filename,
+ "params", params,
+ "type", EV_LINK_ACTION_TYPE_LAUNCH,
+ NULL));
+}
+
+EvLinkAction *
+ev_link_action_new_named (const gchar *name)
+{
+ return EV_LINK_ACTION (g_object_new (EV_TYPE_LINK_ACTION,
+ "name", name,
+ "type", EV_LINK_ACTION_TYPE_NAMED,
+ NULL));
+}
diff --git a/libdocument/ev-link-action.h b/libdocument/ev-link-action.h
new file mode 100644
index 00000000..6940a53b
--- /dev/null
+++ b/libdocument/ev-link-action.h
@@ -0,0 +1,73 @@
+/* this file is part of evince, a mate document viewer
+ *
+ * Copyright (C) 2006 Carlos Garcia Campos <[email protected]>
+ * 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.
+ */
+
+#if !defined (__EV_EVINCE_DOCUMENT_H_INSIDE__) && !defined (EVINCE_COMPILATION)
+#error "Only <evince-document.h> can be included directly."
+#endif
+
+#ifndef EV_LINK_ACTION_H
+#define EV_LINK_ACTION_H
+
+#include <glib-object.h>
+#include "ev-link-dest.h"
+
+G_BEGIN_DECLS
+
+typedef struct _EvLinkAction EvLinkAction;
+typedef struct _EvLinkActionClass EvLinkActionClass;
+typedef struct _EvLinkActionPrivate EvLinkActionPrivate;
+
+#define EV_TYPE_LINK_ACTION (ev_link_action_get_type())
+#define EV_LINK_ACTION(object) (G_TYPE_CHECK_INSTANCE_CAST((object), EV_TYPE_LINK_ACTION, EvLinkAction))
+#define EV_LINK_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), EV_TYPE_LINK_ACTION, EvLinkActionClass))
+#define EV_IS_LINK_ACTION(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), EV_TYPE_LINK_ACTION))
+#define EV_IS_LINK_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), EV_TYPE_LINK_ACTION))
+#define EV_LINK_ACTION_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS((object), EV_TYPE_LINK_ACTION, EvLinkActionClass))
+
+typedef enum {
+ EV_LINK_ACTION_TYPE_GOTO_DEST,
+ EV_LINK_ACTION_TYPE_GOTO_REMOTE,
+ EV_LINK_ACTION_TYPE_EXTERNAL_URI,
+ EV_LINK_ACTION_TYPE_LAUNCH,
+ EV_LINK_ACTION_TYPE_NAMED
+ /* We'll probably fill this in more as we support the other types of
+ * actions */
+} EvLinkActionType;
+
+GType ev_link_action_get_type (void) G_GNUC_CONST;
+
+EvLinkActionType ev_link_action_get_action_type (EvLinkAction *self);
+EvLinkDest *ev_link_action_get_dest (EvLinkAction *self);
+const gchar *ev_link_action_get_uri (EvLinkAction *self);
+const gchar *ev_link_action_get_filename (EvLinkAction *self);
+const gchar *ev_link_action_get_params (EvLinkAction *self);
+const gchar *ev_link_action_get_name (EvLinkAction *self);
+
+EvLinkAction *ev_link_action_new_dest (EvLinkDest *dest);
+EvLinkAction *ev_link_action_new_remote (EvLinkDest *dest,
+ const gchar *filename);
+EvLinkAction *ev_link_action_new_external_uri (const gchar *uri);
+EvLinkAction *ev_link_action_new_launch (const gchar *filename,
+ const gchar *params);
+EvLinkAction *ev_link_action_new_named (const gchar *name);
+
+G_END_DECLS
+
+#endif /* EV_LINK_ACTION_H */
diff --git a/libdocument/ev-link-dest.c b/libdocument/ev-link-dest.c
new file mode 100644
index 00000000..f73f99f7
--- /dev/null
+++ b/libdocument/ev-link-dest.c
@@ -0,0 +1,511 @@
+/* this file is part of evince, a mate document viewer
+ *
+ * Copyright (C) 2006 Carlos Garcia Campos <[email protected]>
+ * 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-link-dest.h"
+#include "ev-document-type-builtins.h"
+
+enum {
+ PROP_0,
+ PROP_TYPE,
+ PROP_PAGE,
+ PROP_LEFT,
+ PROP_TOP,
+ PROP_BOTTOM,
+ PROP_RIGHT,
+ PROP_ZOOM,
+ PROP_CHANGE,
+ PROP_NAMED,
+ PROP_PAGE_LABEL
+};
+
+typedef enum {
+ EV_DEST_CHANGE_TOP = 1 << 0,
+ EV_DEST_CHANGE_LEFT = 1 << 1,
+ EV_DEST_CHANGE_ZOOM = 1 << 2
+} EvDestChange;
+
+struct _EvLinkDest {
+ GObject base_instance;
+
+ EvLinkDestPrivate *priv;
+};
+
+struct _EvLinkDestClass {
+ GObjectClass base_class;
+};
+
+struct _EvLinkDestPrivate {
+ EvLinkDestType type;
+ int page;
+ double top;
+ double left;
+ double bottom;
+ double right;
+ double zoom;
+ EvDestChange change;
+ gchar *named;
+ gchar *page_label;
+};
+
+G_DEFINE_TYPE (EvLinkDest, ev_link_dest, G_TYPE_OBJECT)
+
+#define EV_LINK_DEST_GET_PRIVATE(object) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((object), EV_TYPE_LINK_DEST, EvLinkDestPrivate))
+
+EvLinkDestType
+ev_link_dest_get_dest_type (EvLinkDest *self)
+{
+ g_return_val_if_fail (EV_IS_LINK_DEST (self), 0);
+
+ return self->priv->type;
+}
+
+gint
+ev_link_dest_get_page (EvLinkDest *self)
+{
+ g_return_val_if_fail (EV_IS_LINK_DEST (self), -1);
+
+ return self->priv->page;
+}
+
+gdouble
+ev_link_dest_get_top (EvLinkDest *self,
+ gboolean *change_top)
+{
+ g_return_val_if_fail (EV_IS_LINK_DEST (self), 0);
+
+ if (change_top)
+ *change_top = (self->priv->change & EV_DEST_CHANGE_TOP);
+
+ return self->priv->top;
+}
+
+gdouble
+ev_link_dest_get_left (EvLinkDest *self,
+ gboolean *change_left)
+{
+ g_return_val_if_fail (EV_IS_LINK_DEST (self), 0);
+
+ if (change_left)
+ *change_left = (self->priv->change & EV_DEST_CHANGE_LEFT);
+
+ return self->priv->left;
+}
+
+gdouble
+ev_link_dest_get_bottom (EvLinkDest *self)
+{
+ g_return_val_if_fail (EV_IS_LINK_DEST (self), 0);
+
+ return self->priv->bottom;
+}
+
+gdouble
+ev_link_dest_get_right (EvLinkDest *self)
+{
+ g_return_val_if_fail (EV_IS_LINK_DEST (self), 0);
+
+ return self->priv->right;
+}
+
+gdouble
+ev_link_dest_get_zoom (EvLinkDest *self,
+ gboolean *change_zoom)
+{
+ g_return_val_if_fail (EV_IS_LINK_DEST (self), 0);
+
+ if (change_zoom)
+ *change_zoom = (self->priv->change & EV_DEST_CHANGE_ZOOM);
+
+ return self->priv->zoom;
+}
+
+const gchar *
+ev_link_dest_get_named_dest (EvLinkDest *self)
+{
+ g_return_val_if_fail (EV_IS_LINK_DEST (self), NULL);
+
+ return self->priv->named;
+}
+
+const gchar *
+ev_link_dest_get_page_label (EvLinkDest *self)
+{
+ g_return_val_if_fail (EV_IS_LINK_DEST (self), NULL);
+
+ return self->priv->page_label;
+}
+
+static void
+ev_link_dest_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *param_spec)
+{
+ EvLinkDest *self;
+
+ self = EV_LINK_DEST (object);
+
+ switch (prop_id) {
+ case PROP_TYPE:
+ g_value_set_enum (value, self->priv->type);
+ break;
+ case PROP_PAGE:
+ g_value_set_int (value, self->priv->page);
+ break;
+ case PROP_TOP:
+ g_value_set_double (value, self->priv->top);
+ break;
+ case PROP_LEFT:
+ g_value_set_double (value, self->priv->left);
+ break;
+ case PROP_BOTTOM:
+ g_value_set_double (value, self->priv->bottom);
+ break;
+ case PROP_RIGHT:
+ g_value_set_double (value, self->priv->left);
+ break;
+ case PROP_ZOOM:
+ g_value_set_double (value, self->priv->zoom);
+ break;
+ case PROP_CHANGE:
+ g_value_set_uint (value, self->priv->change);
+ break;
+ case PROP_NAMED:
+ g_value_set_string (value, self->priv->named);
+ break;
+ case PROP_PAGE_LABEL:
+ g_value_set_string (value, self->priv->page_label);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object,
+ prop_id,
+ param_spec);
+ break;
+ }
+}
+
+static void
+ev_link_dest_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *param_spec)
+{
+ EvLinkDest *self = EV_LINK_DEST (object);
+
+ switch (prop_id) {
+ case PROP_TYPE:
+ self->priv->type = g_value_get_enum (value);
+ break;
+ case PROP_PAGE:
+ self->priv->page = g_value_get_int (value);
+ break;
+ case PROP_TOP:
+ self->priv->top = g_value_get_double (value);
+ break;
+ case PROP_LEFT:
+ self->priv->left = g_value_get_double (value);
+ break;
+ case PROP_BOTTOM:
+ self->priv->bottom = g_value_get_double (value);
+ break;
+ case PROP_RIGHT:
+ self->priv->right = g_value_get_double (value);
+ break;
+ case PROP_ZOOM:
+ self->priv->zoom = g_value_get_double (value);
+ break;
+ case PROP_CHANGE:
+ self->priv->change = g_value_get_uint (value);
+ break;
+ case PROP_NAMED:
+ self->priv->named = g_value_dup_string (value);
+ break;
+ case PROP_PAGE_LABEL:
+ self->priv->page_label = g_value_dup_string (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object,
+ prop_id,
+ param_spec);
+ break;
+ }
+}
+
+static void
+ev_link_dest_finalize (GObject *object)
+{
+ EvLinkDestPrivate *priv;
+
+ priv = EV_LINK_DEST (object)->priv;
+
+ if (priv->named) {
+ g_free (priv->named);
+ priv->named = NULL;
+ }
+ if (priv->page_label) {
+ g_free (priv->page_label);
+ priv->page_label = NULL;
+ }
+
+ G_OBJECT_CLASS (ev_link_dest_parent_class)->finalize (object);
+}
+
+static void
+ev_link_dest_init (EvLinkDest *ev_link_dest)
+{
+ ev_link_dest->priv = EV_LINK_DEST_GET_PRIVATE (ev_link_dest);
+
+ ev_link_dest->priv->named = NULL;
+}
+
+static void
+ev_link_dest_class_init (EvLinkDestClass *ev_link_dest_class)
+{
+ GObjectClass *g_object_class;
+
+ g_object_class = G_OBJECT_CLASS (ev_link_dest_class);
+
+ g_object_class->set_property = ev_link_dest_set_property;
+ g_object_class->get_property = ev_link_dest_get_property;
+
+ g_object_class->finalize = ev_link_dest_finalize;
+
+ g_type_class_add_private (g_object_class, sizeof (EvLinkDestPrivate));
+
+ g_object_class_install_property (g_object_class,
+ PROP_TYPE,
+ g_param_spec_enum ("type",
+ "Dest Type",
+ "The destination type",
+ EV_TYPE_LINK_DEST_TYPE,
+ EV_LINK_DEST_TYPE_UNKNOWN,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+ g_object_class_install_property (g_object_class,
+ PROP_PAGE,
+ g_param_spec_int ("page",
+ "Dest Page",
+ "The destination page",
+ -1,
+ G_MAXINT,
+ 0,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+ g_object_class_install_property (g_object_class,
+ PROP_LEFT,
+ g_param_spec_double ("left",
+ "Left coordinate",
+ "The left coordinate",
+ -G_MAXDOUBLE,
+ G_MAXDOUBLE,
+ 0,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+ g_object_class_install_property (g_object_class,
+ PROP_TOP,
+ g_param_spec_double ("top",
+ "Top coordinate",
+ "The top coordinate",
+ -G_MAXDOUBLE,
+ G_MAXDOUBLE,
+ 0,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+ g_object_class_install_property (g_object_class,
+ PROP_BOTTOM,
+ g_param_spec_double ("bottom",
+ "Bottom coordinate",
+ "The bottom coordinate",
+ -G_MAXDOUBLE,
+ G_MAXDOUBLE,
+ 0,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+ g_object_class_install_property (g_object_class,
+ PROP_RIGHT,
+ g_param_spec_double ("right",
+ "Right coordinate",
+ "The right coordinate",
+ -G_MAXDOUBLE,
+ G_MAXDOUBLE,
+ 0,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+
+ g_object_class_install_property (g_object_class,
+ PROP_ZOOM,
+ g_param_spec_double ("zoom",
+ "Zoom",
+ "Zoom",
+ 0,
+ G_MAXDOUBLE,
+ 0,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+ g_object_class_install_property (g_object_class,
+ PROP_CHANGE,
+ g_param_spec_uint ("change",
+ "Change",
+ "Wether top, left, and zoom should be changed",
+ 0,
+ G_MAXUINT,
+ 0,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+ g_object_class_install_property (g_object_class,
+ PROP_NAMED,
+ g_param_spec_string ("named",
+ "Named destination",
+ "The named destination",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+ g_object_class_install_property (g_object_class,
+ PROP_PAGE_LABEL,
+ g_param_spec_string ("page_label",
+ "Label of the page",
+ "The label of the destination page",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+}
+
+EvLinkDest *
+ev_link_dest_new_page (gint page)
+{
+ return EV_LINK_DEST (g_object_new (EV_TYPE_LINK_DEST,
+ "page", page,
+ "type", EV_LINK_DEST_TYPE_PAGE,
+ NULL));
+}
+
+EvLinkDest *
+ev_link_dest_new_xyz (gint page,
+ gdouble left,
+ gdouble top,
+ gdouble zoom,
+ gboolean change_left,
+ gboolean change_top,
+ gboolean change_zoom)
+{
+ EvDestChange change = 0;
+
+ if (change_left)
+ change |= EV_DEST_CHANGE_LEFT;
+ if (change_top)
+ change |= EV_DEST_CHANGE_TOP;
+ if (change_zoom)
+ change |= EV_DEST_CHANGE_ZOOM;
+
+ return EV_LINK_DEST (g_object_new (EV_TYPE_LINK_DEST,
+ "page", page,
+ "type", EV_LINK_DEST_TYPE_XYZ,
+ "left", left,
+ "top", top,
+ "zoom", zoom,
+ "change", change,
+ NULL));
+}
+
+EvLinkDest *
+ev_link_dest_new_fit (gint page)
+{
+ return EV_LINK_DEST (g_object_new (EV_TYPE_LINK_DEST,
+ "page", page,
+ "type", EV_LINK_DEST_TYPE_FIT,
+ NULL));
+}
+
+EvLinkDest *
+ev_link_dest_new_fith (gint page,
+ gdouble top,
+ gboolean change_top)
+{
+ EvDestChange change = 0;
+
+ if (change_top)
+ change |= EV_DEST_CHANGE_TOP;
+
+ return EV_LINK_DEST (g_object_new (EV_TYPE_LINK_DEST,
+ "page", page,
+ "type", EV_LINK_DEST_TYPE_FITH,
+ "top", top,
+ "change", change,
+ NULL));
+}
+
+EvLinkDest *
+ev_link_dest_new_fitv (gint page,
+ gdouble left,
+ gboolean change_left)
+{
+ EvDestChange change = 0;
+
+ if (change_left)
+ change |= EV_DEST_CHANGE_LEFT;
+
+ return EV_LINK_DEST (g_object_new (EV_TYPE_LINK_DEST,
+ "page", page,
+ "type", EV_LINK_DEST_TYPE_FITV,
+ "left", left,
+ "change", change,
+ NULL));
+}
+
+EvLinkDest *
+ev_link_dest_new_fitr (gint page,
+ gdouble left,
+ gdouble bottom,
+ gdouble right,
+ gdouble top)
+{
+ EvDestChange change = EV_DEST_CHANGE_TOP | EV_DEST_CHANGE_LEFT;
+
+ return EV_LINK_DEST (g_object_new (EV_TYPE_LINK_DEST,
+ "page", page,
+ "type", EV_LINK_DEST_TYPE_FITR,
+ "left", left,
+ "bottom", bottom,
+ "right", right,
+ "top", top,
+ "change", change,
+ NULL));
+}
+
+EvLinkDest *
+ev_link_dest_new_named (const gchar *named_dest)
+{
+ return EV_LINK_DEST (g_object_new (EV_TYPE_LINK_DEST,
+ "named", named_dest,
+ "type", EV_LINK_DEST_TYPE_NAMED,
+ NULL));
+}
+
+EvLinkDest *
+ev_link_dest_new_page_label (const gchar *page_label)
+{
+ return EV_LINK_DEST (g_object_new (EV_TYPE_LINK_DEST,
+ "page_label", page_label,
+ "type", EV_LINK_DEST_TYPE_PAGE_LABEL,
+ NULL));
+}
diff --git a/libdocument/ev-link-dest.h b/libdocument/ev-link-dest.h
new file mode 100644
index 00000000..2288d32c
--- /dev/null
+++ b/libdocument/ev-link-dest.h
@@ -0,0 +1,95 @@
+/* this file is part of evince, a mate document viewer
+ *
+ * Copyright (C) 2006 Carlos Garcia Campos <[email protected]>
+ * 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.
+ */
+
+#if !defined (__EV_EVINCE_DOCUMENT_H_INSIDE__) && !defined (EVINCE_COMPILATION)
+#error "Only <evince-document.h> can be included directly."
+#endif
+
+#ifndef EV_LINK_DEST_H
+#define EV_LINK_DEST_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+typedef struct _EvLinkDest EvLinkDest;
+typedef struct _EvLinkDestClass EvLinkDestClass;
+typedef struct _EvLinkDestPrivate EvLinkDestPrivate;
+
+#define EV_TYPE_LINK_DEST (ev_link_dest_get_type())
+#define EV_LINK_DEST(object) (G_TYPE_CHECK_INSTANCE_CAST((object), EV_TYPE_LINK_DEST, EvLinkDest))
+#define EV_LINK_DEST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), EV_TYPE_LINK_DEST, EvLinkDestClass))
+#define EV_IS_LINK_DEST(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), EV_TYPE_LINK_DEST))
+#define EV_IS_LINK_DEST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), EV_TYPE_LINK_DEST))
+#define EV_LINK_DEST_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS((object), EV_TYPE_LINK_DEST, EvLinkDestClass))
+
+typedef enum {
+ EV_LINK_DEST_TYPE_PAGE,
+ EV_LINK_DEST_TYPE_XYZ,
+ EV_LINK_DEST_TYPE_FIT,
+ EV_LINK_DEST_TYPE_FITH,
+ EV_LINK_DEST_TYPE_FITV,
+ EV_LINK_DEST_TYPE_FITR,
+ EV_LINK_DEST_TYPE_NAMED,
+ EV_LINK_DEST_TYPE_PAGE_LABEL,
+ EV_LINK_DEST_TYPE_UNKNOWN
+} EvLinkDestType;
+
+GType ev_link_dest_get_type (void) G_GNUC_CONST;
+
+EvLinkDestType ev_link_dest_get_dest_type (EvLinkDest *self);
+gint ev_link_dest_get_page (EvLinkDest *self);
+gdouble ev_link_dest_get_top (EvLinkDest *self,
+ gboolean *change_top);
+gdouble ev_link_dest_get_left (EvLinkDest *self,
+ gboolean *change_left);
+gdouble ev_link_dest_get_bottom (EvLinkDest *self);
+gdouble ev_link_dest_get_right (EvLinkDest *self);
+gdouble ev_link_dest_get_zoom (EvLinkDest *self,
+ gboolean *change_zoom);
+const gchar *ev_link_dest_get_named_dest (EvLinkDest *self);
+const gchar *ev_link_dest_get_page_label (EvLinkDest *self);
+
+EvLinkDest *ev_link_dest_new_page (gint page);
+EvLinkDest *ev_link_dest_new_xyz (gint page,
+ gdouble left,
+ gdouble top,
+ gdouble zoom,
+ gboolean change_left,
+ gboolean change_top,
+ gboolean change_zoom);
+EvLinkDest *ev_link_dest_new_fit (gint page);
+EvLinkDest *ev_link_dest_new_fith (gint page,
+ gdouble top,
+ gboolean change_top);
+EvLinkDest *ev_link_dest_new_fitv (gint page,
+ gdouble left,
+ gboolean change_left);
+EvLinkDest *ev_link_dest_new_fitr (gint page,
+ gdouble left,
+ gdouble bottom,
+ gdouble right,
+ gdouble top);
+EvLinkDest *ev_link_dest_new_named (const gchar *named_dest);
+EvLinkDest *ev_link_dest_new_page_label (const gchar *page_label);
+
+G_END_DECLS
+
+#endif /* EV_LINK_DEST_H */
diff --git a/libdocument/ev-link.c b/libdocument/ev-link.c
new file mode 100644
index 00000000..b521e68c
--- /dev/null
+++ b/libdocument/ev-link.c
@@ -0,0 +1,202 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; c-indent-level: 8 -*- */
+/* this file is part of evince, a mate 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <config.h>
+#include "ev-link.h"
+
+enum {
+ PROP_0,
+ PROP_TITLE,
+ PROP_ACTION
+};
+
+struct _EvLink {
+ GObject base_instance;
+ EvLinkPrivate *priv;
+};
+
+struct _EvLinkClass {
+ GObjectClass base_class;
+};
+
+struct _EvLinkPrivate {
+ gchar *title;
+ EvLinkAction *action;
+};
+
+G_DEFINE_TYPE (EvLink, ev_link, G_TYPE_OBJECT)
+
+#define EV_LINK_GET_PRIVATE(object) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((object), EV_TYPE_LINK, EvLinkPrivate))
+
+const gchar *
+ev_link_get_title (EvLink *self)
+{
+ g_return_val_if_fail (EV_IS_LINK (self), NULL);
+
+ return self->priv->title;
+}
+
+EvLinkAction *
+ev_link_get_action (EvLink *self)
+{
+ g_return_val_if_fail (EV_IS_LINK (self), NULL);
+
+ return self->priv->action;
+}
+
+static void
+ev_link_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *param_spec)
+{
+ EvLink *self;
+
+ self = EV_LINK (object);
+
+ switch (prop_id) {
+ case PROP_TITLE:
+ g_value_set_string (value, self->priv->title);
+ break;
+ case PROP_ACTION:
+ g_value_set_pointer (value, self->priv->action);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object,
+ prop_id,
+ param_spec);
+ break;
+ }
+}
+
+static void
+ev_link_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *param_spec)
+{
+ EvLink *self = EV_LINK (object);
+
+ switch (prop_id) {
+ case PROP_TITLE:
+ self->priv->title = g_value_dup_string (value);
+ break;
+ case PROP_ACTION:
+ self->priv->action = g_value_get_pointer (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object,
+ prop_id,
+ param_spec);
+ break;
+ }
+}
+
+static void
+ev_link_finalize (GObject *object)
+{
+ EvLinkPrivate *priv;
+
+ priv = EV_LINK (object)->priv;
+
+ if (priv->title) {
+ g_free (priv->title);
+ priv->title = NULL;
+ }
+
+ if (priv->action) {
+ g_object_unref (priv->action);
+ priv->action = NULL;
+ }
+
+ G_OBJECT_CLASS (ev_link_parent_class)->finalize (object);
+}
+
+static void
+ev_link_init (EvLink *ev_link)
+{
+ ev_link->priv = EV_LINK_GET_PRIVATE (ev_link);
+
+ ev_link->priv->title = NULL;
+ ev_link->priv->action = NULL;
+}
+
+static void
+ev_link_class_init (EvLinkClass *ev_window_class)
+{
+ GObjectClass *g_object_class;
+
+ g_object_class = G_OBJECT_CLASS (ev_window_class);
+
+ g_object_class->set_property = ev_link_set_property;
+ g_object_class->get_property = ev_link_get_property;
+
+ g_object_class->finalize = ev_link_finalize;
+
+ g_type_class_add_private (g_object_class, sizeof (EvLinkPrivate));
+
+ g_object_class_install_property (g_object_class,
+ PROP_TITLE,
+ g_param_spec_string ("title",
+ "Link Title",
+ "The link title",
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+ g_object_class_install_property (g_object_class,
+ PROP_ACTION,
+ g_param_spec_pointer ("action",
+ "Link Action",
+ "The link action",
+ G_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
+}
+
+EvLink *
+ev_link_new (const char *title,
+ EvLinkAction *action)
+{
+ return EV_LINK (g_object_new (EV_TYPE_LINK,
+ "title", title,
+ "action", action,
+ NULL));
+}
+
+gint
+ev_link_get_page (EvLink *link)
+{
+ EvLinkAction *action;
+ EvLinkDest *dest;
+
+ action = ev_link_get_action (link);
+ if (!action)
+ return -1;
+
+ if (ev_link_action_get_action_type (action) !=
+ EV_LINK_ACTION_TYPE_GOTO_DEST)
+ return -1;
+
+ dest = ev_link_action_get_dest (action);
+ if (dest)
+ return ev_link_dest_get_page (dest);
+
+ return -1;
+}
diff --git a/libdocument/ev-link.h b/libdocument/ev-link.h
new file mode 100644
index 00000000..9da28c9b
--- /dev/null
+++ b/libdocument/ev-link.h
@@ -0,0 +1,55 @@
+/* this file is part of evince, a mate 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#if !defined (__EV_EVINCE_DOCUMENT_H_INSIDE__) && !defined (EVINCE_COMPILATION)
+#error "Only <evince-document.h> can be included directly."
+#endif
+
+#ifndef EV_LINK_H
+#define EV_LINK_H
+
+#include <glib-object.h>
+#include "ev-document.h"
+#include "ev-link-action.h"
+
+G_BEGIN_DECLS
+
+typedef struct _EvLink EvLink;
+typedef struct _EvLinkClass EvLinkClass;
+typedef struct _EvLinkPrivate EvLinkPrivate;
+
+#define EV_TYPE_LINK (ev_link_get_type())
+#define EV_LINK(object) (G_TYPE_CHECK_INSTANCE_CAST((object), EV_TYPE_LINK, EvLink))
+#define EV_LINK_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), EV_TYPE_LINK, EvLinkClass))
+#define EV_IS_LINK(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), EV_TYPE_LINK))
+#define EV_IS_LINK_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), EV_TYPE_LINK))
+#define EV_LINK_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS((object), EV_TYPE_LINK, EvLinkClass))
+
+GType ev_link_get_type (void) G_GNUC_CONST;
+
+EvLink *ev_link_new (const gchar *title,
+ EvLinkAction *action);
+
+const gchar *ev_link_get_title (EvLink *self);
+EvLinkAction *ev_link_get_action (EvLink *self);
+gint ev_link_get_page (EvLink *link);
+
+G_END_DECLS
+
+#endif /* !EV_LINK_H */
diff --git a/libdocument/ev-mapping-list.c b/libdocument/ev-mapping-list.c
new file mode 100644
index 00000000..50ee9b77
--- /dev/null
+++ b/libdocument/ev-mapping-list.c
@@ -0,0 +1,146 @@
+/* ev-mapping.c
+ * this file is part of evince, a mate document viewer
+ *
+ * Copyright (C) 2009 Carlos Garcia Campos <[email protected]>
+ *
+ * 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 "ev-mapping-list.h"
+
+struct _EvMappingList {
+ guint page;
+ GList *list;
+ GDestroyNotify data_destroy_func;
+ volatile gint ref_count;
+};
+
+EvMapping *
+ev_mapping_list_find (EvMappingList *mapping_list,
+ gconstpointer data)
+{
+ GList *list;
+
+ for (list = mapping_list->list; list; list = list->next) {
+ EvMapping *mapping = list->data;
+
+ if (mapping->data == data)
+ return mapping;
+ }
+
+ return NULL;
+}
+
+EvMapping *
+ev_mapping_list_find_custom (EvMappingList *mapping_list,
+ gconstpointer data,
+ GCompareFunc func)
+{
+ GList *list;
+
+ for (list = mapping_list->list; list; list = list->next) {
+ EvMapping *mapping = list->data;
+
+ if (!func (mapping->data, data))
+ return mapping;
+ }
+
+ return NULL;
+}
+
+gpointer
+ev_mapping_list_get_data (EvMappingList *mapping_list,
+ gdouble x,
+ gdouble y)
+{
+ GList *list;
+
+ for (list = mapping_list->list; list; list = list->next) {
+ EvMapping *mapping = list->data;
+
+ if ((x >= mapping->area.x1) &&
+ (y >= mapping->area.y1) &&
+ (x <= mapping->area.x2) &&
+ (y <= mapping->area.y2)) {
+ return mapping->data;
+ }
+ }
+
+ return NULL;
+}
+
+GList *
+ev_mapping_list_get_list (EvMappingList *mapping_list)
+{
+ return mapping_list ? mapping_list->list : NULL;
+}
+
+guint
+ev_mapping_list_get_page (EvMappingList *mapping_list)
+{
+ return mapping_list->page;
+}
+
+EvMappingList *
+ev_mapping_list_new (guint page,
+ GList *list,
+ GDestroyNotify data_destroy_func)
+{
+ EvMappingList *mapping_list;
+
+ g_return_val_if_fail (data_destroy_func != NULL, NULL);
+
+ mapping_list = g_slice_new (EvMappingList);
+ mapping_list->page = page;
+ mapping_list->list = list;
+ mapping_list->data_destroy_func = data_destroy_func;
+ mapping_list->ref_count = 1;
+
+ return mapping_list;
+}
+
+EvMappingList *
+ev_mapping_list_ref (EvMappingList *mapping_list)
+{
+ g_return_val_if_fail (mapping_list != NULL, NULL);
+ g_return_val_if_fail (mapping_list->ref_count > 0, mapping_list);
+
+ g_atomic_int_add (&mapping_list->ref_count, 1);
+
+ return mapping_list;
+}
+
+static void
+mapping_list_free_foreach (EvMapping *mapping,
+ GDestroyNotify destroy_func)
+{
+ destroy_func (mapping->data);
+ g_free (mapping);
+}
+
+void
+ev_mapping_list_unref (EvMappingList *mapping_list)
+{
+ g_return_if_fail (mapping_list != NULL);
+ g_return_if_fail (mapping_list->ref_count > 0);
+
+ if (g_atomic_int_exchange_and_add (&mapping_list->ref_count, -1) - 1 == 0) {
+ g_list_foreach (mapping_list->list,
+ (GFunc)mapping_list_free_foreach,
+ mapping_list->data_destroy_func);
+ g_list_free (mapping_list->list);
+ g_slice_free (EvMappingList, mapping_list);
+ }
+}
diff --git a/libdocument/ev-mapping-list.h b/libdocument/ev-mapping-list.h
new file mode 100644
index 00000000..c86aee5e
--- /dev/null
+++ b/libdocument/ev-mapping-list.h
@@ -0,0 +1,53 @@
+/* ev-mapping.h
+ * this file is part of evince, a mate document viewer
+ *
+ * Copyright (C) 2009 Carlos Garcia Campos <[email protected]>
+ *
+ * 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.
+ */
+
+#if !defined (__EV_EVINCE_DOCUMENT_H_INSIDE__) && !defined (EVINCE_COMPILATION)
+#error "Only <evince-document.h> can be included directly."
+#endif
+
+#ifndef EV_MAPPING_LIST_H
+#define EV_MAPPING_LIST_H
+
+#include "ev-document.h"
+
+G_BEGIN_DECLS
+
+typedef struct _EvMappingList EvMappingList;
+
+EvMappingList *ev_mapping_list_new (guint page,
+ GList *list,
+ GDestroyNotify data_destroy_func);
+EvMappingList *ev_mapping_list_ref (EvMappingList *mapping_list);
+void ev_mapping_list_unref (EvMappingList *mapping_list);
+
+guint ev_mapping_list_get_page (EvMappingList *mapping_list);
+GList *ev_mapping_list_get_list (EvMappingList *mapping_list);
+EvMapping *ev_mapping_list_find (EvMappingList *mapping_list,
+ gconstpointer data);
+EvMapping *ev_mapping_list_find_custom (EvMappingList *mapping_list,
+ gconstpointer data,
+ GCompareFunc func);
+gpointer ev_mapping_list_get_data (EvMappingList *mapping_list,
+ gdouble x,
+ gdouble y);
+
+G_END_DECLS
+
+#endif /* EV_MAPPING_LIST_H */
diff --git a/libdocument/ev-module.c b/libdocument/ev-module.c
new file mode 100644
index 00000000..330da2cc
--- /dev/null
+++ b/libdocument/ev-module.c
@@ -0,0 +1,196 @@
+/*
+ * ev-module.c
+ * This file is part of Evince
+ *
+ * Copyright (C) 2005 - Paolo Maggi
+ *
+ * This program 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.
+ *
+ * This program 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.
+ */
+
+/* This is a modified version of ephy-module.c from Epiphany source code.
+ * Here the original copyright assignment:
+ *
+ * Copyright (C) 2003 Marco Pesenti Gritti
+ * Copyright (C) 2003, 2004 Christian Persch
+ *
+ */
+
+/*
+ * Modified by the gedit Team, 2005. See the AUTHORS file for a
+ * list of people on the gedit Team.
+ * See the ChangeLog files for a list of changes.
+ *
+ * $Id: gedit-module.c 5367 2006-12-17 14:29:49Z pborelli $
+ */
+
+/* Modified by evince team */
+
+#include "config.h"
+
+#include "ev-module.h"
+
+#include <gmodule.h>
+
+typedef struct _EvModuleClass EvModuleClass;
+
+struct _EvModuleClass {
+ GTypeModuleClass parent_class;
+};
+
+struct _EvModule {
+ GTypeModule parent_instance;
+
+ GModule *library;
+ gboolean resident;
+
+ gchar *path;
+ GType type;
+};
+
+typedef GType (*EvModuleRegisterFunc) (GTypeModule *);
+
+static void ev_module_init (EvModule *action);
+static void ev_module_class_init (EvModuleClass *class);
+
+G_DEFINE_TYPE (EvModule, ev_module, G_TYPE_TYPE_MODULE)
+
+static gboolean
+ev_module_load (GTypeModule *gmodule)
+{
+ EvModule *module = EV_MODULE (gmodule);
+ EvModuleRegisterFunc register_func;
+
+ module->library = g_module_open (module->path, 0);
+
+ if (!module->library) {
+ g_warning ("%s", g_module_error ());
+
+ return FALSE;
+ }
+
+ /* extract symbols from the lib */
+ if (!g_module_symbol (module->library, "register_evince_backend",
+ (void *) &register_func)) {
+ g_warning ("%s", g_module_error ());
+ g_module_close (module->library);
+
+ return FALSE;
+ }
+
+ /* symbol can still be NULL even though g_module_symbol
+ * returned TRUE */
+ if (!register_func) {
+ g_warning ("Symbol 'register_evince_backend' should not be NULL");
+ g_module_close (module->library);
+
+ return FALSE;
+ }
+
+ module->type = register_func (gmodule);
+
+ if (module->type == 0) {
+ g_warning ("Invalid evince backend contained by module %s", module->path);
+
+ return FALSE;
+ }
+
+ if (module->resident)
+ g_module_make_resident (module->library);
+
+ return TRUE;
+}
+
+static void
+ev_module_unload (GTypeModule *gmodule)
+{
+ EvModule *module = EV_MODULE (gmodule);
+
+ g_module_close (module->library);
+
+ module->library = NULL;
+ module->type = 0;
+}
+
+const gchar *
+ev_module_get_path (EvModule *module)
+{
+ g_return_val_if_fail (EV_IS_MODULE (module), NULL);
+
+ return module->path;
+}
+
+GObject *
+ev_module_new_object (EvModule *module)
+{
+ g_return_val_if_fail (EV_IS_MODULE (module), NULL);
+
+ if (module->type == 0)
+ return NULL;
+
+ return g_object_new (module->type, NULL);
+}
+
+GType
+ev_module_get_object_type (EvModule *module)
+{
+ g_return_val_if_fail (EV_IS_MODULE (module), 0);
+
+ return module->type;
+}
+
+static void
+ev_module_init (EvModule *module)
+{
+}
+
+static void
+ev_module_finalize (GObject *object)
+{
+ EvModule *module = EV_MODULE (object);
+
+ g_free (module->path);
+
+ G_OBJECT_CLASS (ev_module_parent_class)->finalize (object);
+}
+
+static void
+ev_module_class_init (EvModuleClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+ GTypeModuleClass *module_class = G_TYPE_MODULE_CLASS (class);
+
+ object_class->finalize = ev_module_finalize;
+
+ module_class->load = ev_module_load;
+ module_class->unload = ev_module_unload;
+}
+
+EvModule *
+ev_module_new (const gchar *path,
+ gboolean resident)
+{
+ EvModule *result;
+
+ g_return_val_if_fail (path != NULL && path[0] != '\0', NULL);
+
+ result = g_object_new (EV_TYPE_MODULE, NULL);
+
+ g_type_module_set_name (G_TYPE_MODULE (result), path);
+ result->path = g_strdup (path);
+ result->resident = resident;
+
+ return result;
+}
diff --git a/libdocument/ev-module.h b/libdocument/ev-module.h
new file mode 100644
index 00000000..8ac33626
--- /dev/null
+++ b/libdocument/ev-module.h
@@ -0,0 +1,74 @@
+/*
+ * ev-module.h
+ * This file is part of Evince
+ *
+ * Copyright (C) 2005 - Paolo Maggi
+ *
+ * This program 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.
+ *
+ * This program 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.
+ */
+
+/* This is a modified version of gedit-module.h from Epiphany source code.
+ * Here the original copyright assignment:
+ *
+ * Copyright (C) 2003 Marco Pesenti Gritti
+ * Copyright (C) 2003, 2004 Christian Persch
+ *
+ */
+
+/*
+ * Modified by the gedit Team, 2005. See the AUTHORS file for a
+ * list of people on the gedit Team.
+ * See the ChangeLog files for a list of changes.
+ *
+ * $Id: gedit-module.h 5263 2006-10-08 14:26:02Z pborelli $
+ */
+
+/* Modified by Evince Team */
+
+#if !defined (EVINCE_COMPILATION)
+#error "This is a private header."
+#endif
+
+#ifndef EV_MODULE_H
+#define EV_MODULE_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define EV_TYPE_MODULE (ev_module_get_type ())
+#define EV_MODULE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EV_TYPE_MODULE, EvModule))
+#define EV_MODULE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EV_TYPE_MODULE, EvModuleClass))
+#define EV_IS_MODULE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EV_TYPE_MODULE))
+#define EV_IS_MODULE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), EV_TYPE_MODULE))
+#define EV_MODULE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), EV_TYPE_MODULE, EvModuleClass))
+
+typedef struct _EvModule EvModule;
+
+GType ev_module_get_type (void) G_GNUC_CONST;
+
+EvModule *ev_module_new (const gchar *path,
+ gboolean resident);
+
+const gchar *ev_module_get_path (EvModule *module);
+
+GObject *ev_module_new_object (EvModule *module);
+
+GType ev_module_get_object_type (EvModule *module);
+
+G_END_DECLS
+
+#endif /* EV_MODULE_H */
diff --git a/libdocument/ev-page.c b/libdocument/ev-page.c
new file mode 100644
index 00000000..3e122332
--- /dev/null
+++ b/libdocument/ev-page.c
@@ -0,0 +1,62 @@
+/* this file is part of evince, a mate document viewer
+ *
+ * Copyright (C) 2008 Carlos Garcia Campos <[email protected]>
+ *
+ * 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-page.h"
+
+G_DEFINE_TYPE (EvPage, ev_page, G_TYPE_OBJECT)
+
+static void
+ev_page_init (EvPage *page)
+{
+}
+
+static void
+ev_page_finalize (GObject *object)
+{
+ EvPage *page = EV_PAGE (object);
+
+ if (page->backend_destroy_func) {
+ page->backend_destroy_func (page->backend_page);
+ page->backend_destroy_func = NULL;
+ }
+ page->backend_page = NULL;
+
+ (* G_OBJECT_CLASS (ev_page_parent_class)->finalize) (object);
+}
+
+static void
+ev_page_class_init (EvPageClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = ev_page_finalize;
+}
+
+EvPage *
+ev_page_new (gint index)
+{
+ EvPage *page;
+
+ page = EV_PAGE (g_object_new (EV_TYPE_PAGE, NULL));
+ page->index = index;
+
+ return page;
+}
diff --git a/libdocument/ev-page.h b/libdocument/ev-page.h
new file mode 100644
index 00000000..5365107a
--- /dev/null
+++ b/libdocument/ev-page.h
@@ -0,0 +1,63 @@
+/* this file is part of evince, a mate document viewer
+ *
+ * Copyright (C) 2008 Carlos Garcia Campos <[email protected]>
+ *
+ * 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.
+ */
+
+#if !defined (__EV_EVINCE_DOCUMENT_H_INSIDE__) && !defined (EVINCE_COMPILATION)
+#error "Only <evince-document.h> can be included directly."
+#endif
+
+#ifndef EV_PAGE_H
+#define EV_PAGE_H
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define EV_TYPE_PAGE (ev_page_get_type())
+#define EV_PAGE(object) (G_TYPE_CHECK_INSTANCE_CAST((object), EV_TYPE_PAGE, EvPage))
+#define EV_PAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), EV_TYPE_PAGE, EvPageClass))
+#define EV_IS_PAGE(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), EV_TYPE_PAGE))
+#define EV_IS_PAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), EV_TYPE_PAGE))
+#define EV_PAGE_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS((object), EV_TYPE_PAGE, EvPageClass))
+
+typedef struct _EvPage EvPage;
+typedef struct _EvPageClass EvPageClass;
+
+typedef gpointer EvBackendPage;
+typedef GDestroyNotify EvBackendPageDestroyFunc;
+
+struct _EvPage {
+ GObject base_instance;
+
+ gint index;
+
+ EvBackendPage backend_page;
+ EvBackendPageDestroyFunc backend_destroy_func;
+};
+
+struct _EvPageClass {
+ GObjectClass base_class;
+};
+
+GType ev_page_get_type (void) G_GNUC_CONST;
+
+EvPage *ev_page_new (gint index);
+
+G_END_DECLS
+
+#endif /* EV_PAGE_H */
diff --git a/libdocument/ev-render-context.c b/libdocument/ev-render-context.c
new file mode 100644
index 00000000..79dfa962
--- /dev/null
+++ b/libdocument/ev-render-context.c
@@ -0,0 +1,101 @@
+/* this file is part of evince, a mate document viewer
+ *
+ * Copyright (C) 2005 Jonathan Blandford <[email protected]>
+ *
+ * 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-render-context.h"
+
+static void ev_render_context_init (EvRenderContext *rc);
+static void ev_render_context_class_init (EvRenderContextClass *class);
+
+
+G_DEFINE_TYPE (EvRenderContext, ev_render_context, G_TYPE_OBJECT);
+
+static void ev_render_context_init (EvRenderContext *rc) { /* Do Nothing */ }
+
+static void
+ev_render_context_dispose (GObject *object)
+{
+ EvRenderContext *rc;
+
+ rc = (EvRenderContext *) object;
+
+ if (rc->page) {
+ g_object_unref (rc->page);
+ rc->page = NULL;
+ }
+
+ (* G_OBJECT_CLASS (ev_render_context_parent_class)->dispose) (object);
+}
+
+static void
+ev_render_context_class_init (EvRenderContextClass *class)
+{
+ GObjectClass *oclass;
+
+ oclass = G_OBJECT_CLASS (class);
+
+ oclass->dispose = ev_render_context_dispose;
+}
+
+EvRenderContext *
+ev_render_context_new (EvPage *page,
+ gint rotation,
+ gdouble scale)
+{
+ EvRenderContext *rc;
+
+ rc = (EvRenderContext *) g_object_new (EV_TYPE_RENDER_CONTEXT, NULL);
+
+ rc->page = page ? g_object_ref (page) : NULL;
+ rc->rotation = rotation;
+ rc->scale = scale;
+
+ return rc;
+}
+
+void
+ev_render_context_set_page (EvRenderContext *rc,
+ EvPage *page)
+{
+ g_return_if_fail (rc != NULL);
+ g_return_if_fail (EV_IS_PAGE (page));
+
+ if (rc->page)
+ g_object_unref (rc->page);
+ rc->page = g_object_ref (page);
+}
+
+void
+ev_render_context_set_rotation (EvRenderContext *rc,
+ int rotation)
+{
+ g_return_if_fail (rc != NULL);
+
+ rc->rotation = rotation;
+}
+
+void
+ev_render_context_set_scale (EvRenderContext *rc,
+ gdouble scale)
+{
+ g_return_if_fail (rc != NULL);
+
+ rc->scale = scale;
+}
+
diff --git a/libdocument/ev-render-context.h b/libdocument/ev-render-context.h
new file mode 100644
index 00000000..b7a5bf71
--- /dev/null
+++ b/libdocument/ev-render-context.h
@@ -0,0 +1,70 @@
+/* this file is part of evince, a mate document viewer
+ *
+ * Copyright (C) 2005 Jonathan Blandford <[email protected]>
+ *
+ * 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.
+ */
+
+#if !defined (__EV_EVINCE_DOCUMENT_H_INSIDE__) && !defined (EVINCE_COMPILATION)
+#error "Only <evince-document.h> can be included directly."
+#endif
+
+#ifndef EV_RENDER_CONTEXT_H
+#define EV_RENDER_CONTEXT_H
+
+#include <glib-object.h>
+
+#include "ev-page.h"
+
+G_BEGIN_DECLS
+
+typedef struct _EvRenderContext EvRenderContext;
+typedef struct _EvRenderContextClass EvRenderContextClass;
+
+#define EV_TYPE_RENDER_CONTEXT (ev_render_context_get_type())
+#define EV_RENDER_CONTEXT(object) (G_TYPE_CHECK_INSTANCE_CAST((object), EV_TYPE_RENDER_CONTEXT, EvRenderContext))
+#define EV_RENDER_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), EV_TYPE_RENDER_CONTEXT, EvRenderContextClass))
+#define EV_IS_RENDER_CONTEXT(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), EV_TYPE_RENDER_CONTEXT))
+
+struct _EvRenderContextClass
+{
+ GObjectClass klass;
+};
+
+struct _EvRenderContext
+{
+ GObject parent;
+
+ EvPage *page;
+ gint rotation;
+ gdouble scale;
+};
+
+
+GType ev_render_context_get_type (void) G_GNUC_CONST;
+EvRenderContext *ev_render_context_new (EvPage *page,
+ gint rotation,
+ gdouble scale);
+void ev_render_context_set_page (EvRenderContext *rc,
+ EvPage *page);
+void ev_render_context_set_rotation (EvRenderContext *rc,
+ gint rotation);
+void ev_render_context_set_scale (EvRenderContext *rc,
+ gdouble scale);
+
+
+G_END_DECLS
+
+#endif /* !EV_RENDER_CONTEXT */
diff --git a/libdocument/ev-selection.c b/libdocument/ev-selection.c
new file mode 100644
index 00000000..49e56eb4
--- /dev/null
+++ b/libdocument/ev-selection.c
@@ -0,0 +1,77 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; c-indent-level: 8 -*- */
+/*
+ * Copyright (C) 2005 Red Hat, Inc.
+ *
+ * This program 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, or (at your option)
+ * any later version.
+ *
+ * This program 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-selection.h"
+
+G_DEFINE_INTERFACE (EvSelection, ev_selection, 0)
+
+static void
+ev_selection_default_init (EvSelectionInterface *klass)
+{
+}
+
+void
+ev_selection_render_selection (EvSelection *selection,
+ EvRenderContext *rc,
+ cairo_surface_t **surface,
+ EvRectangle *points,
+ EvRectangle *old_points,
+ EvSelectionStyle style,
+ GdkColor *text,
+ GdkColor *base)
+{
+ EvSelectionInterface *iface = EV_SELECTION_GET_IFACE (selection);
+
+ if (!iface->render_selection)
+ return;
+
+ iface->render_selection (selection, rc,
+ surface,
+ points, old_points,
+ style,
+ text, base);
+}
+
+gchar *
+ev_selection_get_selected_text (EvSelection *selection,
+ EvPage *page,
+ EvSelectionStyle style,
+ EvRectangle *points)
+{
+ EvSelectionInterface *iface = EV_SELECTION_GET_IFACE (selection);
+
+ return iface->get_selected_text (selection, page, style, points);
+}
+
+cairo_region_t *
+ev_selection_get_selection_region (EvSelection *selection,
+ EvRenderContext *rc,
+ EvSelectionStyle style,
+ EvRectangle *points)
+{
+ EvSelectionInterface *iface = EV_SELECTION_GET_IFACE (selection);
+
+ if (!iface->get_selection_region)
+ return NULL;
+
+ return iface->get_selection_region (selection, rc, style, points);
+}
diff --git a/libdocument/ev-selection.h b/libdocument/ev-selection.h
new file mode 100644
index 00000000..dff12e0a
--- /dev/null
+++ b/libdocument/ev-selection.h
@@ -0,0 +1,93 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; c-indent-level: 8 -*- */
+/*
+ * Copyright (C) 2000-2003 Marco Pesenti Gritti
+ *
+ * This program 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, or (at your option)
+ * any later version.
+ *
+ * This program 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.
+ *
+ */
+
+#if !defined (__EV_EVINCE_DOCUMENT_H_INSIDE__) && !defined (EVINCE_COMPILATION)
+#error "Only <evince-document.h> can be included directly."
+#endif
+
+#ifndef EV_SELECTION_H
+#define EV_SELECTION_H
+
+#include <glib-object.h>
+#include <glib.h>
+#include <gdk/gdk.h>
+#include "ev-document.h"
+
+G_BEGIN_DECLS
+
+#define EV_TYPE_SELECTION (ev_selection_get_type ())
+#define EV_SELECTION(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), EV_TYPE_SELECTION, EvSelection))
+#define EV_SELECTION_IFACE(k) (G_TYPE_CHECK_CLASS_CAST((k), EV_TYPE_SELECTION, EvSelectionInterface))
+#define EV_IS_SELECTION(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), EV_TYPE_SELECTION))
+#define EV_IS_SELECTION_IFACE(k) (G_TYPE_CHECK_CLASS_TYPE ((k), EV_TYPE_SELECTION))
+#define EV_SELECTION_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), EV_TYPE_SELECTION, EvSelectionInterface))
+
+typedef enum {
+ EV_SELECTION_STYLE_GLYPH,
+ EV_SELECTION_STYLE_WORD,
+ EV_SELECTION_STYLE_LINE
+} EvSelectionStyle;
+
+typedef struct _EvSelection EvSelection;
+typedef struct _EvSelectionInterface EvSelectionInterface;
+
+struct _EvSelectionInterface
+{
+ GTypeInterface base_iface;
+
+ void (* render_selection) (EvSelection *selection,
+ EvRenderContext *rc,
+ cairo_surface_t **surface,
+ EvRectangle *points,
+ EvRectangle *old_points,
+ EvSelectionStyle style,
+ GdkColor *text,
+ GdkColor *base);
+ gchar * (* get_selected_text) (EvSelection *selection,
+ EvPage *page,
+ EvSelectionStyle style,
+ EvRectangle *points);
+ cairo_region_t * (* get_selection_region) (EvSelection *selection,
+ EvRenderContext *rc,
+ EvSelectionStyle style,
+ EvRectangle *points);
+};
+
+GType ev_selection_get_type (void) G_GNUC_CONST;
+void ev_selection_render_selection (EvSelection *selection,
+ EvRenderContext *rc,
+ cairo_surface_t **surface,
+ EvRectangle *points,
+ EvRectangle *old_points,
+ EvSelectionStyle style,
+ GdkColor *text,
+ GdkColor *base);
+gchar *ev_selection_get_selected_text (EvSelection *selection,
+ EvPage *page,
+ EvSelectionStyle style,
+ EvRectangle *points);
+cairo_region_t *ev_selection_get_selection_region (EvSelection *selection,
+ EvRenderContext *rc,
+ EvSelectionStyle style,
+ EvRectangle *points);
+
+G_END_DECLS
+
+#endif
diff --git a/libdocument/ev-transition-effect.c b/libdocument/ev-transition-effect.c
new file mode 100644
index 00000000..72bd67c2
--- /dev/null
+++ b/libdocument/ev-transition-effect.c
@@ -0,0 +1,224 @@
+/* ev-transition-effect.c
+ * this file is part of evince, a mate document viewer
+ *
+ * Copyright (C) 2007 Carlos Garnacho <[email protected]>
+ *
+ * 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-transition-effect.h"
+
+#include "ev-document-type-builtins.h"
+
+#define EV_TRANSITION_EFFECT_GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), EV_TYPE_TRANSITION_EFFECT, EvTransitionEffectPrivate))
+
+typedef struct EvTransitionEffectPrivate EvTransitionEffectPrivate;
+
+struct EvTransitionEffectPrivate {
+ EvTransitionEffectType type;
+ EvTransitionEffectAlignment alignment;
+ EvTransitionEffectDirection direction;
+
+ gint duration;
+ gint angle;
+ gdouble scale;
+
+ guint rectangular : 1;
+};
+
+enum {
+ PROP_0,
+ PROP_TYPE,
+ PROP_ALIGNMENT,
+ PROP_DIRECTION,
+ PROP_DURATION,
+ PROP_ANGLE,
+ PROP_SCALE,
+ PROP_RECTANGULAR
+};
+
+G_DEFINE_TYPE (EvTransitionEffect, ev_transition_effect, G_TYPE_OBJECT)
+
+static void
+ev_transition_effect_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ EvTransitionEffectPrivate *priv;
+
+ priv = EV_TRANSITION_EFFECT_GET_PRIV (object);
+
+ switch (prop_id) {
+ case PROP_TYPE:
+ priv->type = g_value_get_enum (value);
+ break;
+ case PROP_ALIGNMENT:
+ priv->alignment = g_value_get_enum (value);
+ break;
+ case PROP_DIRECTION:
+ priv->direction = g_value_get_enum (value);
+ break;
+ case PROP_DURATION:
+ priv->duration = g_value_get_int (value);
+ break;
+ case PROP_ANGLE:
+ priv->angle = g_value_get_int (value);
+ break;
+ case PROP_SCALE:
+ priv->scale = g_value_get_double (value);
+ break;
+ case PROP_RECTANGULAR:
+ priv->rectangular = g_value_get_boolean (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+ev_transition_effect_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ EvTransitionEffectPrivate *priv;
+
+ priv = EV_TRANSITION_EFFECT_GET_PRIV (object);
+
+ switch (prop_id) {
+ case PROP_TYPE:
+ g_value_set_enum (value, priv->type);
+ break;
+ case PROP_ALIGNMENT:
+ g_value_set_enum (value, priv->alignment);
+ break;
+ case PROP_DIRECTION:
+ g_value_set_enum (value, priv->direction);
+ break;
+ case PROP_DURATION:
+ g_value_set_int (value, priv->duration);
+ break;
+ case PROP_ANGLE:
+ g_value_set_int (value, priv->angle);
+ break;
+ case PROP_SCALE:
+ g_value_set_double (value, priv->scale);
+ break;
+ case PROP_RECTANGULAR:
+ g_value_set_enum (value, priv->rectangular);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+ev_transition_effect_init (EvTransitionEffect *effect)
+{
+ EvTransitionEffectPrivate *priv;
+
+ priv = EV_TRANSITION_EFFECT_GET_PRIV (effect);
+
+ priv->scale = 1.;
+}
+
+static void
+ev_transition_effect_class_init (EvTransitionEffectClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->set_property = ev_transition_effect_set_property;
+ object_class->get_property = ev_transition_effect_get_property;
+
+ g_object_class_install_property (object_class,
+ PROP_TYPE,
+ g_param_spec_enum ("type",
+ "Effect type",
+ "Page transition effect type",
+ EV_TYPE_TRANSITION_EFFECT_TYPE,
+ EV_TRANSITION_EFFECT_REPLACE,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (object_class,
+ PROP_ALIGNMENT,
+ g_param_spec_enum ("alignment",
+ "Effect alignment",
+ "Alignment for the effect",
+ EV_TYPE_TRANSITION_EFFECT_ALIGNMENT,
+ EV_TRANSITION_ALIGNMENT_HORIZONTAL,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (object_class,
+ PROP_DIRECTION,
+ g_param_spec_enum ("direction",
+ "Effect direction",
+ "Direction for the effect",
+ EV_TYPE_TRANSITION_EFFECT_DIRECTION,
+ EV_TRANSITION_DIRECTION_INWARD,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (object_class,
+ PROP_DURATION,
+ g_param_spec_int ("duration",
+ "Effect duration",
+ "Effect duration in seconds",
+ 0, G_MAXINT, 0,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (object_class,
+ PROP_ANGLE,
+ g_param_spec_int ("angle",
+ "Effect angle",
+ "Effect angle in degrees, counted "
+ "counterclockwise from left to right",
+ 0, 360, 0,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (object_class,
+ PROP_SCALE,
+ g_param_spec_double ("scale",
+ "Effect scale",
+ "Scale at which the effect is applied",
+ 0., 1., 1.,
+ G_PARAM_READWRITE));
+ g_object_class_install_property (object_class,
+ PROP_RECTANGULAR,
+ g_param_spec_boolean ("rectangular",
+ "Rectangular area",
+ "Whether the covered area is rectangular",
+ FALSE,
+ G_PARAM_READWRITE));
+
+ g_type_class_add_private (klass, sizeof (EvTransitionEffectPrivate));
+}
+
+EvTransitionEffect *
+ev_transition_effect_new (EvTransitionEffectType type,
+ const gchar *first_property_name,
+ ...)
+{
+ GObject *object;
+ va_list args;
+
+ object = g_object_new (EV_TYPE_TRANSITION_EFFECT,
+ "type", type,
+ NULL);
+
+ va_start (args, first_property_name);
+ g_object_set_valist (object, first_property_name, args);
+ va_end (args);
+
+ return EV_TRANSITION_EFFECT (object);
+}
diff --git a/libdocument/ev-transition-effect.h b/libdocument/ev-transition-effect.h
new file mode 100644
index 00000000..23591a51
--- /dev/null
+++ b/libdocument/ev-transition-effect.h
@@ -0,0 +1,87 @@
+/* ev-transition-effect.h
+ * this file is part of evince, a mate document viewer
+ *
+ * Copyright (C) 2007 Carlos Garnacho <[email protected]>
+ *
+ * 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.
+ */
+
+#if !defined (__EV_EVINCE_DOCUMENT_H_INSIDE__) && !defined (EVINCE_COMPILATION)
+#error "Only <evince-document.h> can be included directly."
+#endif
+
+#ifndef __EV_TRANSITION_EFFECT_H__
+#define __EV_TRANSITION_EFFECT_H__
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+#define EV_TYPE_TRANSITION_EFFECT (ev_transition_effect_get_type ())
+#define EV_TRANSITION_EFFECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EV_TYPE_TRANSITION_EFFECT, EvTransitionEffect))
+#define EV_TRANSITION_EFFECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EV_TYPE_TRANSITION_EFFECT, EvTransitionEffectClass))
+#define EV_IS_TRANSITION_EFFECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EV_TYPE_TRANSITION_EFFECT))
+#define EV_IS_TRANSITION_EFFECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EV_TYPE_TRANSITION_EFFECT))
+#define EV_TRANSITION_EFFECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EV_TYPE_TRANSITION_EFFECT, EvTransitionEffectClass))
+
+typedef enum {
+ EV_TRANSITION_EFFECT_REPLACE,
+ EV_TRANSITION_EFFECT_SPLIT,
+ EV_TRANSITION_EFFECT_BLINDS,
+ EV_TRANSITION_EFFECT_BOX,
+ EV_TRANSITION_EFFECT_WIPE,
+ EV_TRANSITION_EFFECT_DISSOLVE,
+ EV_TRANSITION_EFFECT_GLITTER,
+ EV_TRANSITION_EFFECT_FLY,
+ EV_TRANSITION_EFFECT_PUSH,
+ EV_TRANSITION_EFFECT_COVER,
+ EV_TRANSITION_EFFECT_UNCOVER,
+ EV_TRANSITION_EFFECT_FADE
+} EvTransitionEffectType;
+
+typedef enum {
+ EV_TRANSITION_ALIGNMENT_HORIZONTAL,
+ EV_TRANSITION_ALIGNMENT_VERTICAL
+} EvTransitionEffectAlignment;
+
+typedef enum {
+ EV_TRANSITION_DIRECTION_INWARD,
+ EV_TRANSITION_DIRECTION_OUTWARD
+} EvTransitionEffectDirection;
+
+
+typedef struct EvTransitionEffect EvTransitionEffect;
+typedef struct EvTransitionEffectClass EvTransitionEffectClass;
+
+struct EvTransitionEffect
+{
+ GObject parent_instance;
+};
+
+struct EvTransitionEffectClass
+{
+ GObjectClass parent_class;
+};
+
+
+GType ev_transition_effect_get_type (void) G_GNUC_CONST;
+
+EvTransitionEffect *ev_transition_effect_new (EvTransitionEffectType type,
+ const gchar *first_property_name,
+ ...);
+
+G_END_DECLS
+
+#endif /* __EV_TRANSITION_EFFECT_H__ */
diff --git a/libdocument/ev-version.h.in b/libdocument/ev-version.h.in
new file mode 100644
index 00000000..97cf0a98
--- /dev/null
+++ b/libdocument/ev-version.h.in
@@ -0,0 +1,69 @@
+/*
+ * Copyright © 2009 Christian Persch
+ *
+ * This library is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published by the
+ * Free Software Foundation; either version 2.1 of the License, or (at your
+ * option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser 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.
+ */
+
+#ifndef EV_VERSION_H
+#define EV_VERSION_H
+
+/**
+ * SECTION:ev-version
+ * @short_description: Library version checks
+ *
+ * These macros enable compile time checks of the library version.
+ */
+
+/**
+ * EV_MAJOR_VERSION:
+ *
+ * The major version number of the EV library
+ * (e.g. in version 3.1.4 this is 3).
+ */
+
+#define EV_MAJOR_VERSION (@EV_MAJOR_VERSION@)
+
+/**
+ * EV_MINOR_VERSION:
+ *
+ * The minor version number of the EV library
+ * (e.g. in version 3.1.4 this is 1).
+ */
+#define EV_MINOR_VERSION (@EV_MINOR_VERSION@)
+
+/**
+ * EV_MICRO_VERSION:
+ *
+ * The micro version number of the EV library
+ * (e.g. in version 3.1.4 this is 4).
+ */
+#define EV_MICRO_VERSION (@EV_MICRO_VERSION@)
+
+/**
+ * EV_CHECK_VERSION:
+ * @major: required major version
+ * @minor: required minor version
+ * @micro: required micro version
+ *
+ * Macro to check the library version at compile time.
+ * It returns <literal>1</literal> if the version of EV is greater or
+ * equal to the required one, and <literal>0</literal> otherwise.
+ */
+#define EV_CHECK_VERSION(major,minor,micro) \
+ (EV_MAJOR_VERSION > (major) || \
+ (EV_MAJOR_VERSION == (major) && EV_MINOR_VERSION > (minor)) || \
+ (EV_MAJOR_VERSION == (major) && EV_MINOR_VERSION == (minor) && EV_MICRO_VERSION >= (micro)))
+
+#endif /* #ifndef EV_VERSION_H */