diff options
author | Perberos <[email protected]> | 2011-11-09 18:17:43 -0300 |
---|---|---|
committer | Perberos <[email protected]> | 2011-11-09 18:17:43 -0300 |
commit | f6ce926719943751cf65cacde7fae050593eb2d6 (patch) | |
tree | 9224d1751678cf2d1fbd0431f128b711311c0287 /libdocument | |
download | atril-f6ce926719943751cf65cacde7fae050593eb2d6.tar.bz2 atril-f6ce926719943751cf65cacde7fae050593eb2d6.tar.xz |
inicial
Diffstat (limited to 'libdocument')
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 *) ®ister_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 */ |