Evince
Evince is a document viewer capable of displaying multiple and single page document formats like PDF and Postscript.
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
ev-annotation.c
Go to the documentation of this file.
1 /* ev-annotation.c
2  * this file is part of evince, a gnome document viewer
3  *
4  * Copyright (C) 2009 Carlos Garcia Campos <carlosgc@gnome.org>
5  * Copyright (C) 2007 IƱigo Martinez <inigomartinez@gmail.com>
6  *
7  * Evince is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 2 of the License, or
10  * (at your option) any later version.
11  *
12  * Evince is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  */
21 
22 #include "config.h"
23 
24 #include "ev-annotation.h"
25 #include "ev-document-misc.h"
26 #include "ev-document-type-builtins.h"
27 
28 struct _EvAnnotation {
29  GObject parent;
30 
33 
34  gchar *contents;
35  gchar *name;
36  gchar *modified;
37  GdkRGBA rgba;
39 };
40 
42  GObjectClass parent_class;
43 };
44 
46  GTypeInterface base_iface;
47 };
48 
51 
52  gboolean is_open : 1;
54 };
55 
58 };
59 
62 
64 };
65 
68 };
69 
72 
74 };
75 
78 };
79 
84 
85 /* EvAnnotation */
86 enum {
95 };
96 
97 /* EvAnnotationMarkup */
98 enum {
106 };
107 
108 /* EvAnnotationText */
109 enum {
112 };
113 
114 /* EvAnnotationAttachment */
115 enum {
117 };
118 
119 /* EvAnnotationTextMarkup */
120 enum {
122 };
123 
124 G_DEFINE_ABSTRACT_TYPE (EvAnnotation, ev_annotation, G_TYPE_OBJECT)
125 G_DEFINE_INTERFACE (EvAnnotationMarkup, ev_annotation_markup, EV_TYPE_ANNOTATION)
127  {
128  G_IMPLEMENT_INTERFACE (EV_TYPE_ANNOTATION_MARKUP,
130  });
132  {
133  G_IMPLEMENT_INTERFACE (EV_TYPE_ANNOTATION_MARKUP,
135  });
137  {
138  G_IMPLEMENT_INTERFACE (EV_TYPE_ANNOTATION_MARKUP,
140  });
141 
142 /* EvAnnotation */
143 static void
144 ev_annotation_finalize (GObject *object)
145 {
146  EvAnnotation *annot = EV_ANNOTATION (object);
147 
148  if (annot->page) {
149  g_object_unref (annot->page);
150  annot->page = NULL;
151  }
152 
153  if (annot->contents) {
154  g_free (annot->contents);
155  annot->contents = NULL;
156  }
157 
158  if (annot->name) {
159  g_free (annot->name);
160  annot->name = NULL;
161  }
162 
163  if (annot->modified) {
164  g_free (annot->modified);
165  annot->modified = NULL;
166  }
167 
168  G_OBJECT_CLASS (ev_annotation_parent_class)->finalize (object);
169 }
170 
171 static void
173 {
175  annot->area.x1 = -1;
176  annot->area.y1 = -1;
177  annot->area.x2 = -1;
178  annot->area.y2 = -1;
179 }
180 
181 static void
182 ev_annotation_set_property (GObject *object,
183  guint prop_id,
184  const GValue *value,
185  GParamSpec *pspec)
186 {
187  EvAnnotation *annot = EV_ANNOTATION (object);
188 
189  switch (prop_id) {
190  case PROP_ANNOT_PAGE:
191  annot->page = g_value_dup_object (value);
192  break;
193  case PROP_ANNOT_CONTENTS:
194  ev_annotation_set_contents (annot, g_value_get_string (value));
195  break;
196  case PROP_ANNOT_NAME:
197  ev_annotation_set_name (annot, g_value_get_string (value));
198  break;
199  case PROP_ANNOT_MODIFIED:
200  ev_annotation_set_modified (annot, g_value_get_string (value));
201  break;
202  case PROP_ANNOT_COLOR:
203  ev_annotation_set_color (annot, g_value_get_pointer (value));
204  break;
205  case PROP_ANNOT_RGBA:
206  ev_annotation_set_rgba (annot, g_value_get_boxed (value));
207  break;
208  case PROP_ANNOT_AREA:
209  ev_annotation_set_area (annot, g_value_get_boxed (value));
210  break;
211  default:
212  G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
213  }
214 }
215 
216 static void
217 ev_annotation_get_property (GObject *object,
218  guint prop_id,
219  GValue *value,
220  GParamSpec *pspec)
221 {
222  EvAnnotation *annot = EV_ANNOTATION (object);
223 
224  switch (prop_id) {
225  case PROP_ANNOT_CONTENTS:
226  g_value_set_string (value, ev_annotation_get_contents (annot));
227  break;
228  case PROP_ANNOT_NAME:
229  g_value_set_string (value, ev_annotation_get_name (annot));
230  break;
231  case PROP_ANNOT_MODIFIED:
232  g_value_set_string (value, ev_annotation_get_modified (annot));
233  break;
234  case PROP_ANNOT_COLOR: {
235  GdkColor color;
236 
237  ev_annotation_get_color (annot, &color);
238  g_value_set_pointer (value, &color);
239  break;
240  }
241  case PROP_ANNOT_RGBA:
242  g_value_set_boxed (value, &annot->rgba);
243  break;
244  case PROP_ANNOT_AREA:
245  g_value_set_boxed (value, &annot->area);
246  break;
247  default:
248  G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
249  }
250 }
251 
252 static void
254 {
255  GObjectClass *g_object_class = G_OBJECT_CLASS (klass);
256 
257  g_object_class->finalize = ev_annotation_finalize;
258  g_object_class->set_property = ev_annotation_set_property;
259  g_object_class->get_property = ev_annotation_get_property;
260 
261  g_object_class_install_property (g_object_class,
263  g_param_spec_object ("page",
264  "Page",
265  "The page wehere the annotation is",
266  EV_TYPE_PAGE,
267  G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY |
268  G_PARAM_STATIC_STRINGS));
269  g_object_class_install_property (g_object_class,
271  g_param_spec_string ("contents",
272  "Contents",
273  "The annotation contents",
274  NULL,
275  G_PARAM_READWRITE |
276  G_PARAM_STATIC_STRINGS));
277  g_object_class_install_property (g_object_class,
279  g_param_spec_string ("name",
280  "Name",
281  "The annotation unique name",
282  NULL,
283  G_PARAM_READWRITE |
284  G_PARAM_STATIC_STRINGS));
285  g_object_class_install_property (g_object_class,
287  g_param_spec_string ("modified",
288  "Modified",
289  "Last modified date as string",
290  NULL,
291  G_PARAM_READWRITE |
292  G_PARAM_STATIC_STRINGS));
300  g_object_class_install_property (g_object_class,
302  g_param_spec_pointer ("color",
303  "Color",
304  "The annotation color",
305  G_PARAM_READWRITE |
306  G_PARAM_STATIC_STRINGS));
307 
315  g_object_class_install_property (g_object_class,
317  g_param_spec_boxed ("rgba", NULL, NULL,
318  GDK_TYPE_RGBA,
319  G_PARAM_READWRITE |
320  G_PARAM_STATIC_STRINGS));
321 
329  g_object_class_install_property (g_object_class,
331  g_param_spec_boxed ("area",
332  "Area",
333  "The area of the page where the annotation is placed",
335  G_PARAM_READWRITE |
336  G_PARAM_STATIC_STRINGS));
337 }
338 
341 {
342  g_return_val_if_fail (EV_IS_ANNOTATION (annot), 0);
343 
344  return annot->type;
345 }
346 
355 EvPage *
357 {
358  g_return_val_if_fail (EV_IS_ANNOTATION (annot), NULL);
359 
360  return annot->page;
361 }
362 
372 guint
374 {
375  g_return_val_if_fail (EV_IS_ANNOTATION (annot), 0);
376 
377  return annot->page->index;
378 }
379 
389 gboolean
391  EvAnnotation *other)
392 {
393  g_return_val_if_fail (EV_IS_ANNOTATION (annot), FALSE);
394  g_return_val_if_fail (EV_IS_ANNOTATION (other), FALSE);
395 
396  return (annot == other || g_strcmp0 (annot->name, other->name) == 0);
397 }
398 
410 const gchar *
412 {
413  g_return_val_if_fail (EV_IS_ANNOTATION (annot), NULL);
414 
415  return annot->contents;
416 }
417 
428 gboolean
430  const gchar *contents)
431 {
432  g_return_val_if_fail (EV_IS_ANNOTATION (annot), FALSE);
433 
434  if (g_strcmp0 (annot->contents, contents) == 0)
435  return FALSE;
436 
437  if (annot->contents)
438  g_free (annot->contents);
439  annot->contents = contents ? g_strdup (contents) : NULL;
440 
441  g_object_notify (G_OBJECT (annot), "contents");
442 
443  return TRUE;
444 }
445 
456 const gchar *
458 {
459  g_return_val_if_fail (EV_IS_ANNOTATION (annot), NULL);
460 
461  return annot->name;
462 }
463 
474 gboolean
476  const gchar *name)
477 {
478  g_return_val_if_fail (EV_IS_ANNOTATION (annot), FALSE);
479 
480  if (g_strcmp0 (annot->name, name) == 0)
481  return FALSE;
482 
483  if (annot->name)
484  g_free (annot->name);
485  annot->name = name ? g_strdup (name) : NULL;
486 
487  g_object_notify (G_OBJECT (annot), "name");
488 
489  return TRUE;
490 }
491 
500 const gchar *
502 {
503  g_return_val_if_fail (EV_IS_ANNOTATION (annot), NULL);
504 
505  return annot->modified;
506 }
507 
521 gboolean
523  const gchar *modified)
524 {
525  g_return_val_if_fail (EV_IS_ANNOTATION (annot), FALSE);
526 
527  if (g_strcmp0 (annot->modified, modified) == 0)
528  return FALSE;
529 
530  if (annot->modified)
531  g_free (annot->modified);
532  annot->modified = modified ? g_strdup (modified) : NULL;
533 
534  g_object_notify (G_OBJECT (annot), "modified");
535 
536  return TRUE;
537 }
538 
551 gboolean
553  GTime utime)
554 {
555  gchar *modified;
556 
557  g_return_val_if_fail (EV_IS_ANNOTATION (annot), FALSE);
558 
559  modified = ev_document_misc_format_date (utime);
560 
561  if (g_strcmp0 (annot->modified, modified) == 0) {
562  g_free (modified);
563  return FALSE;
564  }
565 
566  if (annot->modified)
567  g_free (annot->modified);
568  annot->modified = modified;
569 
570  g_object_notify (G_OBJECT (annot), "modified");
571 
572  return TRUE;
573 }
574 
584 void
586  GdkColor *color)
587 {
588  GdkRGBA rgba;
589 
590  g_return_if_fail (EV_IS_ANNOTATION (annot));
591  g_return_if_fail (color != NULL);
592 
593  ev_annotation_get_rgba (annot, &rgba);
594 
595  color->pixel = 0;
596  color->red = CLAMP (rgba.red * 65535. + 0.5, 0, 65535);
597  color->green = CLAMP (rgba.green * 65535. + 0.5, 0, 65535);
598  color->blue = CLAMP (rgba.blue * 65535. + 0.5, 0, 65535);
599 }
600 
614 gboolean
616  const GdkColor *color)
617 {
618  GdkColor annot_color;
619  GdkRGBA rgba;
620 
621  g_return_val_if_fail (EV_IS_ANNOTATION (annot), FALSE);
622 
623  ev_annotation_get_color (annot, &annot_color);
624  if (color == NULL || gdk_color_equal (color, &annot_color))
625  return FALSE;
626 
627  rgba.red = color->red / 65535.;
628  rgba.green = color->green / 65535.;
629  rgba.blue = color->blue / 65535.;
630  rgba.alpha = 1.;
631 
632  ev_annotation_set_rgba (annot, &rgba);
633 
634  return TRUE;
635 }
636 
646 void
648  GdkRGBA *rgba)
649 {
650  g_return_if_fail (EV_IS_ANNOTATION (annot));
651  g_return_if_fail (rgba != NULL);
652 
653  *rgba = annot->rgba;
654 }
655 
667 gboolean
669  const GdkRGBA *rgba)
670 {
671  g_return_val_if_fail (EV_IS_ANNOTATION (annot), FALSE);
672  g_return_val_if_fail (rgba != NULL, FALSE);
673 
674  if (gdk_rgba_equal (rgba, &annot->rgba))
675  return FALSE;
676 
677  annot->rgba = *rgba;
678  g_object_notify (G_OBJECT (annot), "rgba");
679  g_object_notify (G_OBJECT (annot), "color");
680 
681  return TRUE;
682 }
683 
693 void
695  EvRectangle *area)
696 {
697  g_return_if_fail (EV_IS_ANNOTATION (annot));
698  g_return_if_fail (area != NULL);
699 
700  *area = annot->area;
701 }
702 
714 gboolean
716  const EvRectangle *area)
717 {
718  gboolean was_initial;
719 
720  g_return_val_if_fail (EV_IS_ANNOTATION (annot), FALSE);
721  g_return_val_if_fail (area != NULL, FALSE);
722 
723  if (ev_rect_cmp ((EvRectangle *)area, &annot->area) == 0)
724  return FALSE;
725 
726  was_initial = annot->area.x1 == -1 && annot->area.x2 == -1
727  && annot->area.y1 == -1 && annot->area.y2 == -1;
728  annot->area = *area;
729  if (!was_initial)
730  g_object_notify (G_OBJECT (annot), "area");
731 
732  return TRUE;
733 }
734 
735 /* EvAnnotationMarkup */
736 typedef struct {
737  gchar *label;
738  gdouble opacity;
739  gboolean can_have_popup;
740  gboolean has_popup;
741  gboolean popup_is_open;
744 
745 static void
747 {
748  static gboolean initialized = FALSE;
749 
750  if (!initialized) {
751  g_object_interface_install_property (iface,
752  g_param_spec_string ("label",
753  "Label",
754  "Label of the markup annotation",
755  NULL,
756  G_PARAM_READWRITE |
757  G_PARAM_STATIC_STRINGS));
758  g_object_interface_install_property (iface,
759  g_param_spec_double ("opacity",
760  "Opacity",
761  "Opacity of the markup annotation",
762  0,
763  G_MAXDOUBLE,
764  1.,
765  G_PARAM_READWRITE |
766  G_PARAM_STATIC_STRINGS));
767  g_object_interface_install_property (iface,
768  g_param_spec_boolean ("can-have-popup",
769  "Can have popup",
770  "Whether it is allowed to have a popup "
771  "window for this type of markup annotation",
772  FALSE,
773  G_PARAM_READWRITE |
774  G_PARAM_STATIC_STRINGS));
775  g_object_interface_install_property (iface,
776  g_param_spec_boolean ("has-popup",
777  "Has popup",
778  "Whether the markup annotation has "
779  "a popup window associated",
780  TRUE,
781  G_PARAM_READWRITE |
782  G_PARAM_STATIC_STRINGS));
783  g_object_interface_install_property (iface,
784  g_param_spec_boxed ("rectangle",
785  "Rectangle",
786  "The Rectangle of the popup associated "
787  "to the markup annotation",
789  G_PARAM_READWRITE |
790  G_PARAM_STATIC_STRINGS));
791  g_object_interface_install_property (iface,
792  g_param_spec_boolean ("popup-is-open",
793  "PopupIsOpen",
794  "Whether the popup associated to "
795  "the markup annotation is open",
796  FALSE,
797  G_PARAM_READWRITE |
798  G_PARAM_STATIC_STRINGS));
799  initialized = TRUE;
800  }
801 }
802 
803 static void
805 {
806  g_free (props->label);
807  g_slice_free (EvAnnotationMarkupProps, props);
808 }
809 
812 {
814  static GQuark props_key = 0;
815 
816  if (!props_key)
817  props_key = g_quark_from_static_string ("ev-annotation-markup-props");
818 
819  props = g_object_get_qdata (G_OBJECT (markup), props_key);
820  if (!props) {
821  props = g_slice_new0 (EvAnnotationMarkupProps);
822  g_object_set_qdata_full (G_OBJECT (markup),
823  props_key, props,
824  (GDestroyNotify) ev_annotation_markup_props_free);
825  }
826 
827  return props;
828 }
829 
830 static void
832  guint prop_id,
833  const GValue *value,
834  GParamSpec *pspec)
835 {
836  EvAnnotationMarkup *markup = EV_ANNOTATION_MARKUP (object);
837 
838  switch (prop_id) {
839  case PROP_MARKUP_LABEL:
840  ev_annotation_markup_set_label (markup, g_value_get_string (value));
841  break;
842  case PROP_MARKUP_OPACITY:
843  ev_annotation_markup_set_opacity (markup, g_value_get_double (value));
844  break;
847 
848  props = ev_annotation_markup_get_properties (markup);
849  props->can_have_popup = g_value_get_boolean (value);
850  break;
851  }
853  ev_annotation_markup_set_has_popup (markup, g_value_get_boolean (value));
854  break;
856  ev_annotation_markup_set_rectangle (markup, g_value_get_boxed (value));
857  break;
859  ev_annotation_markup_set_popup_is_open (markup, g_value_get_boolean (value));
860  break;
861  default:
862  G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
863  }
864 }
865 
866 static void
868  guint prop_id,
869  GValue *value,
870  GParamSpec *pspec)
871 {
873 
875 
876  switch (prop_id) {
877  case PROP_MARKUP_LABEL:
878  g_value_set_string (value, props->label);
879  break;
880  case PROP_MARKUP_OPACITY:
881  g_value_set_double (value, props->opacity);
882  break;
884  g_value_set_boolean (value, props->can_have_popup);
885  break;
887  g_value_set_boolean (value, props->has_popup);
888  break;
890  g_value_set_boxed (value, &props->rectangle);
891  break;
893  g_value_set_boolean (value, props->popup_is_open);
894  break;
895  default:
896  G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
897  }
898 }
899 
900 static void
902 {
903  klass->set_property = ev_annotation_markup_set_property;
904  klass->get_property = ev_annotation_markup_get_property;
905 
906  g_object_class_override_property (klass, PROP_MARKUP_LABEL, "label");
907  g_object_class_override_property (klass, PROP_MARKUP_OPACITY, "opacity");
908  g_object_class_override_property (klass, PROP_MARKUP_CAN_HAVE_POPUP, "can-have-popup");
909  g_object_class_override_property (klass, PROP_MARKUP_HAS_POPUP, "has-popup");
910  g_object_class_override_property (klass, PROP_MARKUP_RECTANGLE, "rectangle");
911  g_object_class_override_property (klass, PROP_MARKUP_POPUP_IS_OPEN, "popup-is-open");
912 }
913 
914 const gchar *
916 {
918 
919  g_return_val_if_fail (EV_IS_ANNOTATION_MARKUP (markup), NULL);
920 
921  props = ev_annotation_markup_get_properties (markup);
922  return props->label;
923 }
924 
925 gboolean
927  const gchar *label)
928 {
930 
931  g_return_val_if_fail (EV_IS_ANNOTATION_MARKUP (markup), FALSE);
932  g_return_val_if_fail (label != NULL, FALSE);
933 
934  props = ev_annotation_markup_get_properties (markup);
935  if (g_strcmp0 (props->label, label) == 0)
936  return FALSE;
937 
938  if (props->label)
939  g_free (props->label);
940  props->label = g_strdup (label);
941 
942  g_object_notify (G_OBJECT (markup), "label");
943 
944  return TRUE;
945 }
946 
947 gdouble
949 {
951 
952  g_return_val_if_fail (EV_IS_ANNOTATION_MARKUP (markup), 1.0);
953 
954  props = ev_annotation_markup_get_properties (markup);
955  return props->opacity;
956 }
957 
958 gboolean
960  gdouble opacity)
961 {
963 
964  g_return_val_if_fail (EV_IS_ANNOTATION_MARKUP (markup), FALSE);
965 
966  props = ev_annotation_markup_get_properties (markup);
967  if (props->opacity == opacity)
968  return FALSE;
969 
970  props->opacity = opacity;
971 
972  g_object_notify (G_OBJECT (markup), "opacity");
973 
974  return TRUE;
975 }
976 
977 gboolean
979 {
981 
982  g_return_val_if_fail (EV_IS_ANNOTATION_MARKUP (markup), FALSE);
983 
984  props = ev_annotation_markup_get_properties (markup);
985  return props->can_have_popup;
986 }
987 
988 gboolean
990 {
992 
993  g_return_val_if_fail (EV_IS_ANNOTATION_MARKUP (markup), FALSE);
994 
995  props = ev_annotation_markup_get_properties (markup);
996  return props->has_popup;
997 }
998 
999 gboolean
1001  gboolean has_popup)
1002 {
1003  EvAnnotationMarkupProps *props;
1004 
1005  g_return_val_if_fail (EV_IS_ANNOTATION_MARKUP (markup), FALSE);
1006 
1007  props = ev_annotation_markup_get_properties (markup);
1008  if (props->has_popup == has_popup)
1009  return FALSE;
1010 
1011  props->has_popup = has_popup;
1012 
1013  g_object_notify (G_OBJECT (markup), "has-popup");
1014 
1015  return TRUE;
1016 }
1017 
1018 void
1020  EvRectangle *ev_rect)
1021 {
1022  EvAnnotationMarkupProps *props;
1023 
1024  g_return_if_fail (EV_IS_ANNOTATION_MARKUP (markup));
1025  g_return_if_fail (ev_rect != NULL);
1026 
1027  props = ev_annotation_markup_get_properties (markup);
1028  *ev_rect = props->rectangle;
1029 }
1030 
1031 gboolean
1033  const EvRectangle *ev_rect)
1034 {
1035  EvAnnotationMarkupProps *props;
1036 
1037  g_return_val_if_fail (EV_IS_ANNOTATION_MARKUP (markup), FALSE);
1038  g_return_val_if_fail (ev_rect != NULL, FALSE);
1039 
1040  props = ev_annotation_markup_get_properties (markup);
1041  if (props->rectangle.x1 == ev_rect->x1 &&
1042  props->rectangle.y1 == ev_rect->y1 &&
1043  props->rectangle.x2 == ev_rect->x2 &&
1044  props->rectangle.y2 == ev_rect->y2)
1045  return FALSE;
1046 
1047  props->rectangle = *ev_rect;
1048 
1049  g_object_notify (G_OBJECT (markup), "rectangle");
1050 
1051  return TRUE;
1052 }
1053 
1054 gboolean
1056 {
1057  EvAnnotationMarkupProps *props;
1058 
1059  g_return_val_if_fail (EV_IS_ANNOTATION_MARKUP (markup), FALSE);
1060 
1061  props = ev_annotation_markup_get_properties (markup);
1062  return props->popup_is_open;
1063 }
1064 
1065 gboolean
1067  gboolean is_open)
1068 {
1069  EvAnnotationMarkupProps *props;
1070 
1071  g_return_val_if_fail (EV_IS_ANNOTATION_MARKUP (markup), FALSE);
1072 
1073  props = ev_annotation_markup_get_properties (markup);
1074  if (props->popup_is_open == is_open)
1075  return FALSE;
1076 
1077  props->popup_is_open = is_open;
1078 
1079  g_object_notify (G_OBJECT (markup), "popup_is_open");
1080 
1081  return TRUE;
1082 }
1083 
1084 /* EvAnnotationText */
1085 static void
1087 {
1088  EV_ANNOTATION (annot)->type = EV_ANNOTATION_TYPE_TEXT;
1089 }
1090 
1091 static void
1093  guint prop_id,
1094  const GValue *value,
1095  GParamSpec *pspec)
1096 {
1097  EvAnnotationText *annot = EV_ANNOTATION_TEXT (object);
1098 
1099  if (prop_id < PROP_ATTACHMENT_ATTACHMENT) {
1100  ev_annotation_markup_set_property (object, prop_id, value, pspec);
1101  return;
1102  }
1103 
1104  switch (prop_id) {
1105  case PROP_TEXT_ICON:
1106  ev_annotation_text_set_icon (annot, g_value_get_enum (value));
1107  break;
1108  case PROP_TEXT_IS_OPEN:
1109  ev_annotation_text_set_is_open (annot, g_value_get_boolean (value));
1110  break;
1111  default:
1112  G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1113  }
1114 }
1115 
1116 static void
1118  guint prop_id,
1119  GValue *value,
1120  GParamSpec *pspec)
1121 {
1122  EvAnnotationText *annot = EV_ANNOTATION_TEXT (object);
1123 
1124  if (prop_id < PROP_ATTACHMENT_ATTACHMENT) {
1125  ev_annotation_markup_get_property (object, prop_id, value, pspec);
1126  return;
1127  }
1128 
1129  switch (prop_id) {
1130  case PROP_TEXT_ICON:
1131  g_value_set_enum (value, annot->icon);
1132  break;
1133  case PROP_TEXT_IS_OPEN:
1134  g_value_set_boolean (value, annot->is_open);
1135  break;
1136  default:
1137  G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1138  }
1139 }
1140 
1141 static void
1143 {
1144  GObjectClass *g_object_class = G_OBJECT_CLASS (klass);
1145 
1147 
1148  g_object_class->set_property = ev_annotation_text_set_property;
1149  g_object_class->get_property = ev_annotation_text_get_property;
1150 
1151  g_object_class_install_property (g_object_class,
1153  g_param_spec_enum ("icon",
1154  "Icon",
1155  "The icon fo the text annotation",
1156  EV_TYPE_ANNOTATION_TEXT_ICON,
1158  G_PARAM_READWRITE |
1159  G_PARAM_STATIC_STRINGS));
1160  g_object_class_install_property (g_object_class,
1162  g_param_spec_boolean ("is-open",
1163  "IsOpen",
1164  "Whether text annot is initially open",
1165  FALSE,
1166  G_PARAM_READWRITE |
1167  G_PARAM_STATIC_STRINGS));
1168 }
1169 
1170 static void
1172 {
1173 }
1174 
1175 EvAnnotation *
1177 {
1178  return EV_ANNOTATION (g_object_new (EV_TYPE_ANNOTATION_TEXT,
1179  "page", page,
1180  NULL));
1181 }
1182 
1185 {
1186  g_return_val_if_fail (EV_IS_ANNOTATION_TEXT (text), 0);
1187 
1188  return text->icon;
1189 }
1190 
1191 gboolean
1193  EvAnnotationTextIcon icon)
1194 {
1195  g_return_val_if_fail (EV_IS_ANNOTATION_TEXT (text), FALSE);
1196 
1197  if (text->icon == icon)
1198  return FALSE;
1199 
1200  text->icon = icon;
1201 
1202  g_object_notify (G_OBJECT (text), "icon");
1203 
1204  return TRUE;
1205 }
1206 
1207 gboolean
1209 {
1210  g_return_val_if_fail (EV_IS_ANNOTATION_TEXT (text), FALSE);
1211 
1212  return text->is_open;
1213 }
1214 
1215 gboolean
1217  gboolean is_open)
1218 {
1219  g_return_val_if_fail (EV_IS_ANNOTATION_TEXT (text), FALSE);
1220 
1221  if (text->is_open == is_open)
1222  return FALSE;
1223 
1224  text->is_open = is_open;
1225 
1226  g_object_notify (G_OBJECT (text), "is_open");
1227 
1228  return TRUE;
1229 }
1230 
1231 /* EvAnnotationAttachment */
1232 static void
1234 {
1236 
1237  if (annot->attachment) {
1238  g_object_unref (annot->attachment);
1239  annot->attachment = NULL;
1240  }
1241 
1242  G_OBJECT_CLASS (ev_annotation_attachment_parent_class)->finalize (object);
1243 }
1244 
1245 static void
1247 {
1249 }
1250 
1251 static void
1253  guint prop_id,
1254  const GValue *value,
1255  GParamSpec *pspec)
1256 {
1258 
1259  if (prop_id < PROP_ATTACHMENT_ATTACHMENT) {
1260  ev_annotation_markup_set_property (object, prop_id, value, pspec);
1261  return;
1262  }
1263 
1264  switch (prop_id) {
1266  ev_annotation_attachment_set_attachment (annot, g_value_get_object (value));
1267  break;
1268  default:
1269  G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1270  }
1271 }
1272 
1273 static void
1275  guint prop_id,
1276  GValue *value,
1277  GParamSpec *pspec)
1278 {
1280 
1281  if (prop_id < PROP_ATTACHMENT_ATTACHMENT) {
1282  ev_annotation_markup_get_property (object, prop_id, value, pspec);
1283  return;
1284  }
1285 
1286  switch (prop_id) {
1288  g_value_set_object (value, annot->attachment);
1289  break;
1290  default:
1291  G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1292  }
1293 }
1294 
1295 static void
1297 {
1298  GObjectClass *g_object_class = G_OBJECT_CLASS (klass);
1299 
1301 
1302  g_object_class->set_property = ev_annotation_attachment_set_property;
1303  g_object_class->get_property = ev_annotation_attachment_get_property;
1304  g_object_class->finalize = ev_annotation_attachment_finalize;
1305 
1306  g_object_class_install_property (g_object_class,
1308  g_param_spec_object ("attachment",
1309  "Attachment",
1310  "The attachment of the annotation",
1312  G_PARAM_CONSTRUCT |
1313  G_PARAM_READWRITE |
1314  G_PARAM_STATIC_STRINGS));
1315 }
1316 
1317 static void
1319 {
1320 }
1321 
1322 EvAnnotation *
1324  EvAttachment *attachment)
1325 {
1326  g_return_val_if_fail (EV_IS_ATTACHMENT (attachment), NULL);
1327 
1328  return EV_ANNOTATION (g_object_new (EV_TYPE_ANNOTATION_ATTACHMENT,
1329  "page", page,
1330  "attachment", attachment,
1331  NULL));
1332 }
1333 
1340 EvAttachment *
1342 {
1343  g_return_val_if_fail (EV_IS_ANNOTATION_ATTACHMENT (annot), NULL);
1344 
1345  return annot->attachment;
1346 }
1347 
1348 gboolean
1350  EvAttachment *attachment)
1351 {
1352  g_return_val_if_fail (EV_IS_ANNOTATION_ATTACHMENT (annot), FALSE);
1353 
1354  if (annot->attachment == attachment)
1355  return FALSE;
1356 
1357  if (annot->attachment)
1358  g_object_unref (annot->attachment);
1359  annot->attachment = attachment ? g_object_ref (attachment) : NULL;
1360 
1361  g_object_notify (G_OBJECT (annot), "attachment");
1362 
1363  return TRUE;
1364 }
1365 
1366 /* EvAnnotationTextMarkup */
1367 static void
1369  guint prop_id,
1370  GValue *value,
1371  GParamSpec *pspec)
1372 {
1374 
1375  if (prop_id < PROP_TEXT_MARKUP_TYPE) {
1376  ev_annotation_markup_get_property (object, prop_id, value, pspec);
1377  return;
1378  }
1379 
1380  switch (prop_id) {
1381  case PROP_TEXT_MARKUP_TYPE:
1382  g_value_set_enum (value, annot->type);
1383  break;
1384  default:
1385  G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1386  }
1387 }
1388 
1389 static void
1391  guint prop_id,
1392  const GValue *value,
1393  GParamSpec *pspec)
1394 {
1396 
1397  if (prop_id < PROP_TEXT_MARKUP_TYPE) {
1398  ev_annotation_markup_set_property (object, prop_id, value, pspec);
1399  return;
1400  }
1401 
1402  switch (prop_id) {
1403  case PROP_TEXT_MARKUP_TYPE:
1404  annot->type = g_value_get_enum (value);
1405  break;
1406  default:
1407  G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
1408  }
1409 }
1410 
1411 static void
1413 {
1415 }
1416 
1417 static void
1419 {
1420  GObjectClass *g_object_class = G_OBJECT_CLASS (class);
1421 
1423 
1424  g_object_class->get_property = ev_annotation_text_markup_get_property;
1425  g_object_class->set_property = ev_annotation_text_markup_set_property;
1426 
1427  g_object_class_install_property (g_object_class,
1429  g_param_spec_enum ("type",
1430  "Type",
1431  "The text markup annotation type",
1432  EV_TYPE_ANNOTATION_TEXT_MARKUP_TYPE,
1434  G_PARAM_READWRITE |
1435  G_PARAM_CONSTRUCT |
1436  G_PARAM_STATIC_STRINGS));
1437 }
1438 
1439 static void
1441 {
1442 }
1443 
1444 EvAnnotation *
1446 {
1448  "page", page,
1450  NULL));
1451  return annot;
1452 }
1453 
1454 EvAnnotation *
1456 {
1458  "page", page,
1460  NULL));
1461  return annot;
1462 }
1463 
1464 EvAnnotation *
1466 {
1468  "page", page,
1470  NULL));
1471  return annot;
1472 }
1473 
1474 EvAnnotation *
1476 {
1478  "page", page,
1480  NULL));
1481  return annot;
1482 }
1483 
1486 {
1487  g_return_val_if_fail (EV_IS_ANNOTATION_TEXT_MARKUP (annot), EV_ANNOTATION_TEXT_MARKUP_HIGHLIGHT);
1488 
1489  return annot->type;
1490 }
1491 
1492 gboolean
1494  EvAnnotationTextMarkupType markup_type)
1495 {
1496  g_return_val_if_fail (EV_IS_ANNOTATION_TEXT_MARKUP (annot), FALSE);
1497 
1498  if (annot->type == markup_type)
1499  return FALSE;
1500 
1501  annot->type = markup_type;
1502  g_object_notify (G_OBJECT (annot), "type");
1503 
1504  return TRUE;
1505 }