]> www.fi.muni.cz Git - evince.git/blob - shell/ev-document-types.c
724412fb968e2e808bae1b8fcbae83e4270ea288
[evince.git] / shell / ev-document-types.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; c-indent-level: 8 -*- */
2 /*
3  *  Copyright (C) 2005, Red Hat, Inc. 
4  *
5  *  This program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2, or (at your option)
8  *  any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this program; if not, write to the Free Software
17  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18  *
19  */
20
21 #ifdef HAVE_CONFIG_H
22 #include "config.h"
23 #endif
24
25 #include "ev-document-types.h"
26
27 /* The various document type backends: */
28 #include "ev-poppler.h"
29 #include "pixbuf-document.h"
30 #include "tiff-document.h"
31 #include "ps-document.h"
32 #ifdef ENABLE_DVI
33 #include "dvi-document.h"
34 #endif
35 #ifdef ENABLE_DJVU
36 #include "djvu-document.h"
37 #endif
38
39 #include <string.h>
40 #include <glib/gi18n.h>
41 #include <libgnomevfs/gnome-vfs-mime-utils.h>
42 #include <libgnomevfs/gnome-vfs-file-info.h>
43 #include <libgnomevfs/gnome-vfs-ops.h>
44 #include <gtk/gtkfilechooserdialog.h>
45
46 typedef struct _EvDocumentType EvDocumentType;
47 struct _EvDocumentType
48 {
49         const char *mime_type;
50         GType (*document_type_factory_callback)();
51 };
52
53 const EvDocumentType document_types[] = {
54         /* PDF: */
55         {"application/pdf",            pdf_document_get_type},
56
57         /* Postscript: */
58         {"application/postscript",     ps_document_get_type},
59         {"application/x-gzpostscript", ps_document_get_type},
60         {"image/x-eps",                ps_document_get_type},
61
62 #ifdef ENABLE_TIFF
63         /* Tiff: */
64         {"image/tiff",                 tiff_document_get_type},
65 #endif
66
67 #ifdef ENABLE_DJVU
68         /* djvu: */
69         {"image/vnd.djvu",             djvu_document_get_type},
70 #endif          
71
72 #ifdef ENABLE_DVI
73         /* dvi: */
74         {"application/x-dvi",          dvi_document_get_type},
75 #endif
76 };
77
78 /* Would be nice to have this in gdk-pixbuf */
79 static gboolean
80 mime_type_supported_by_gdk_pixbuf (const gchar *mime_type)
81 {
82         GSList *formats, *list;
83         gboolean retval = FALSE;
84
85         formats = gdk_pixbuf_get_formats ();
86
87         list = formats;
88         while (list) {
89                 GdkPixbufFormat *format = list->data;
90                 int i;
91                 gchar **mime_types;
92
93                 if (gdk_pixbuf_format_is_disabled (format))
94                         continue;
95
96                 mime_types = gdk_pixbuf_format_get_mime_types (format);
97
98                 for (i = 0; mime_types[i] != NULL; i++) {
99                         if (strcmp (mime_types[i], mime_type) == 0) {
100                                 retval = TRUE;
101                                 break;
102                         }
103                 }
104
105                 if (retval)
106                         break;
107
108                 list = list->next;
109         }
110
111         g_slist_free (formats);
112
113         return retval;
114 }
115
116
117 static GType
118 ev_document_type_from_from_mime (const char *mime_type)
119 {
120         int i;
121         
122         g_return_val_if_fail (mime_type, G_TYPE_INVALID);
123
124         for (i = 0; i < G_N_ELEMENTS (document_types); i++) {
125                 if (strcmp (mime_type, document_types[i].mime_type) == 0) {
126                         g_assert (document_types[i].document_type_factory_callback != NULL);
127                         return document_types[i].document_type_factory_callback();
128                 }
129         }
130
131         if (mime_type_supported_by_gdk_pixbuf (mime_type)) {
132                 return pixbuf_document_get_type ();
133         }
134
135         return G_TYPE_INVALID;
136 }
137
138 /**
139  * ev_document_type_get_type:
140  * @uri: String with uri
141  * @slow: Do we need to check slow gnome-vfs mime type
142  * @mime_type: If we've found handled type, the mime_type string is returned here.
143  * @error: Information about error occured
144  * 
145  * Return value: G_TYPE_INVALID on error, G_TYPE_NONE when we are not sure about
146  * mime type, and type of EvDocument implementation when we've found document.
147  **/
148 static GType
149 ev_document_type_get_type (const char *uri, gboolean slow, gchar **mime_type, GError **error)
150 {
151         GnomeVFSFileInfo *info;
152         GnomeVFSResult result;
153
154         GType type = G_TYPE_INVALID;
155         
156         info = gnome_vfs_file_info_new ();
157         result = gnome_vfs_get_file_info (uri, info,
158                                           GNOME_VFS_FILE_INFO_GET_MIME_TYPE |
159                                           GNOME_VFS_FILE_INFO_FOLLOW_LINKS | 
160                                           (slow ? GNOME_VFS_FILE_INFO_FORCE_SLOW_MIME_TYPE : 0));
161         if (result != GNOME_VFS_OK) {
162                 g_set_error (error,
163                              EV_DOCUMENT_ERROR,
164                              0,
165                              gnome_vfs_result_to_string (result));                      
166                 gnome_vfs_file_info_unref (info);
167                 return G_TYPE_INVALID;
168         } 
169         
170         if (info->mime_type == NULL) {
171                 g_set_error (error,
172                              EV_DOCUMENT_ERROR, 
173                              0,
174                              _("Unknown MIME Type"));
175                 gnome_vfs_file_info_unref (info);
176                 return slow ? G_TYPE_INVALID : G_TYPE_NONE;
177         }
178         
179         type = ev_document_type_from_from_mime (info->mime_type);
180         
181         if (type == G_TYPE_INVALID) {
182                 g_set_error (error,
183                              EV_DOCUMENT_ERROR, 
184                              0,
185                              _("Unhandled MIME type: '%s'"), info->mime_type);
186                 gnome_vfs_file_info_unref (info);
187                 return slow ? G_TYPE_INVALID : G_TYPE_NONE;
188         }                       
189
190         if (mime_type != NULL) {
191                     *mime_type = g_strdup (info->mime_type);
192         }
193         gnome_vfs_file_info_unref (info);
194         
195         return type;
196 }
197
198 GType
199 ev_document_type_lookup (const char *uri, gchar **mime_type, GError **error)
200 {
201         GType type = G_TYPE_INVALID;
202         
203         type = ev_document_type_get_type (uri, FALSE, mime_type, error);
204
205         if (type != G_TYPE_NONE)
206                 return type;
207                 
208         if (error) {
209                 g_error_free (*error);
210                 *error = NULL;
211         }
212
213         type = ev_document_type_get_type (uri, TRUE, mime_type, error);
214
215         return type;
216 }
217
218 void 
219 ev_document_types_add_filters (GtkWidget *chooser)
220 {
221         GtkFileFilter *documents_filter;
222         GtkFileFilter *pdf_filter;
223         GtkFileFilter *ps_filter;
224         GtkFileFilter *pixbuf_filter;
225         GtkFileFilter *all_filter;
226 #ifdef ENABLE_DJVU
227         GtkFileFilter *djvu_filter;
228 #endif
229 #ifdef ENABLE_DVI
230         GtkFileFilter *dvi_filter;
231 #endif
232
233         documents_filter = gtk_file_filter_new ();
234         gtk_file_filter_set_name (documents_filter,
235                                   _("All Documents"));
236         gtk_file_filter_add_mime_type (documents_filter, "application/postscript");
237         gtk_file_filter_add_mime_type (documents_filter, "application/x-gzpostscript");
238         gtk_file_filter_add_mime_type (documents_filter, "image/x-eps");
239         gtk_file_filter_add_mime_type (documents_filter, "application/pdf");
240 #ifdef ENABLE_DVI
241         gtk_file_filter_add_mime_type (documents_filter, "application/x-dvi");
242 #endif
243         gtk_file_filter_add_pixbuf_formats (documents_filter);
244 #ifdef ENABLE_DJVU
245         gtk_file_filter_add_mime_type (documents_filter, "image/vnd.djvu");
246 #endif
247         gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (chooser), documents_filter);
248
249         ps_filter = gtk_file_filter_new ();
250         gtk_file_filter_set_name (ps_filter, _("PostScript Documents"));
251         gtk_file_filter_add_mime_type (ps_filter, "application/postscript");
252         gtk_file_filter_add_mime_type (ps_filter, "application/x-gzpostscript");
253         gtk_file_filter_add_mime_type (ps_filter, "image/x-eps");
254         gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (chooser), ps_filter);
255
256         pdf_filter = gtk_file_filter_new ();
257         gtk_file_filter_set_name (pdf_filter, _("PDF Documents"));
258         gtk_file_filter_add_mime_type (pdf_filter, "application/pdf");
259         gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (chooser), pdf_filter);
260
261 #ifdef ENABLE_DVI
262         dvi_filter = gtk_file_filter_new ();
263         gtk_file_filter_set_name (dvi_filter, _("DVI Documents"));
264         gtk_file_filter_add_mime_type (dvi_filter, "application/x-dvi");
265         gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (chooser), dvi_filter);
266 #endif
267
268         pixbuf_filter = gtk_file_filter_new ();
269         gtk_file_filter_set_name (pixbuf_filter, _("Images"));
270         gtk_file_filter_add_pixbuf_formats (pixbuf_filter);
271         gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (chooser), pixbuf_filter);
272
273 #ifdef ENABLE_DJVU
274         djvu_filter = gtk_file_filter_new ();
275         gtk_file_filter_set_name (djvu_filter, _("Djvu Documents"));
276         gtk_file_filter_add_mime_type (djvu_filter, "image/vnd.djvu");
277         gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (chooser), djvu_filter);
278 #endif  
279         
280         all_filter = gtk_file_filter_new ();
281         gtk_file_filter_set_name (all_filter, _("All Files"));
282         gtk_file_filter_add_pattern (all_filter, "*");
283
284         gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (chooser), all_filter);
285         gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (chooser), documents_filter);
286 }
287
288 void 
289 ev_document_types_add_filters_for_type (GtkWidget *chooser, GType type)
290 {
291         GtkFileFilter *documents_filter;
292         GtkFileFilter *pdf_filter;
293         GtkFileFilter *ps_filter;
294         GtkFileFilter *pixbuf_filter;
295         GtkFileFilter *all_filter;
296 #ifdef ENABLE_DJVU
297         GtkFileFilter *djvu_filter;
298 #endif
299 #ifdef ENABLE_DVI
300         GtkFileFilter *dvi_filter;
301 #endif
302         GtkFileFilter *default_filter;
303
304         documents_filter = gtk_file_filter_new ();
305         gtk_file_filter_set_name (documents_filter,
306                                   _("All Documents"));
307         gtk_file_filter_add_mime_type (documents_filter, "application/postscript");
308         gtk_file_filter_add_mime_type (documents_filter, "application/x-gzpostscript");
309         gtk_file_filter_add_mime_type (documents_filter, "image/x-eps");
310         gtk_file_filter_add_mime_type (documents_filter, "application/pdf");
311 #ifdef ENABLE_DVI
312         gtk_file_filter_add_mime_type (documents_filter, "application/x-dvi");
313 #endif
314         gtk_file_filter_add_pixbuf_formats (documents_filter);
315 #ifdef ENABLE_DJVU
316         gtk_file_filter_add_mime_type (documents_filter, "image/vnd.djvu");
317 #endif
318         gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (chooser), documents_filter);
319
320         if (type == PS_TYPE_DOCUMENT) {
321                 ps_filter = gtk_file_filter_new ();
322                 gtk_file_filter_set_name (ps_filter, _("PostScript Documents"));
323                 gtk_file_filter_add_mime_type (ps_filter, "application/postscript");
324                 gtk_file_filter_add_mime_type (ps_filter, "application/x-gzpostscript");
325                 gtk_file_filter_add_mime_type (ps_filter, "image/x-eps");
326                 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (chooser), ps_filter);
327                 default_filter = ps_filter;
328         } else if (type == PDF_TYPE_DOCUMENT) {
329                 pdf_filter = gtk_file_filter_new ();
330                 gtk_file_filter_set_name (pdf_filter, _("PDF Documents"));
331                 gtk_file_filter_add_mime_type (pdf_filter, "application/pdf");
332                 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (chooser), pdf_filter);
333                 default_filter = pdf_filter;
334 #ifdef ENABLE_DVI
335         } else if (type == DVI_TYPE_DOCUMENT) {
336                 dvi_filter = gtk_file_filter_new ();
337                 gtk_file_filter_set_name (dvi_filter, _("DVI Documents"));
338                 gtk_file_filter_add_mime_type (dvi_filter, "application/x-dvi");
339                 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (chooser), dvi_filter);
340                 default_filter = dvi_filter;
341 #endif
342         } else if (type == PIXBUF_TYPE_DOCUMENT) {
343                 pixbuf_filter = gtk_file_filter_new ();
344                 gtk_file_filter_set_name (pixbuf_filter, _("Images"));
345                 gtk_file_filter_add_pixbuf_formats (pixbuf_filter);
346                 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (chooser), pixbuf_filter);
347                 default_filter = pixbuf_filter;
348 #ifdef ENABLE_DJVU
349         } else if (type == DJVU_TYPE_DOCUMENT) {
350                 djvu_filter = gtk_file_filter_new ();
351                 gtk_file_filter_set_name (djvu_filter, _("Djvu Documents"));
352                 gtk_file_filter_add_mime_type (djvu_filter, "image/vnd.djvu");
353                 gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (chooser), djvu_filter);
354                 default_filter = djvu_filter;
355 #endif  
356         } else {
357                 default_filter = documents_filter;
358         }
359
360         all_filter = gtk_file_filter_new ();
361         gtk_file_filter_set_name (all_filter, _("All Files"));
362         gtk_file_filter_add_pattern (all_filter, "*");
363
364         gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (chooser), all_filter);
365         gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (chooser), default_filter);
366 }
367