]> www.fi.muni.cz Git - evince.git/blob - shell/ev-sidebar-thumbnails.c
Add thumbnail support.
[evince.git] / shell / ev-sidebar-thumbnails.c
1 /* this file is part of evince, a gnome document viewer
2  *
3  *  Copyright (C) 2004 Red Hat, Inc.
4  *  Copyright (C) 2004 Anders Carlsson <andersca@gnome.org>
5  *
6  *  Authors:
7  *    Jonathan Blandford <jrb@alum.mit.edu>
8  *    Anders Carlsson <andersca@gnome.org>
9  *
10  * Evince is free software; you can redistribute it and/or modify it
11  * under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * Evince is distributed in the hope that it will be useful, but
16  * WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  * General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
23  */
24
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif
28
29 #include <string.h>
30 #include <gtk/gtk.h>
31
32 #include "ev-sidebar-thumbnails.h"
33 #include "ev-document-thumbnails.h"
34 #include "ev-utils.h"
35
36 #define THUMBNAIL_WIDTH 96
37
38 struct _EvSidebarThumbnailsPrivate {
39         GtkWidget *tree_view;
40         GtkListStore *list_store;
41         EvDocument *document;
42         
43         guint idle_id;
44         gint current_page, n_pages;
45 };
46
47 enum {
48         COLUMN_PAGE_STRING,
49         COLUMN_PIXBUF,
50         NUM_COLUMNS
51 };
52
53 static GtkVBoxClass *parent_class;
54
55 G_DEFINE_TYPE (EvSidebarThumbnails, ev_sidebar_thumbnails, GTK_TYPE_VBOX);
56
57 #define EV_SIDEBAR_THUMBNAILS_GET_PRIVATE(object) \
58         (G_TYPE_INSTANCE_GET_PRIVATE ((object), EV_TYPE_SIDEBAR_THUMBNAILS, EvSidebarThumbnailsPrivate));
59
60 static void
61 ev_sidebar_thumbnails_destroy (GtkObject *object)
62 {
63         EvSidebarThumbnails *ev_sidebar_thumbnails = EV_SIDEBAR_THUMBNAILS (object);
64         EvSidebarThumbnailsPrivate *priv = ev_sidebar_thumbnails->priv;
65         
66         if (priv->idle_id != 0) {
67                 g_source_remove (priv->idle_id);
68
69                 priv->idle_id = 0;
70         }
71         
72         GTK_OBJECT_CLASS (parent_class)->destroy (object);
73 }
74
75 static void
76 ev_sidebar_thumbnails_class_init (EvSidebarThumbnailsClass *ev_sidebar_thumbnails_class)
77 {
78         GObjectClass *g_object_class;
79         GtkObjectClass *gtk_object_class;
80         
81         g_object_class = G_OBJECT_CLASS (ev_sidebar_thumbnails_class);
82         gtk_object_class = GTK_OBJECT_CLASS (ev_sidebar_thumbnails_class);
83
84         parent_class = g_type_class_peek_parent (ev_sidebar_thumbnails_class);
85         
86         gtk_object_class->destroy = ev_sidebar_thumbnails_destroy;
87         
88         g_type_class_add_private (g_object_class, sizeof (EvSidebarThumbnailsPrivate));
89
90 }
91
92 static void
93 ev_sidebar_thumbnails_init (EvSidebarThumbnails *ev_sidebar_thumbnails)
94 {
95         GtkWidget *swindow;
96         EvSidebarThumbnailsPrivate *priv;
97
98         priv = ev_sidebar_thumbnails->priv = EV_SIDEBAR_THUMBNAILS_GET_PRIVATE (ev_sidebar_thumbnails);
99
100         priv->list_store = gtk_list_store_new (NUM_COLUMNS, G_TYPE_STRING, GDK_TYPE_PIXBUF);
101         priv->tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (priv->list_store));
102
103         gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (priv->tree_view), FALSE);
104         gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (priv->tree_view), -1,
105                                                      NULL, gtk_cell_renderer_pixbuf_new (),
106                                                      "pixbuf", 1, NULL);
107         gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (priv->tree_view), -1,
108                                                      NULL, gtk_cell_renderer_text_new (),
109                                                      "text", 0, NULL);
110         
111         g_object_unref (priv->list_store);
112
113         swindow = gtk_scrolled_window_new (NULL, NULL);
114         gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swindow),
115                                         GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
116         gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (swindow),
117                                              GTK_SHADOW_IN);
118
119         gtk_container_add (GTK_CONTAINER (swindow), priv->tree_view);
120         gtk_box_pack_start (GTK_BOX (ev_sidebar_thumbnails), swindow, TRUE, TRUE, 0);
121         
122         gtk_widget_show_all (swindow);
123 }
124
125 GtkWidget *
126 ev_sidebar_thumbnails_new (void)
127 {
128         GtkWidget *ev_sidebar_thumbnails;
129
130         ev_sidebar_thumbnails = g_object_new (EV_TYPE_SIDEBAR_THUMBNAILS, NULL);
131
132         return ev_sidebar_thumbnails;
133 }
134
135 static gboolean
136 populate_thumbnails (gpointer data)
137 {
138         EvSidebarThumbnails *ev_sidebar_thumbnails = EV_SIDEBAR_THUMBNAILS (data);
139         EvSidebarThumbnailsPrivate *priv = ev_sidebar_thumbnails->priv;
140         GdkPixbuf *tmp, *pixbuf;
141         GtkTreePath *path;
142         GtkTreeIter iter;
143         
144         tmp = ev_document_thumbnails_get_thumbnail (EV_DOCUMENT_THUMBNAILS (priv->document),
145                                                        priv->current_page, THUMBNAIL_WIDTH);
146
147
148         /* Add shadow */
149         pixbuf = ev_pixbuf_add_shadow (tmp, 5, 0, 0, 0.5);
150         
151         path = gtk_tree_path_new_from_indices (priv->current_page, -1);
152         gtk_tree_model_get_iter (GTK_TREE_MODEL (priv->list_store), &iter, path);
153         gtk_tree_path_free (path);
154
155         gtk_list_store_set (priv->list_store, &iter,
156                             COLUMN_PIXBUF, pixbuf,
157                             -1);
158
159         g_object_unref (tmp);
160         g_object_unref (pixbuf);
161         
162         priv->current_page++;
163         
164         if (priv->current_page == priv->n_pages)
165                 return FALSE;
166         else
167                 return TRUE;
168 }
169
170 void
171 ev_sidebar_thumbnails_set_document (EvSidebarThumbnails *sidebar_thumbnails,
172                                     EvDocument          *document)
173 {
174         GtkIconTheme *theme;
175         GdkPixbuf *loading_icon;
176         gint i, n_pages;
177         EvSidebarThumbnailsPrivate *priv = sidebar_thumbnails->priv;
178         
179         g_return_if_fail (EV_IS_DOCUMENT_THUMBNAILS (document));
180
181         if (priv->idle_id != 0) {
182                 g_source_remove (priv->idle_id);
183         }
184         
185         theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (sidebar_thumbnails)));
186
187         loading_icon = gtk_icon_theme_load_icon (theme, "gnome-fs-loading-icon",
188                                                  THUMBNAIL_WIDTH, 0, NULL);
189
190         n_pages = ev_document_get_n_pages (document);
191         
192         for (i = 0; i < n_pages; i++) {
193                 GtkTreeIter iter;
194                 gchar *page;
195
196                 page = g_strdup_printf ("Page %d", i + 1);
197                 gtk_list_store_append (sidebar_thumbnails->priv->list_store,
198                                        &iter);
199                 gtk_list_store_set (sidebar_thumbnails->priv->list_store,
200                                     &iter,
201                                     COLUMN_PAGE_STRING, page,
202                                     COLUMN_PIXBUF, loading_icon,
203                                     -1);
204                 g_free (page);
205         }
206
207         priv->document = document;
208         priv->idle_id = g_idle_add (populate_thumbnails, sidebar_thumbnails);
209         priv->n_pages = n_pages;
210         priv->current_page = 0;
211 }
212