]> www.fi.muni.cz Git - evince.git/blob - libview/ev-page-cache.c
[libview] Move height_to_page cache from EvPageCache to EvView
[evince.git] / libview / ev-page-cache.c
1 #include <config.h>
2 #include "ev-page-cache.h"
3 #include "ev-document-thumbnails.h"
4 #include "ev-page.h"
5 #include <stdlib.h>
6 #include <string.h>
7
8 struct _EvPageCache
9 {
10         GObject parent;
11
12         EvDocument *document;
13
14         gint current_page;
15
16         gboolean dual_even_left;
17
18         int rotation;
19 };
20
21 struct _EvPageCacheClass
22 {
23         GObjectClass parent_class;
24
25         void (* page_changed) (EvPageCache *page_cache, gint page);
26         void (* history_changed) (EvPageCache *page_cache, gint page);
27 };
28
29 enum
30 {
31         PAGE_CHANGED,
32         HISTORY_CHANGED,
33         N_SIGNALS,
34 };
35
36 static guint signals[N_SIGNALS] = {0, };
37
38 static void ev_page_cache_init       (EvPageCache      *page_cache);
39 static void ev_page_cache_class_init (EvPageCacheClass *page_cache);
40 static void ev_page_cache_finalize   (GObject *object);
41
42 G_DEFINE_TYPE (EvPageCache, ev_page_cache, G_TYPE_OBJECT)
43
44 static void
45 ev_page_cache_init (EvPageCache *page_cache)
46 {
47         page_cache->current_page = -1;
48 }
49
50 static void
51 ev_page_cache_class_init (EvPageCacheClass *class)
52 {
53         GObjectClass *object_class;
54
55         object_class = G_OBJECT_CLASS (class);
56
57         object_class->finalize = ev_page_cache_finalize;
58
59         signals [PAGE_CHANGED] =
60                 g_signal_new ("page-changed",
61                               EV_TYPE_PAGE_CACHE,
62                               G_SIGNAL_RUN_LAST,
63                               G_STRUCT_OFFSET (EvPageCacheClass, page_changed),
64                               NULL, NULL,
65                               g_cclosure_marshal_VOID__INT,
66                               G_TYPE_NONE, 1,
67                               G_TYPE_INT);
68
69         signals [HISTORY_CHANGED] =
70                 g_signal_new ("history-changed",
71                               EV_TYPE_PAGE_CACHE,
72                               G_SIGNAL_RUN_LAST,
73                               G_STRUCT_OFFSET (EvPageCacheClass, history_changed),
74                               NULL, NULL,
75                               g_cclosure_marshal_VOID__INT,
76                               G_TYPE_NONE, 1,
77                               G_TYPE_INT);
78
79 }
80
81 static void
82 ev_page_cache_finalize (GObject *object)
83 {
84         EvPageCache *page_cache = EV_PAGE_CACHE (object);
85
86         page_cache->document = NULL;
87
88         G_OBJECT_CLASS (ev_page_cache_parent_class)->finalize (object);
89 }
90
91 static EvPageCache *
92 ev_page_cache_new (EvDocument *document)
93 {
94         EvPageCache *page_cache;
95
96         page_cache = (EvPageCache *) g_object_new (EV_TYPE_PAGE_CACHE, NULL);
97         page_cache->document = document;
98
99         if (ev_document_get_n_pages (page_cache->document) > 0)
100                 ev_page_cache_set_current_page (page_cache, 0);
101
102         return page_cache;
103 }
104
105 gint
106 ev_page_cache_get_current_page (EvPageCache *page_cache)
107 {
108         g_return_val_if_fail (EV_IS_PAGE_CACHE (page_cache), 0);
109
110         return page_cache->current_page;
111 }
112
113 void
114 ev_page_cache_set_current_page (EvPageCache *page_cache,
115                                 int          page)
116 {
117         g_return_if_fail (EV_IS_PAGE_CACHE (page_cache));
118
119         if (page == page_cache->current_page)
120                 return;
121
122         page_cache->current_page = page;
123         g_signal_emit (page_cache, signals[PAGE_CHANGED], 0, page);
124 }
125
126 void
127 ev_page_cache_set_current_page_history (EvPageCache *page_cache,
128                                         int          page)
129 {
130         if (abs (page - page_cache->current_page) > 1)
131                 g_signal_emit (page_cache, signals [HISTORY_CHANGED], 0, page);
132         
133         ev_page_cache_set_current_page (page_cache, page);
134 }
135
136 gboolean
137 ev_page_cache_set_page_label (EvPageCache *page_cache,
138                               const gchar *page_label)
139 {
140         gint page;
141
142         g_return_val_if_fail (EV_IS_PAGE_CACHE (page_cache), FALSE);
143
144         if (ev_document_find_page_by_label (page_cache->document, page_label, &page)) {
145                 ev_page_cache_set_current_page (page_cache, page);
146                 return TRUE;
147         }
148
149         return FALSE;
150 }
151
152 void
153 ev_page_cache_get_size (EvPageCache  *page_cache,
154                         gint          page,
155                         gint          rotation,
156                         gfloat        scale,
157                         gint         *width,
158                         gint         *height)
159 {
160         double w, h;
161
162         g_return_if_fail (EV_IS_PAGE_CACHE (page_cache));
163
164         ev_document_get_page_size (page_cache->document, page, &w, &h);
165
166         w = w * scale + 0.5;
167         h = h * scale + 0.5;
168
169         if (rotation == 0 || rotation == 180) {
170                 if (width) *width = (int)w;
171                 if (height) *height = (int)h;
172         } else {
173                 if (width) *width = (int)h;
174                 if (height) *height = (int)w;
175         }
176 }
177
178 void
179 ev_page_cache_get_max_width (EvPageCache   *page_cache,
180                              gint           rotation,
181                              gfloat         scale,
182                              gint          *width)
183 {
184         double w, h;
185
186         g_return_if_fail (EV_IS_PAGE_CACHE (page_cache));
187
188         if (!width)
189                 return;
190
191         ev_document_get_max_page_size (page_cache->document, &w, &h);
192         *width = (rotation == 0 || rotation == 180) ? w * scale : h * scale;
193 }
194
195 void
196 ev_page_cache_get_max_height (EvPageCache   *page_cache,
197                               gint           rotation,
198                               gfloat         scale,
199                               gint          *height)
200 {
201         double w, h;
202
203         g_return_if_fail (EV_IS_PAGE_CACHE (page_cache));
204
205         if (!height)
206                 return;
207
208         ev_document_get_max_page_size (page_cache->document, &w, &h);
209         *height = (rotation == 0 || rotation == 180) ? h * scale : w * scale;
210 }
211
212 gboolean
213 ev_page_cache_get_dual_even_left (EvPageCache *page_cache)
214 {
215         g_return_val_if_fail (EV_IS_PAGE_CACHE (page_cache), 0);
216
217         return (ev_document_get_n_pages (page_cache->document) > 2);
218 }
219
220 #define PAGE_CACHE_STRING "ev-page-cache"
221
222 EvPageCache *
223 ev_page_cache_get (EvDocument *document)
224 {
225         EvPageCache *page_cache;
226
227         g_return_val_if_fail (EV_IS_DOCUMENT (document), NULL);
228
229         page_cache = g_object_get_data (G_OBJECT (document), PAGE_CACHE_STRING);
230         if (page_cache == NULL) {
231                 page_cache = ev_page_cache_new (document);
232                 g_object_set_data_full (G_OBJECT (document), PAGE_CACHE_STRING, page_cache, g_object_unref);
233         }
234
235         return page_cache;
236 }