]> www.fi.muni.cz Git - evince.git/blob - backend/ev-link.c
Fix some bugs with xyz links, respect zoom
[evince.git] / backend / ev-link.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; c-indent-level: 8 -*- */
2 /* this file is part of evince, a gnome document viewer
3  *
4  *  Copyright (C) 2005 Red Hat, Inc.
5  *
6  * Evince is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * Evince is distributed in the hope that it will be useful, but
12  * WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
19  */
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #include "ev-link.h"
26
27 enum {
28         PROP_0,
29         PROP_TITLE,
30         PROP_TYPE,
31         PROP_PAGE,
32         PROP_URI,
33         PROP_LEFT,
34         PROP_TOP,
35         PROP_ZOOM
36 };
37
38
39 struct _EvLink {
40         GObject base_instance;
41         EvLinkPrivate *priv;
42 };
43
44 struct _EvLinkClass {
45         GObjectClass base_class;
46 };
47
48 struct _EvLinkPrivate {
49         char *title;
50         char *uri;
51         EvLinkType type;
52         int page;
53         double top;
54         double left;
55         double zoom;
56 };
57
58 G_DEFINE_TYPE (EvLink, ev_link, G_TYPE_OBJECT)
59
60 #define EV_LINK_GET_PRIVATE(object) \
61         (G_TYPE_INSTANCE_GET_PRIVATE ((object), EV_TYPE_LINK, EvLinkPrivate))
62
63 GType
64 ev_link_type_get_type (void)
65 {
66         static GType type = 0;
67
68         if (G_UNLIKELY (type == 0)) {
69                 static const GEnumValue values[] = {
70                         { EV_LINK_TYPE_TITLE, "EV_LINK_TYPE_TITLE", "title" },
71                         { EV_LINK_TYPE_PAGE, "EV_LINK_TYPE_PAGE", "page" },
72                         { EV_LINK_TYPE_PAGE_XYZ, "EV_LINK_TYPE_PAGE_XYZ", "page-xyz" },
73                         { EV_LINK_TYPE_EXTERNAL_URI, "EV_LINK_TYPE_EXTERNAL_URI", "external" },
74                         { 0, NULL, NULL }
75                 };
76
77                 type = g_enum_register_static ("EvLinkType", values);
78         }
79
80         return type;
81 }
82
83 const char *
84 ev_link_get_title (EvLink *self)
85 {
86         g_return_val_if_fail (EV_IS_LINK (self), NULL);
87         
88         return self->priv->title;
89 }
90
91 const char *
92 ev_link_get_uri (EvLink *self)
93 {
94         g_return_val_if_fail (EV_IS_LINK (self), NULL);
95         
96         return self->priv->uri;
97 }
98
99 EvLinkType
100 ev_link_get_link_type (EvLink *self)
101 {
102         g_return_val_if_fail (EV_IS_LINK (self), 0);
103         
104         return self->priv->type;
105 }
106
107 int
108 ev_link_get_page (EvLink *self)
109 {
110         g_return_val_if_fail (EV_IS_LINK (self), 0);
111         
112         return self->priv->page;
113 }
114
115 double
116 ev_link_get_top (EvLink *self)
117 {
118         g_return_val_if_fail (EV_IS_LINK (self), 0);
119         
120         return self->priv->top;
121 }
122
123 double
124 ev_link_get_left (EvLink *self)
125 {
126         g_return_val_if_fail (EV_IS_LINK (self), 0);
127         
128         return self->priv->left;
129 }
130
131 double
132 ev_link_get_zoom (EvLink *self)
133 {
134         g_return_val_if_fail (EV_IS_LINK (self), 0);
135         
136         return self->priv->zoom;
137 }
138
139 static void
140 ev_link_get_property (GObject *object, guint prop_id, GValue *value,
141                       GParamSpec *param_spec)
142 {
143         EvLink *self;
144
145         self = EV_LINK (object);
146
147         switch (prop_id) {
148         case PROP_TITLE:
149                 g_value_set_string (value, self->priv->title);
150                 break;
151         case PROP_URI:
152                 g_value_set_string (value, self->priv->uri);
153                 break;
154         case PROP_TYPE:
155                 g_value_set_enum (value, self->priv->type);
156                 break;
157         case PROP_PAGE:
158                 g_value_set_int (value, self->priv->page);
159                 break;
160         case PROP_TOP:
161                 g_value_set_double (value, self->priv->top);
162                 break;
163         case PROP_LEFT:
164                 g_value_set_double (value, self->priv->left);
165                 break;
166         case PROP_ZOOM:
167                 g_value_set_double (value, self->priv->zoom);
168                 break;
169         default:
170                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object,
171                                                    prop_id,
172                                                    param_spec);
173                 break;
174         }
175 }
176
177 static void
178 ev_link_set_property (GObject *object, guint prop_id, const GValue *value,
179                       GParamSpec *param_spec)
180 {
181         EvLink *link = EV_LINK (object);
182         
183         switch (prop_id) {
184         case PROP_TITLE:
185                 link->priv->title = g_strdup (g_value_get_string (value));      
186                 break;
187         case PROP_URI:
188                 link->priv->uri = g_strdup (g_value_get_string (value));
189                 break;
190         case PROP_TYPE:
191                 link->priv->type = g_value_get_enum (value);
192                 break;
193         case PROP_PAGE:
194                 link->priv->page = g_value_get_int (value);
195                 break;
196         case PROP_TOP:
197                 link->priv->top = g_value_get_double (value);
198                 break;
199         case PROP_LEFT:
200                 link->priv->left = g_value_get_double (value);
201                 break;
202         case PROP_ZOOM:
203                 link->priv->zoom = g_value_get_double (value);
204                 break;
205
206         default:
207                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object,
208                                                    prop_id,
209                                                    param_spec);
210                 break;
211         }
212 }
213
214 static void
215 ev_window_dispose (GObject *object)
216 {
217         EvLinkPrivate *priv;
218
219         g_return_if_fail (EV_IS_LINK (object));
220
221         priv = EV_LINK (object)->priv;
222
223         if (priv->title) {
224                 g_free (priv->title);
225                 priv->title = NULL;
226         }
227
228         if (priv->uri) {
229                 g_free (priv->uri);
230                 priv->uri = NULL;
231         }
232
233         G_OBJECT_CLASS (ev_link_parent_class)->dispose (object);
234 }
235
236 static void
237 ev_link_init (EvLink *ev_link)
238 {
239         ev_link->priv = EV_LINK_GET_PRIVATE (ev_link);
240
241         ev_link->priv->type = EV_LINK_TYPE_TITLE;
242 }
243
244 static void
245 ev_link_class_init (EvLinkClass *ev_window_class)
246 {
247         GObjectClass *g_object_class;
248
249         g_object_class = G_OBJECT_CLASS (ev_window_class);
250         g_object_class->dispose = ev_window_dispose;
251         g_object_class->set_property = ev_link_set_property;
252         g_object_class->get_property = ev_link_get_property;
253
254         g_type_class_add_private (g_object_class, sizeof (EvLinkPrivate));
255
256         g_object_class_install_property (g_object_class,
257                                          PROP_TITLE,
258                                          g_param_spec_string ("title",
259                                                               "Link Title",
260                                                               "The link title",
261                                                               NULL,
262                                                               G_PARAM_READWRITE |
263                                                               G_PARAM_CONSTRUCT_ONLY));
264         g_object_class_install_property (g_object_class,
265                                          PROP_URI,
266                                          g_param_spec_string ("uri",
267                                                               "Link URI",
268                                                               "The link URI",
269                                                               NULL,
270                                                               G_PARAM_READWRITE |
271                                                               G_PARAM_CONSTRUCT_ONLY));
272         g_object_class_install_property (g_object_class,
273                                          PROP_TYPE,
274                                          g_param_spec_enum  ("type",
275                                                              "Link Type",
276                                                              "The link type",
277                                                              EV_TYPE_LINK_TYPE,
278                                                              EV_LINK_TYPE_TITLE,
279                                                              G_PARAM_READWRITE |
280                                                              G_PARAM_CONSTRUCT_ONLY));
281         g_object_class_install_property (g_object_class,
282                                          PROP_PAGE,
283                                          g_param_spec_int ("page",
284                                                            "Link Page",
285                                                            "The link page",
286                                                             -1,
287                                                             G_MAXINT,
288                                                             0,
289                                                             G_PARAM_READWRITE |
290                                                             G_PARAM_CONSTRUCT_ONLY));
291         g_object_class_install_property (g_object_class,
292                                          PROP_LEFT,
293                                          g_param_spec_double ("left",
294                                                               "Left coordinate",
295                                                               "The left coordinate",
296                                                               0,
297                                                               G_MAXDOUBLE,
298                                                               0,
299                                                               G_PARAM_READWRITE |
300                                                               G_PARAM_CONSTRUCT_ONLY));
301         g_object_class_install_property (g_object_class,
302                                          PROP_TOP,
303                                          g_param_spec_double ("top",
304                                                               "Top coordinate",
305                                                               "The top coordinate",
306                                                               0,
307                                                               G_MAXDOUBLE,
308                                                               0,
309                                                               G_PARAM_READWRITE |
310                                                               G_PARAM_CONSTRUCT_ONLY));
311         g_object_class_install_property (g_object_class,
312                                          PROP_ZOOM,
313                                          g_param_spec_double ("zoom",
314                                                               "Zoom",
315                                                               "Zoom",
316                                                               0,
317                                                               G_MAXDOUBLE,
318                                                               0,
319                                                               G_PARAM_READWRITE |
320                                                               G_PARAM_CONSTRUCT_ONLY));
321 }
322
323 EvLink *
324 ev_link_new_title (const char *title)
325 {
326         return EV_LINK (g_object_new (EV_TYPE_LINK,
327                                       "title", title,
328                                       "type", EV_LINK_TYPE_TITLE,
329                                       NULL));
330 }
331
332 EvLink *
333 ev_link_new_page (const char *title, int page)
334 {
335         return EV_LINK (g_object_new (EV_TYPE_LINK,
336                                       "title", title,
337                                       "page", page,
338                                       "type", EV_LINK_TYPE_PAGE,
339                                       NULL));
340 }
341
342 EvLink *
343 ev_link_new_page_xyz (const char *title,
344                       int         page,
345                       double      left,
346                       double      top,
347                       double      zoom)
348 {
349         return EV_LINK (g_object_new (EV_TYPE_LINK,
350                                       "title", title,
351                                       "page", page,
352                                       "type", EV_LINK_TYPE_PAGE_XYZ,
353                                       "left", left,
354                                       "top", top,
355                                       "zoom", zoom,
356                                       NULL));
357 }
358
359 EvLink *
360 ev_link_new_external (const char *title, const char *uri)
361 {
362         return EV_LINK (g_object_new (EV_TYPE_LINK,
363                                       "title", title,
364                                       "uri", uri,
365                                       "type", EV_LINK_TYPE_EXTERNAL_URI,
366                                       NULL));
367 }
368
369
370
371 static void
372 ev_link_mapping_free_foreach (EvLinkMapping *mapping)
373 {
374         g_object_unref (G_OBJECT (mapping->link));
375         g_free (mapping);
376 }
377
378 void
379 ev_link_mapping_free (GList *link_mapping)
380 {
381         if (link_mapping == NULL)
382                 return;
383
384         g_list_foreach (link_mapping, (GFunc) (ev_link_mapping_free_foreach), NULL);
385         g_list_free (link_mapping);
386 }
387
388
389 EvLink *
390 ev_link_mapping_find (GList   *link_mapping,
391                       gdouble  x,
392                       gdouble  y)
393 {
394         GList *list;
395         EvLink *link = NULL;
396         int i;
397         
398         i = 0;
399
400         for (list = link_mapping; list; list = list->next) {
401                 EvLinkMapping *mapping = list->data;
402
403                 i++;
404                 if ((x >= mapping->x1) &&
405                     (y >= mapping->y1) &&
406                     (x <= mapping->x2) &&
407                     (y <= mapping->y2)) {
408                         link = mapping->link;
409                         break;
410                 }
411         }
412
413         return link;
414 }
415