]> www.fi.muni.cz Git - evince.git/blob - shell/ev-document-types.c
Transfer remote documents to tmp directory to display them later
[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
45 typedef struct _EvDocumentType EvDocumentType;
46 struct _EvDocumentType
47 {
48         const char *mime_type;
49         GType (*document_type_factory_callback)();
50 };
51
52 const EvDocumentType document_types[] = {
53         /* PDF: */
54         {"application/pdf",            pdf_document_get_type},
55
56         /* Postscript: */
57         {"application/postscript",     ps_document_get_type},
58         {"application/x-gzpostscript", ps_document_get_type},
59         {"image/x-eps",                ps_document_get_type},
60
61 #ifdef ENABLE_TIFF
62         /* Tiff: */
63         {"image/tiff",                 tiff_document_get_type},
64 #endif
65
66 #ifdef ENABLE_DJVU
67         /* djvu: */
68         {"image/vnd.djvu",             djvu_document_get_type},
69 #endif          
70
71 #ifdef ENABLE_DVI
72         /* dvi: */
73         {"application/x-dvi",          dvi_document_get_type},
74 #endif
75 };
76
77 /* Would be nice to have this in gdk-pixbuf */
78 static gboolean
79 mime_type_supported_by_gdk_pixbuf (const gchar *mime_type)
80 {
81         GSList *formats, *list;
82         gboolean retval = FALSE;
83
84         formats = gdk_pixbuf_get_formats ();
85
86         list = formats;
87         while (list) {
88                 GdkPixbufFormat *format = list->data;
89                 int i;
90                 gchar **mime_types;
91
92                 if (gdk_pixbuf_format_is_disabled (format))
93                         continue;
94
95                 mime_types = gdk_pixbuf_format_get_mime_types (format);
96
97                 for (i = 0; mime_types[i] != NULL; i++) {
98                         if (strcmp (mime_types[i], mime_type) == 0) {
99                                 retval = TRUE;
100                                 break;
101                         }
102                 }
103
104                 if (retval)
105                         break;
106
107                 list = list->next;
108         }
109
110         g_slist_free (formats);
111
112         return retval;
113 }
114
115
116 static GType
117 ev_document_type_from_from_mime (const char *mime_type)
118 {
119         int i;
120         
121         g_return_val_if_fail (mime_type, G_TYPE_INVALID);
122
123         for (i = 0; i < G_N_ELEMENTS (document_types); i++) {
124                 if (strcmp (mime_type, document_types[i].mime_type) == 0) {
125                         g_assert (document_types[i].document_type_factory_callback != NULL);
126                         return document_types[i].document_type_factory_callback();
127                 }
128         }
129
130         if (mime_type_supported_by_gdk_pixbuf (mime_type)) {
131                 return pixbuf_document_get_type ();
132         }
133
134         return G_TYPE_INVALID;
135 }
136
137 /**
138  * ev_document_type_get_type:
139  * @uri: String with uri
140  * @slow: Do we need to check slow gnome-vfs mime type
141  * @mime_type: If we've found handled type, the mime_type string is returned here.
142  * @error: Information about error occured
143  * 
144  * Return value: G_TYPE_INVALID on error, G_TYPE_NONE when we are not sure about
145  * mime type, and type of EvDocument implementation when we've found document.
146  **/
147 static GType
148 ev_document_type_get_type (const char *uri, gboolean slow, gchar **mime_type, GError **error)
149 {
150         GnomeVFSFileInfo *info;
151         GnomeVFSResult result;
152
153         GType type = G_TYPE_INVALID;
154         
155         info = gnome_vfs_file_info_new ();
156         result = gnome_vfs_get_file_info (uri, info,
157                                           GNOME_VFS_FILE_INFO_GET_MIME_TYPE |
158                                           GNOME_VFS_FILE_INFO_FOLLOW_LINKS | 
159                                           (slow ? GNOME_VFS_FILE_INFO_FORCE_SLOW_MIME_TYPE : 0));
160         if (result != GNOME_VFS_OK) {
161                 g_set_error (error,
162                              EV_DOCUMENT_ERROR,
163                              0,
164                              gnome_vfs_result_to_string (result));                      
165                 gnome_vfs_file_info_unref (info);
166                 return G_TYPE_INVALID;
167         } 
168         
169         if (info->mime_type == NULL) {
170                 g_set_error (error,
171                              EV_DOCUMENT_ERROR, 
172                              0,
173                              _("Unknown MIME Type"));
174                 gnome_vfs_file_info_unref (info);
175                 return slow ? G_TYPE_INVALID : G_TYPE_NONE;
176         }
177         
178         type = ev_document_type_from_from_mime (info->mime_type);
179         
180         if (type == G_TYPE_INVALID) {
181                 g_set_error (error,
182                              EV_DOCUMENT_ERROR, 
183                              0,
184                              _("Unhandled MIME type: '%s'"), info->mime_type);
185                 gnome_vfs_file_info_unref (info);
186                 return slow ? G_TYPE_INVALID : G_TYPE_NONE;
187         }                       
188
189         if (mime_type != NULL) {
190                     *mime_type = g_strdup (info->mime_type);
191         }
192         gnome_vfs_file_info_unref (info);
193         
194         return type;
195 }
196
197 GType
198 ev_document_type_lookup (const char *uri, gchar **mime_type, GError **error)
199 {
200         GType type = G_TYPE_INVALID;
201         
202         type = ev_document_type_get_type (uri, FALSE, mime_type, error);
203
204         if (type != G_TYPE_NONE)
205                 return type;
206                 
207         if (error) {
208                 g_error_free (*error);
209                 *error = NULL;
210         }
211
212         type = ev_document_type_get_type (uri, TRUE, mime_type, error);
213
214         return type;
215 }