]> www.fi.muni.cz Git - evince.git/blob - libdocument/ev-annotation.c
b38fd0a912366f0c10b01e96db7c9ff40747b290
[evince.git] / libdocument / ev-annotation.c
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
26
27 static void ev_annotation_markup_iface_base_init       (EvAnnotationMarkupIface *iface);
28 static void ev_annotation_text_markup_iface_init       (EvAnnotationMarkupIface *iface);
29 static void ev_annotation_attachment_markup_iface_init (EvAnnotationMarkupIface *iface);
30
31 enum {
32         PROP_0,
33         PROP_LABEL,
34         PROP_OPACITY,
35         PROP_HAS_POPUP,
36         PROP_RECTANGLE,
37         PROP_IS_OPEN
38 };
39
40 G_DEFINE_ABSTRACT_TYPE (EvAnnotation, ev_annotation, G_TYPE_OBJECT)
41 GType
42 ev_annotation_markup_get_type (void)
43 {
44         static volatile gsize g_define_type_id__volatile = 0;
45
46         if (g_once_init_enter (&g_define_type_id__volatile)) {
47                 GType g_define_type_id;
48                 const GTypeInfo our_info = {
49                         sizeof (EvAnnotationMarkupIface),
50                         (GBaseInitFunc) ev_annotation_markup_iface_base_init,
51                         NULL,
52                 };
53
54                 g_define_type_id = g_type_register_static (G_TYPE_INTERFACE,
55                                                            "EvAnnotationMarkup",
56                                                            &our_info, (GTypeFlags)0);
57                 g_type_interface_add_prerequisite (g_define_type_id, EV_TYPE_ANNOTATION);
58
59                 g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
60         }
61
62         return g_define_type_id__volatile;
63 }
64
65 G_DEFINE_TYPE_WITH_CODE (EvAnnotationText, ev_annotation_text, EV_TYPE_ANNOTATION,
66          {
67                  G_IMPLEMENT_INTERFACE (EV_TYPE_ANNOTATION_MARKUP,
68                                         ev_annotation_text_markup_iface_init);
69          });
70 G_DEFINE_TYPE_WITH_CODE (EvAnnotationAttachment, ev_annotation_attachment, EV_TYPE_ANNOTATION,
71          {
72                  G_IMPLEMENT_INTERFACE (EV_TYPE_ANNOTATION_MARKUP,
73                                         ev_annotation_attachment_markup_iface_init);
74          });
75
76 /* EvAnnotation */
77 static void
78 ev_annotation_finalize (GObject *object)
79 {
80         EvAnnotation *annot = EV_ANNOTATION (object);
81
82         if (annot->page) {
83                 g_object_unref (annot->page);
84                 annot->page = NULL;
85         }
86
87         if (annot->contents) {
88                 g_free (annot->contents);
89                 annot->contents = NULL;
90         }
91
92         if (annot->name) {
93                 g_free (annot->name);
94                 annot->name = NULL;
95         }
96
97         if (annot->modified) {
98                 g_free (annot->modified);
99                 annot->modified = NULL;
100         }
101
102         G_OBJECT_CLASS (ev_annotation_parent_class)->finalize (object);
103 }
104
105 static void
106 ev_annotation_init (EvAnnotation *annot)
107 {
108 }
109
110 static void
111 ev_annotation_class_init (EvAnnotationClass *klass)
112 {
113         GObjectClass *g_object_class = G_OBJECT_CLASS (klass);
114
115         g_object_class->finalize = ev_annotation_finalize;
116 }
117
118 /* EvAnnotationMarkup */
119 typedef struct {
120         gchar   *label;
121         gdouble  opacity;
122         gboolean has_popup;
123         gboolean is_open;
124         EvRectangle *rectangle;
125 } EvAnnotationMarkupProps;
126
127 static void
128 ev_annotation_markup_iface_base_init (EvAnnotationMarkupIface *iface)
129 {
130         static gboolean initialized = FALSE;
131
132         if (!initialized) {
133                 g_object_interface_install_property (iface,
134                                                      g_param_spec_string ("label",
135                                                                           "Label",
136                                                                           "Label of the markup annotation",
137                                                                           NULL,
138                                                                           G_PARAM_READWRITE));
139                 g_object_interface_install_property (iface,
140                                                      g_param_spec_double ("opacity",
141                                                                           "Opacity",
142                                                                           "Opacity of the markup annotation",
143                                                                           0,
144                                                                           G_MAXDOUBLE,
145                                                                           0,
146                                                                           G_PARAM_READWRITE));
147                 g_object_interface_install_property (iface,
148                                                      g_param_spec_boolean ("has_popup",
149                                                                            "Has popup",
150                                                                            "Whether the markup annotation has "
151                                                                            "a popup window associated",
152                                                                            TRUE,
153                                                                            G_PARAM_READWRITE));
154                 g_object_interface_install_property (iface,
155                                                      g_param_spec_boxed ("rectangle",
156                                                                          "Rectangle",
157                                                                          "The Rectangle of the popup associated "
158                                                                          "to the markup annotation",
159                                                                          EV_TYPE_RECTANGLE,
160                                                                          G_PARAM_READWRITE));
161                 g_object_interface_install_property (iface,
162                                                      g_param_spec_boolean ("is_open",
163                                                                            "Is open",
164                                                                            "Whether the popup associated to "
165                                                                            "the markup annotation is open",
166                                                                            FALSE,
167                                                                            G_PARAM_READWRITE));
168                 initialized = TRUE;
169         }
170 }
171
172 static void
173 ev_annotation_markup_props_free (EvAnnotationMarkupProps *props)
174 {
175         g_free (props->label);
176         ev_rectangle_free (props->rectangle);
177         g_slice_free (EvAnnotationMarkupProps, props);
178 }
179
180 static EvAnnotationMarkupProps *
181 ev_annotation_markup_get_properties (EvAnnotationMarkup *markup)
182 {
183         EvAnnotationMarkupProps *props;
184         static GQuark props_key = 0;
185
186         if (!props_key)
187                 props_key = g_quark_from_static_string ("ev-annotation-markup-props");
188
189         props = g_object_get_qdata (G_OBJECT (markup), props_key);
190         if (!props) {
191                 props = g_slice_new0 (EvAnnotationMarkupProps);
192                 g_object_set_qdata_full (G_OBJECT (markup),
193                                          props_key, props,
194                                          (GDestroyNotify) ev_annotation_markup_props_free);
195         }
196
197         return props;
198 }
199
200 static void
201 ev_annotation_markup_set_property (GObject      *object,
202                                    guint         prop_id,
203                                    const GValue *value,
204                                    GParamSpec   *pspec)
205 {
206         EvAnnotationMarkupProps *props;
207
208         props = ev_annotation_markup_get_properties (EV_ANNOTATION_MARKUP (object));
209
210         switch (prop_id) {
211         case PROP_LABEL:
212                 g_free (props->label);
213                 props->label = g_value_dup_string (value);
214                 break;
215         case PROP_OPACITY:
216                 props->opacity = g_value_get_double (value);
217                 break;
218         case PROP_HAS_POPUP:
219                 props->has_popup = g_value_get_boolean (value);
220                 break;
221         case PROP_RECTANGLE:
222                 ev_rectangle_free (props->rectangle);
223                 props->rectangle = g_value_dup_boxed (value);
224                 break;
225         case PROP_IS_OPEN:
226                 props->is_open = g_value_get_boolean (value);
227                 break;
228         default:
229                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
230         }
231 }
232
233 static void
234 ev_annotation_markup_get_property (GObject    *object,
235                                    guint       prop_id,
236                                    GValue     *value,
237                                    GParamSpec *pspec)
238 {
239         EvAnnotationMarkupProps *props;
240
241         props = ev_annotation_markup_get_properties (EV_ANNOTATION_MARKUP (object));
242
243         switch (prop_id) {
244         case PROP_LABEL:
245                 g_value_set_string (value, props->label);
246                 break;
247         case PROP_OPACITY:
248                 g_value_set_double (value, props->opacity);
249                 break;
250         case PROP_HAS_POPUP:
251                 g_value_set_boolean (value, props->has_popup);
252                 break;
253         case PROP_RECTANGLE:
254                 g_value_set_boxed (value, props->rectangle);
255                 break;
256         case PROP_IS_OPEN:
257                 g_value_set_boolean (value, props->is_open);
258                 break;
259         default:
260                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
261         }
262 }
263
264 static void
265 ev_annotation_markup_class_install_properties (GObjectClass *klass)
266 {
267         klass->set_property = ev_annotation_markup_set_property;
268         klass->get_property = ev_annotation_markup_get_property;
269
270         g_object_class_override_property (klass, PROP_LABEL, "label");
271         g_object_class_override_property (klass, PROP_OPACITY, "opacity");
272         g_object_class_override_property (klass, PROP_HAS_POPUP, "has_popup");
273         g_object_class_override_property (klass, PROP_RECTANGLE, "rectangle");
274         g_object_class_override_property (klass, PROP_IS_OPEN, "is_open");
275 }
276
277 gchar *
278 ev_annotation_markup_get_label (EvAnnotationMarkup *markup)
279 {
280         gchar *retval;
281
282         g_return_val_if_fail (EV_IS_ANNOTATION_MARKUP (markup), NULL);
283
284         g_object_get (G_OBJECT (markup), "label", &retval, NULL);
285
286         return retval;
287 }
288
289 void
290 ev_annotation_markup_set_label (EvAnnotationMarkup *markup,
291                                 const gchar        *label)
292 {
293         g_return_if_fail (EV_IS_ANNOTATION_MARKUP (markup));
294         g_return_if_fail (label != NULL);
295
296         g_object_set (G_OBJECT (markup), "label", label, NULL);
297 }
298
299 gdouble
300 ev_annotation_markup_get_opacity (EvAnnotationMarkup *markup)
301 {
302         gdouble retval;
303
304         g_return_val_if_fail (EV_IS_ANNOTATION_MARKUP (markup), 0.0);
305
306         g_object_get (G_OBJECT (markup), "opacity", &retval, NULL);
307
308         return retval;
309 }
310
311 void
312 ev_annotation_markup_set_opacity (EvAnnotationMarkup *markup,
313                                   gdouble             opacity)
314 {
315         g_return_if_fail (EV_IS_ANNOTATION_MARKUP (markup));
316
317         g_object_set (G_OBJECT (markup), "opacity", opacity, NULL);
318 }
319
320 gboolean
321 ev_annotation_markup_has_popup (EvAnnotationMarkup *markup)
322 {
323         gboolean retval;
324
325         g_return_val_if_fail (EV_IS_ANNOTATION_MARKUP (markup), FALSE);
326
327         g_object_get (G_OBJECT (markup), "has_popup", &retval, NULL);
328
329         return retval;
330 }
331
332 void
333 ev_annotation_markup_get_rectangle (EvAnnotationMarkup *markup,
334                                     EvRectangle        *ev_rect)
335 {
336         EvRectangle *r;
337
338         g_return_if_fail (EV_IS_ANNOTATION_MARKUP (markup));
339         g_return_if_fail (ev_rect != NULL);
340
341         g_object_get (G_OBJECT (markup), "rectangle", &r, NULL);
342         *ev_rect = *r;
343 }
344
345 gboolean
346 ev_annotation_markup_get_is_open (EvAnnotationMarkup *markup)
347 {
348         gboolean retval;
349
350         g_return_val_if_fail (EV_IS_ANNOTATION_MARKUP (markup), FALSE);
351
352         g_object_get (G_OBJECT (markup), "is_open", &retval, NULL);
353
354         return retval;
355 }
356
357 void
358 ev_annotation_markup_set_is_open (EvAnnotationMarkup *markup,
359                                   gboolean            is_open)
360 {
361         g_return_if_fail (EV_IS_ANNOTATION_MARKUP (markup));
362
363         g_object_set (G_OBJECT (markup), "is_open", is_open, NULL);
364 }
365
366 /* EvAnnotationText */
367 static void
368 ev_annotation_text_init (EvAnnotationText *annot)
369 {
370 }
371
372 static void
373 ev_annotation_text_class_init (EvAnnotationTextClass *klass)
374 {
375         GObjectClass *g_object_class = G_OBJECT_CLASS (klass);
376
377         ev_annotation_markup_class_install_properties (g_object_class);
378 }
379
380 static void
381 ev_annotation_text_markup_iface_init (EvAnnotationMarkupIface *iface)
382 {
383 }
384
385 EvAnnotation *
386 ev_annotation_text_new (EvPage *page)
387 {
388         EvAnnotation *annot;
389
390         annot = EV_ANNOTATION (g_object_new (EV_TYPE_ANNOTATION_TEXT, NULL));
391         annot->page = g_object_ref (page);
392
393         return annot;
394 }
395
396 /* EvAnnotationAttachment */
397 static void
398 ev_annotation_attachment_finalize (GObject *object)
399 {
400         EvAnnotationAttachment *annot = EV_ANNOTATION_ATTACHMENT (object);
401
402         if (annot->attachment) {
403                 g_object_unref (annot->attachment);
404                 annot->attachment = NULL;
405         }
406
407         G_OBJECT_CLASS (ev_annotation_attachment_parent_class)->finalize (object);
408 }
409
410 static void
411 ev_annotation_attachment_init (EvAnnotationAttachment *annot)
412 {
413 }
414
415 static void
416 ev_annotation_attachment_class_init (EvAnnotationAttachmentClass *klass)
417 {
418         GObjectClass *g_object_class = G_OBJECT_CLASS (klass);
419
420         ev_annotation_markup_class_install_properties (g_object_class);
421
422         g_object_class->finalize = ev_annotation_attachment_finalize;
423 }
424
425 static void
426 ev_annotation_attachment_markup_iface_init (EvAnnotationMarkupIface *iface)
427 {
428 }
429
430 EvAnnotation *
431 ev_annotation_attachment_new (EvPage       *page,
432                               EvAttachment *attachment)
433 {
434         EvAnnotation *annot;
435
436         g_return_val_if_fail (EV_IS_ATTACHMENT (attachment), NULL);
437
438         annot = EV_ANNOTATION (g_object_new (EV_TYPE_ANNOTATION_ATTACHMENT, NULL));
439         annot->page = g_object_ref (page);
440         EV_ANNOTATION_ATTACHMENT (annot)->attachment = g_object_ref (attachment);
441
442         return annot;
443 }