]> www.fi.muni.cz Git - evince.git/blob - backend/ev-link.c
Implement FIT_HEIGHT mode (only for links). Implement FITH links
[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_PAGE_FIT, "EV_LINK_TYPE_PAGE_FIT", "page-fit" },
74                         { EV_LINK_TYPE_PAGE_FITH, "EV_LINK_TYPE_PAGE_FITH", "page-fith" },
75                         { EV_LINK_TYPE_PAGE_FITV, "EV_LINK_TYPE_PAGE_FITV", "page-fitv" },
76                         { EV_LINK_TYPE_EXTERNAL_URI, "EV_LINK_TYPE_EXTERNAL_URI", "external" },
77                         { 0, NULL, NULL }
78                 };
79
80                 type = g_enum_register_static ("EvLinkType", values);
81         }
82
83         return type;
84 }
85
86 const char *
87 ev_link_get_title (EvLink *self)
88 {
89         g_return_val_if_fail (EV_IS_LINK (self), NULL);
90         
91         return self->priv->title;
92 }
93
94 const char *
95 ev_link_get_uri (EvLink *self)
96 {
97         g_return_val_if_fail (EV_IS_LINK (self), NULL);
98         
99         return self->priv->uri;
100 }
101
102 EvLinkType
103 ev_link_get_link_type (EvLink *self)
104 {
105         g_return_val_if_fail (EV_IS_LINK (self), 0);
106         
107         return self->priv->type;
108 }
109
110 int
111 ev_link_get_page (EvLink *self)
112 {
113         g_return_val_if_fail (EV_IS_LINK (self), 0);
114         
115         return self->priv->page;
116 }
117
118 double
119 ev_link_get_top (EvLink *self)
120 {
121         g_return_val_if_fail (EV_IS_LINK (self), 0);
122         
123         return self->priv->top;
124 }
125
126 double
127 ev_link_get_left (EvLink *self)
128 {
129         g_return_val_if_fail (EV_IS_LINK (self), 0);
130         
131         return self->priv->left;
132 }
133
134 double
135 ev_link_get_zoom (EvLink *self)
136 {
137         g_return_val_if_fail (EV_IS_LINK (self), 0);
138         
139         return self->priv->zoom;
140 }
141
142 static void
143 ev_link_get_property (GObject *object, guint prop_id, GValue *value,
144                       GParamSpec *param_spec)
145 {
146         EvLink *self;
147
148         self = EV_LINK (object);
149
150         switch (prop_id) {
151         case PROP_TITLE:
152                 g_value_set_string (value, self->priv->title);
153                 break;
154         case PROP_URI:
155                 g_value_set_string (value, self->priv->uri);
156                 break;
157         case PROP_TYPE:
158                 g_value_set_enum (value, self->priv->type);
159                 break;
160         case PROP_PAGE:
161                 g_value_set_int (value, self->priv->page);
162                 break;
163         case PROP_TOP:
164                 g_value_set_double (value, self->priv->top);
165                 break;
166         case PROP_LEFT:
167                 g_value_set_double (value, self->priv->left);
168                 break;
169         case PROP_ZOOM:
170                 g_value_set_double (value, self->priv->zoom);
171                 break;
172         default:
173                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object,
174                                                    prop_id,
175                                                    param_spec);
176                 break;
177         }
178 }
179
180 static void
181 ev_link_set_property (GObject *object, guint prop_id, const GValue *value,
182                       GParamSpec *param_spec)
183 {
184         EvLink *link = EV_LINK (object);
185         
186         switch (prop_id) {
187         case PROP_TITLE:
188                 link->priv->title = g_strdup (g_value_get_string (value));      
189                 break;
190         case PROP_URI:
191                 link->priv->uri = g_strdup (g_value_get_string (value));
192                 break;
193         case PROP_TYPE:
194                 link->priv->type = g_value_get_enum (value);
195                 break;
196         case PROP_PAGE:
197                 link->priv->page = g_value_get_int (value);
198                 break;
199         case PROP_TOP:
200                 link->priv->top = g_value_get_double (value);
201                 break;
202         case PROP_LEFT:
203                 link->priv->left = g_value_get_double (value);
204                 break;
205         case PROP_ZOOM:
206                 link->priv->zoom = g_value_get_double (value);
207                 break;
208
209         default:
210                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object,
211                                                    prop_id,
212                                                    param_spec);
213                 break;
214         }
215 }
216
217 static void
218 ev_window_dispose (GObject *object)
219 {
220         EvLinkPrivate *priv;
221
222         g_return_if_fail (EV_IS_LINK (object));
223
224         priv = EV_LINK (object)->priv;
225
226         if (priv->title) {
227                 g_free (priv->title);
228                 priv->title = NULL;
229         }
230
231         if (priv->uri) {
232                 g_free (priv->uri);
233                 priv->uri = NULL;
234         }
235
236         G_OBJECT_CLASS (ev_link_parent_class)->dispose (object);
237 }
238
239 static void
240 ev_link_init (EvLink *ev_link)
241 {
242         ev_link->priv = EV_LINK_GET_PRIVATE (ev_link);
243
244         ev_link->priv->type = EV_LINK_TYPE_TITLE;
245 }
246
247 static void
248 ev_link_class_init (EvLinkClass *ev_window_class)
249 {
250         GObjectClass *g_object_class;
251
252         g_object_class = G_OBJECT_CLASS (ev_window_class);
253         g_object_class->dispose = ev_window_dispose;
254         g_object_class->set_property = ev_link_set_property;
255         g_object_class->get_property = ev_link_get_property;
256
257         g_type_class_add_private (g_object_class, sizeof (EvLinkPrivate));
258
259         g_object_class_install_property (g_object_class,
260                                          PROP_TITLE,
261                                          g_param_spec_string ("title",
262                                                               "Link Title",
263                                                               "The link title",
264                                                               NULL,
265                                                               G_PARAM_READWRITE |
266                                                               G_PARAM_CONSTRUCT_ONLY));
267         g_object_class_install_property (g_object_class,
268                                          PROP_URI,
269                                          g_param_spec_string ("uri",
270                                                               "Link URI",
271                                                               "The link URI",
272                                                               NULL,
273                                                               G_PARAM_READWRITE |
274                                                               G_PARAM_CONSTRUCT_ONLY));
275         g_object_class_install_property (g_object_class,
276                                          PROP_TYPE,
277                                          g_param_spec_enum  ("type",
278                                                              "Link Type",
279                                                              "The link type",
280                                                              EV_TYPE_LINK_TYPE,
281                                                              EV_LINK_TYPE_TITLE,
282                                                              G_PARAM_READWRITE |
283                                                              G_PARAM_CONSTRUCT_ONLY));
284         g_object_class_install_property (g_object_class,
285                                          PROP_PAGE,
286                                          g_param_spec_int ("page",
287                                                            "Link Page",
288                                                            "The link page",
289                                                             -1,
290                                                             G_MAXINT,
291                                                             0,
292                                                             G_PARAM_READWRITE |
293                                                             G_PARAM_CONSTRUCT_ONLY));
294         g_object_class_install_property (g_object_class,
295                                          PROP_LEFT,
296                                          g_param_spec_double ("left",
297                                                               "Left coordinate",
298                                                               "The left coordinate",
299                                                               -G_MAXDOUBLE,
300                                                               G_MAXDOUBLE,
301                                                               0,
302                                                               G_PARAM_READWRITE |
303                                                               G_PARAM_CONSTRUCT_ONLY));
304         g_object_class_install_property (g_object_class,
305                                          PROP_TOP,
306                                          g_param_spec_double ("top",
307                                                               "Top coordinate",
308                                                               "The top coordinate",
309                                                               -G_MAXDOUBLE,
310                                                               G_MAXDOUBLE,
311                                                               0,
312                                                               G_PARAM_READWRITE |
313                                                               G_PARAM_CONSTRUCT_ONLY));
314         g_object_class_install_property (g_object_class,
315                                          PROP_ZOOM,
316                                          g_param_spec_double ("zoom",
317                                                               "Zoom",
318                                                               "Zoom",
319                                                               0,
320                                                               G_MAXDOUBLE,
321                                                               0,
322                                                               G_PARAM_READWRITE |
323                                                               G_PARAM_CONSTRUCT_ONLY));
324 }
325
326 EvLink *
327 ev_link_new_title (const char *title)
328 {
329         return EV_LINK (g_object_new (EV_TYPE_LINK,
330                                       "title", title,
331                                       "type", EV_LINK_TYPE_TITLE,
332                                       NULL));
333 }
334
335 EvLink *
336 ev_link_new_page (const char *title, int page)
337 {
338         return EV_LINK (g_object_new (EV_TYPE_LINK,
339                                       "title", title,
340                                       "page", page,
341                                       "type", EV_LINK_TYPE_PAGE,
342                                       NULL));
343 }
344
345 EvLink *
346 ev_link_new_page_xyz (const char *title,
347                       int         page,
348                       double      left,
349                       double      top,
350                       double      zoom)
351 {
352         return EV_LINK (g_object_new (EV_TYPE_LINK,
353                                       "title", title,
354                                       "page", page,
355                                       "type", EV_LINK_TYPE_PAGE_XYZ,
356                                       "left", left,
357                                       "top", top,
358                                       "zoom", zoom,
359                                       NULL));
360 }
361
362 EvLink *
363 ev_link_new_page_fit (const char *title,
364                       int         page)
365 {
366         return EV_LINK (g_object_new (EV_TYPE_LINK,
367                                       "title", title,
368                                       "page", page,
369                                       "type", EV_LINK_TYPE_PAGE_FIT,
370                                       NULL));
371 }
372
373 EvLink *
374 ev_link_new_page_fith (const char *title,
375                        int         page,
376                        double      top)
377 {
378         return EV_LINK (g_object_new (EV_TYPE_LINK,
379                                       "title", title,
380                                       "page", page,
381                                       "type", EV_LINK_TYPE_PAGE_FITH,
382                                       "top", top,
383                                       NULL));
384 }
385
386 EvLink *
387 ev_link_new_page_fitv (const char *title,
388                        int         page,
389                        double      left)
390 {
391         return EV_LINK (g_object_new (EV_TYPE_LINK,
392                                       "title", title,
393                                       "page", page,
394                                       "type", EV_LINK_TYPE_PAGE_FITV,
395                                       "left", left,
396                                       NULL));
397 }
398
399 EvLink *
400 ev_link_new_external (const char *title, const char *uri)
401 {
402         return EV_LINK (g_object_new (EV_TYPE_LINK,
403                                       "title", title,
404                                       "uri", uri,
405                                       "type", EV_LINK_TYPE_EXTERNAL_URI,
406                                       NULL));
407 }
408
409
410
411 static void
412 ev_link_mapping_free_foreach (EvLinkMapping *mapping)
413 {
414         g_object_unref (G_OBJECT (mapping->link));
415         g_free (mapping);
416 }
417
418 void
419 ev_link_mapping_free (GList *link_mapping)
420 {
421         if (link_mapping == NULL)
422                 return;
423
424         g_list_foreach (link_mapping, (GFunc) (ev_link_mapping_free_foreach), NULL);
425         g_list_free (link_mapping);
426 }
427
428
429 EvLink *
430 ev_link_mapping_find (GList   *link_mapping,
431                       gdouble  x,
432                       gdouble  y)
433 {
434         GList *list;
435         EvLink *link = NULL;
436         int i;
437         
438         i = 0;
439
440         for (list = link_mapping; list; list = list->next) {
441                 EvLinkMapping *mapping = list->data;
442
443                 i++;
444                 if ((x >= mapping->x1) &&
445                     (y >= mapping->y1) &&
446                     (x <= mapping->x2) &&
447                     (y <= mapping->y2)) {
448                         link = mapping->link;
449                         break;
450                 }
451         }
452
453         return link;
454 }
455