From 584f014b63c56fe3770cba9682fc21c31e09a2e9 Mon Sep 17 00:00:00 2001 From: Carlos Garcia Campos Date: Tue, 20 Jul 2010 15:01:56 +0000 Subject: Preliminary support for adding new annotations At the moment only Text annotations can be added. See bug #168304. --- (limited to 'libdocument') diff --git a/libdocument/ev-annotation.c b/libdocument/ev-annotation.c index 21ffc0a..f7acc0b 100644 --- a/libdocument/ev-annotation.c +++ b/libdocument/ev-annotation.c @@ -22,19 +22,86 @@ #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_0, - PROP_LABEL, - PROP_OPACITY, - PROP_HAS_POPUP, - PROP_RECTANGLE, - PROP_IS_OPEN + PROP_TEXT_0, + PROP_TEXT_ICON, + PROP_TEXT_IS_OPEN +}; + +/* EvAnnotationAttachment */ +enum { + PROP_ATTACHMENT_0, + PROP_ATTACHMENT_ATTACHMENT }; G_DEFINE_ABSTRACT_TYPE (EvAnnotation, ev_annotation, G_TYPE_OBJECT) @@ -82,6 +149,62 @@ ev_annotation_finalize (GObject *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 @@ -90,6 +213,208 @@ 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 */ @@ -97,8 +422,8 @@ typedef struct { gchar *label; gdouble opacity; gboolean has_popup; - gboolean is_open; - EvRectangle *rectangle; + gboolean popup_is_open; + EvRectangle rectangle; } EvAnnotationMarkupProps; static void @@ -119,7 +444,7 @@ ev_annotation_markup_default_init (EvAnnotationMarkupInterface *iface) "Opacity of the markup annotation", 0, G_MAXDOUBLE, - 0, + 1., G_PARAM_READWRITE)); g_object_interface_install_property (iface, g_param_spec_boolean ("has_popup", @@ -136,8 +461,8 @@ ev_annotation_markup_default_init (EvAnnotationMarkupInterface *iface) EV_TYPE_RECTANGLE, G_PARAM_READWRITE)); g_object_interface_install_property (iface, - g_param_spec_boolean ("is_open", - "Is open", + g_param_spec_boolean ("popup_is_open", + "PopupIsOpen", "Whether the popup associated to " "the markup annotation is open", FALSE, @@ -150,7 +475,6 @@ static void ev_annotation_markup_props_free (EvAnnotationMarkupProps *props) { g_free (props->label); - ev_rectangle_free (props->rectangle); g_slice_free (EvAnnotationMarkupProps, props); } @@ -180,27 +504,23 @@ ev_annotation_markup_set_property (GObject *object, const GValue *value, GParamSpec *pspec) { - EvAnnotationMarkupProps *props; - - props = ev_annotation_markup_get_properties (EV_ANNOTATION_MARKUP (object)); + EvAnnotationMarkup *markup = EV_ANNOTATION_MARKUP (object); switch (prop_id) { - case PROP_LABEL: - g_free (props->label); - props->label = g_value_dup_string (value); + case PROP_MARKUP_LABEL: + ev_annotation_markup_set_label (markup, g_value_get_string (value)); break; - case PROP_OPACITY: - props->opacity = g_value_get_double (value); + case PROP_MARKUP_OPACITY: + ev_annotation_markup_set_opacity (markup, g_value_get_double (value)); break; - case PROP_HAS_POPUP: - props->has_popup = g_value_get_boolean (value); + case PROP_MARKUP_HAS_POPUP: + ev_annotation_markup_set_has_popup (markup, g_value_get_boolean (value)); break; - case PROP_RECTANGLE: - ev_rectangle_free (props->rectangle); - props->rectangle = g_value_dup_boxed (value); + case PROP_MARKUP_RECTANGLE: + ev_annotation_markup_set_rectangle (markup, g_value_get_boxed (value)); break; - case PROP_IS_OPEN: - props->is_open = g_value_get_boolean (value); + 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); @@ -218,20 +538,20 @@ ev_annotation_markup_get_property (GObject *object, props = ev_annotation_markup_get_properties (EV_ANNOTATION_MARKUP (object)); switch (prop_id) { - case PROP_LABEL: + case PROP_MARKUP_LABEL: g_value_set_string (value, props->label); break; - case PROP_OPACITY: + case PROP_MARKUP_OPACITY: g_value_set_double (value, props->opacity); break; - case PROP_HAS_POPUP: + case PROP_MARKUP_HAS_POPUP: g_value_set_boolean (value, props->has_popup); break; - case PROP_RECTANGLE: - g_value_set_boxed (value, props->rectangle); + case PROP_MARKUP_RECTANGLE: + g_value_set_boxed (value, &props->rectangle); break; - case PROP_IS_OPEN: - g_value_set_boolean (value, props->is_open); + 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); @@ -244,106 +564,217 @@ 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_LABEL, "label"); - g_object_class_override_property (klass, PROP_OPACITY, "opacity"); - g_object_class_override_property (klass, PROP_HAS_POPUP, "has_popup"); - g_object_class_override_property (klass, PROP_RECTANGLE, "rectangle"); - g_object_class_override_property (klass, PROP_IS_OPEN, "is_open"); + 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"); } -gchar * +const gchar * ev_annotation_markup_get_label (EvAnnotationMarkup *markup) { - gchar *retval; + EvAnnotationMarkupProps *props; g_return_val_if_fail (EV_IS_ANNOTATION_MARKUP (markup), NULL); - g_object_get (G_OBJECT (markup), "label", &retval, NULL); - - return retval; + props = ev_annotation_markup_get_properties (markup); + return props->label; } -void +gboolean ev_annotation_markup_set_label (EvAnnotationMarkup *markup, const gchar *label) { - g_return_if_fail (EV_IS_ANNOTATION_MARKUP (markup)); - g_return_if_fail (label != NULL); + 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; - g_object_set (G_OBJECT (markup), "label", label, NULL); + 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) { - gdouble retval; - - g_return_val_if_fail (EV_IS_ANNOTATION_MARKUP (markup), 0.0); + EvAnnotationMarkupProps *props; - g_object_get (G_OBJECT (markup), "opacity", &retval, NULL); + g_return_val_if_fail (EV_IS_ANNOTATION_MARKUP (markup), 1.0); - return retval; + props = ev_annotation_markup_get_properties (markup); + return props->opacity; } -void +gboolean ev_annotation_markup_set_opacity (EvAnnotationMarkup *markup, gdouble opacity) { - g_return_if_fail (EV_IS_ANNOTATION_MARKUP (markup)); + EvAnnotationMarkupProps *props; - g_object_set (G_OBJECT (markup), "opacity", opacity, NULL); + 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) { - gboolean retval; + EvAnnotationMarkupProps *props; g_return_val_if_fail (EV_IS_ANNOTATION_MARKUP (markup), FALSE); - g_object_get (G_OBJECT (markup), "has_popup", &retval, NULL); + props = ev_annotation_markup_get_properties (markup); + return props->has_popup; +} - return retval; +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) { - EvRectangle *r; + EvAnnotationMarkupProps *props; g_return_if_fail (EV_IS_ANNOTATION_MARKUP (markup)); g_return_if_fail (ev_rect != NULL); - g_object_get (G_OBJECT (markup), "rectangle", &r, NULL); - *ev_rect = *r; + props = ev_annotation_markup_get_properties (markup); + *ev_rect = props->rectangle; } gboolean -ev_annotation_markup_get_is_open (EvAnnotationMarkup *markup) +ev_annotation_markup_set_rectangle (EvAnnotationMarkup *markup, + const EvRectangle *ev_rect) { - gboolean retval; + 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_get (G_OBJECT (markup), "is_open", &retval, NULL); + g_object_notify (G_OBJECT (markup), "rectangle"); - return retval; + return TRUE; } -void -ev_annotation_markup_set_is_open (EvAnnotationMarkup *markup, - gboolean is_open) +gboolean +ev_annotation_markup_get_popup_is_open (EvAnnotationMarkup *markup) { - g_return_if_fail (EV_IS_ANNOTATION_MARKUP (markup)); + EvAnnotationMarkupProps *props; + + g_return_val_if_fail (EV_IS_ANNOTATION_MARKUP (markup), FALSE); - g_object_set (G_OBJECT (markup), "is_open", is_open, NULL); + 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); + + 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); + + 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 @@ -351,7 +782,26 @@ ev_annotation_text_class_init (EvAnnotationTextClass *klass) { GObjectClass *g_object_class = G_OBJECT_CLASS (klass); + g_object_class->set_property = ev_annotation_text_set_property; + g_object_class->get_property = ev_annotation_text_get_property; + ev_annotation_markup_class_install_properties (g_object_class); + + 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 @@ -362,12 +812,57 @@ ev_annotation_text_markup_iface_init (EvAnnotationMarkupInterface *iface) EvAnnotation * ev_annotation_text_new (EvPage *page) { - EvAnnotation *annot; + return EV_ANNOTATION (g_object_new (EV_TYPE_ANNOTATION_TEXT, + "page", page, + NULL)); +} - annot = EV_ANNOTATION (g_object_new (EV_TYPE_ANNOTATION_TEXT, NULL)); - annot->page = g_object_ref (page); +EvAnnotationTextIcon +ev_annotation_text_get_icon (EvAnnotationText *text) +{ + g_return_val_if_fail (EV_IS_ANNOTATION_TEXT (text), 0); - return annot; + 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 */ @@ -387,6 +882,41 @@ ev_annotation_attachment_finalize (GObject *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); + + 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); + + 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 @@ -394,9 +924,20 @@ ev_annotation_attachment_class_init (EvAnnotationAttachmentClass *klass) { GObjectClass *g_object_class = G_OBJECT_CLASS (klass); + 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; + ev_annotation_markup_class_install_properties (g_object_class); - 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 @@ -408,13 +949,36 @@ EvAnnotation * ev_annotation_attachment_new (EvPage *page, EvAttachment *attachment) { - EvAnnotation *annot; - g_return_val_if_fail (EV_IS_ATTACHMENT (attachment), NULL); - annot = EV_ANNOTATION (g_object_new (EV_TYPE_ANNOTATION_ATTACHMENT, NULL)); - annot->page = g_object_ref (page); - EV_ANNOTATION_ATTACHMENT (annot)->attachment = g_object_ref (attachment); + 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 annot; + return TRUE; } diff --git a/libdocument/ev-annotation.h b/libdocument/ev-annotation.h index de8736e..554523c 100644 --- a/libdocument/ev-annotation.h +++ b/libdocument/ev-annotation.h @@ -77,80 +77,84 @@ typedef struct _EvAnnotationTextClass EvAnnotationTextClass; typedef struct _EvAnnotationAttachment EvAnnotationAttachment; typedef struct _EvAnnotationAttachmentClass EvAnnotationAttachmentClass; -struct _EvAnnotation -{ - GObject parent; - - EvPage *page; - gboolean changed; - - 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; -}; - -struct _EvAnnotationTextClass -{ - EvAnnotationClass parent_class; -}; - -struct _EvAnnotationAttachment -{ - EvAnnotation parent; - - EvAttachment *attachment; -}; - -struct _EvAnnotationAttachmentClass -{ - EvAnnotationClass parent_class; -}; +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; +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; -gchar *ev_annotation_markup_get_label (EvAnnotationMarkup *markup); -void ev_annotation_markup_set_label (EvAnnotationMarkup *markup, - const gchar *label); -gdouble ev_annotation_markup_get_opacity (EvAnnotationMarkup *markup); -void ev_annotation_markup_set_opacity (EvAnnotationMarkup *markup, - gdouble opacity); -gboolean ev_annotation_markup_has_popup (EvAnnotationMarkup *markup); -void ev_annotation_markup_get_rectangle (EvAnnotationMarkup *markup, - EvRectangle *ev_rect); -gboolean ev_annotation_markup_get_is_open (EvAnnotationMarkup *markup); -void ev_annotation_markup_set_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); +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_attachment_get_type (void) G_GNUC_CONST; -EvAnnotation *ev_annotation_attachment_new (EvPage *page, - EvAttachment *attachment); +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 diff --git a/libdocument/ev-document-annotations.c b/libdocument/ev-document-annotations.c index 6ccdd57..4bc039e 100644 --- a/libdocument/ev-document-annotations.c +++ b/libdocument/ev-document-annotations.c @@ -38,11 +38,30 @@ ev_document_annotations_get_annotations (EvDocumentAnnotations *document_annots, } void -ev_document_annotations_annotation_set_contents (EvDocumentAnnotations *document_annots, - EvAnnotation *annot, - const gchar *contents) +ev_document_annotations_save_annotation (EvDocumentAnnotations *document_annots, + EvAnnotation *annot, + EvAnnotationsSaveMask mask) { EvDocumentAnnotationsInterface *iface = EV_DOCUMENT_ANNOTATIONS_GET_IFACE (document_annots); - iface->annotation_set_contents (document_annots, annot, contents); + 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 index 6da49d9..8eb2c7c 100644 --- a/libdocument/ev-document-annotations.h +++ b/libdocument/ev-document-annotations.h @@ -40,6 +40,28 @@ G_BEGIN_DECLS #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; @@ -48,20 +70,26 @@ struct _EvDocumentAnnotationsInterface GTypeInterface base_iface; /* Methods */ - EvMappingList *(* get_annotations) (EvDocumentAnnotations *document_annots, - EvPage *page); - void (* annotation_set_contents) (EvDocumentAnnotations *document_annots, - EvAnnotation *annot, - const gchar *contents); + EvMappingList *(* get_annotations) (EvDocumentAnnotations *document_annots, + EvPage *page); + 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); - -void ev_document_annotations_annotation_set_contents (EvDocumentAnnotations *document_annots, - EvAnnotation *annot, - const gchar *contents); +GType ev_document_annotations_get_type (void) G_GNUC_CONST; +EvMappingList *ev_document_annotations_get_annotations (EvDocumentAnnotations *document_annots, + EvPage *page); +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 -- cgit v0.9.1