~ubuntu-branches/ubuntu/quantal/evince/quantal

« back to all changes in this revision

Viewing changes to libdocument/ev-backends-manager.c

  • Committer: Package Import Robot
  • Author(s): Robert Ancell
  • Date: 2012-06-07 16:47:24 UTC
  • mfrom: (1.1.76)
  • Revision ID: package-import@ubuntu.com-20120607164724-fg32ta2uv3lrkwnk
Tags: 3.5.2-0ubuntu1
* New upstream release
* debian/control:
  - Bump build-depends on libpoppler-glib-dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* this file is part of evince, a gnome document viewer
2
 
 *
3
 
 *  Copyright (C) 2007 Carlos Garcia Campos <carlosgc@gnome.org>
4
 
 *
5
 
 * Evince is free software; you can redistribute it and/or modify it
6
 
 * under the terms of the GNU General Public License as published by
7
 
 * the Free Software Foundation; either version 2 of the License, or
8
 
 * (at your option) any later version.
9
 
 *
10
 
 * Evince is distributed in the hope that it will be useful, but
11
 
 * WITHOUT ANY WARRANTY; without even the implied warranty of
12
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
 
 * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18
 
 */
19
 
 
20
 
#include <config.h>
21
 
 
22
 
#include <glib/gstdio.h>
23
 
 
24
 
#include "ev-module.h"
25
 
#include "ev-backends-manager.h"
26
 
 
27
 
static GList *ev_backends_list = NULL;
28
 
 
29
 
typedef struct _EvBackendInfo EvBackendInfo;
30
 
struct _EvBackendInfo {
31
 
        gchar       *module_name;
32
 
        GTypeModule *module;
33
 
        gboolean     resident;
34
 
 
35
 
        GType        type_id;
36
 
 
37
 
        gchar       *type_desc;
38
 
        gchar      **mime_types;
39
 
};
40
 
 
41
 
#define EV_BACKENDS_GROUP     "Evince Backend"
42
 
#define EV_BACKENDS_EXTENSION ".evince-backend"
43
 
 
44
 
static gchar *backendsdir = NULL;
45
 
 
46
 
static const gchar *
47
 
backends_dir (void)
48
 
{
49
 
        if (!backendsdir) {
50
 
#ifdef G_OS_WIN32
51
 
                gchar *dir;
52
 
 
53
 
                dir = g_win32_get_package_installation_directory_of_module (NULL);
54
 
                backendsdir = g_build_filename (dir, "lib", "evince",
55
 
                                                EV_BACKENDSBINARYVERSION,
56
 
                                                "backends", NULL);
57
 
                g_free (dir);
58
 
#else
59
 
                backendsdir = g_strdup (EV_BACKENDSDIR);
60
 
#endif
61
 
        }
62
 
 
63
 
        return backendsdir;
64
 
}
65
 
 
66
 
static void
67
 
ev_backend_info_free (EvBackendInfo *info)
68
 
{
69
 
        g_free (info->module_name);
70
 
        g_free (info->type_desc);
71
 
        g_strfreev (info->mime_types);
72
 
        g_free (info);
73
 
}
74
 
 
75
 
static EvBackendInfo *
76
 
ev_backends_manager_load_backend (const gchar *file)
77
 
{
78
 
        EvBackendInfo *info;
79
 
        GKeyFile      *backend_file = NULL;
80
 
        GError        *error = NULL;
81
 
 
82
 
        backend_file = g_key_file_new ();
83
 
        if (!g_key_file_load_from_file (backend_file, file, G_KEY_FILE_NONE, &error)) {
84
 
                g_warning ("Error opening backend file %s: %s",
85
 
                           file, error->message);
86
 
                g_error_free (error);
87
 
                g_key_file_free (backend_file);
88
 
 
89
 
                return NULL;
90
 
        }
91
 
 
92
 
        info = g_new0 (EvBackendInfo, 1);
93
 
        info->module_name = g_key_file_get_string (backend_file, EV_BACKENDS_GROUP,
94
 
                                                   "Module", NULL);
95
 
        if (!info->module_name) {
96
 
                g_warning ("Bad evince backend file %s: Could not find 'Module'",
97
 
                           file);
98
 
                ev_backend_info_free (info);
99
 
                g_key_file_free (backend_file);
100
 
 
101
 
                return NULL;
102
 
        }
103
 
 
104
 
        info->resident = g_key_file_get_boolean (backend_file, EV_BACKENDS_GROUP,
105
 
                                                 "Resident", NULL);
106
 
        
107
 
        info->type_desc = g_key_file_get_locale_string (backend_file, EV_BACKENDS_GROUP,
108
 
                                                        "TypeDescription", NULL, NULL);
109
 
        if (!info->type_desc) {
110
 
                g_warning ("Bad evince backend file %s: Could not find 'TypeDescription'",
111
 
                           file);
112
 
                ev_backend_info_free (info);
113
 
                g_key_file_free (backend_file);
114
 
 
115
 
                return NULL;
116
 
        }
117
 
 
118
 
        info->mime_types = g_key_file_get_string_list (backend_file, EV_BACKENDS_GROUP,
119
 
                                                       "MimeType", NULL, NULL);
120
 
        if (!info->mime_types) {
121
 
                g_warning ("Bad evince backend file %s: Could not find 'MimeType'",
122
 
                           file);
123
 
                ev_backend_info_free (info);
124
 
                g_key_file_free (backend_file);
125
 
 
126
 
                return NULL;
127
 
        }
128
 
 
129
 
        g_key_file_free (backend_file);
130
 
 
131
 
        return info;
132
 
}
133
 
 
134
 
static gboolean
135
 
ev_backends_manager_load (void)
136
 
{
137
 
        GDir        *dir;
138
 
        const gchar *dirent;
139
 
        GError      *error = NULL;
140
 
 
141
 
        dir = g_dir_open (backends_dir(), 0, &error);
142
 
        if (!dir) {
143
 
                g_warning ("%s", error->message);
144
 
                g_error_free (error);
145
 
 
146
 
                return FALSE;
147
 
        }
148
 
 
149
 
        while ((dirent = g_dir_read_name (dir))) {
150
 
                EvBackendInfo *info;
151
 
                gchar         *file;
152
 
                
153
 
                if (!g_str_has_suffix (dirent, EV_BACKENDS_EXTENSION))
154
 
                        continue;
155
 
 
156
 
                file = g_build_filename (backends_dir(), dirent, NULL);
157
 
                info = ev_backends_manager_load_backend (file);
158
 
                g_free (file);
159
 
 
160
 
                if (!info)
161
 
                        continue;
162
 
                
163
 
                ev_backends_list = g_list_prepend (ev_backends_list, info);
164
 
        }
165
 
 
166
 
        g_dir_close (dir);
167
 
 
168
 
        return ev_backends_list != NULL;
169
 
}
170
 
 
171
 
/*
172
 
 * _ev_backends_manager_init:
173
 
 *
174
 
 * Initializes the evince backends manager.
175
 
 *
176
 
 * Returns: %TRUE if there were any backends found; %FALSE otherwise
177
 
 */
178
 
gboolean
179
 
_ev_backends_manager_init (void)
180
 
{
181
 
        if (ev_backends_list)
182
 
                return TRUE;
183
 
 
184
 
        return ev_backends_manager_load ();
185
 
}
186
 
 
187
 
/*
188
 
 * _ev_backends_manager_shutdown:
189
 
 *
190
 
 * Shuts the evince backends manager down.
191
 
 */
192
 
void
193
 
_ev_backends_manager_shutdown (void)
194
 
{
195
 
        g_list_foreach (ev_backends_list, (GFunc)ev_backend_info_free, NULL);
196
 
        g_list_free (ev_backends_list);
197
 
        ev_backends_list = NULL;
198
 
 
199
 
        g_free (backendsdir);
200
 
}
201
 
 
202
 
static EvBackendInfo *
203
 
ev_backends_manager_get_backend_info (const gchar *mime_type)
204
 
{
205
 
        GList *l;
206
 
 
207
 
        for (l = ev_backends_list; l; l = g_list_next (l)) {
208
 
                EvBackendInfo *info;
209
 
                gint           i = 0;
210
 
                const char    *mime;
211
 
                
212
 
                info = (EvBackendInfo *)l->data;
213
 
                
214
 
                while ((mime = info->mime_types[i++])) {
215
 
                        if (g_ascii_strcasecmp (mime, mime_type) == 0)
216
 
                                return info;
217
 
                }
218
 
        }
219
 
 
220
 
        return NULL;
221
 
}
222
 
 
223
 
EvDocument *
224
 
ev_backends_manager_get_document (const gchar *mime_type)
225
 
{
226
 
        EvDocument    *document;
227
 
        EvBackendInfo *info;
228
 
 
229
 
        info = ev_backends_manager_get_backend_info (mime_type);
230
 
        if (!info)
231
 
                return NULL;
232
 
 
233
 
        if (!info->module) {
234
 
                gchar *path;
235
 
                
236
 
                path = g_module_build_path (backends_dir(), info->module_name);
237
 
                info->module = G_TYPE_MODULE (ev_module_new (path, info->resident));
238
 
                g_free (path);
239
 
        }
240
 
        
241
 
        if (!g_type_module_use (info->module)) {
242
 
                g_warning ("Cannot load backend '%s' since file '%s' cannot be read.",
243
 
                           info->module_name,
244
 
                           ev_module_get_path (EV_MODULE (info->module)));
245
 
                g_object_unref (G_OBJECT (info->module));
246
 
                info->module = NULL;
247
 
 
248
 
                return NULL;
249
 
        }
250
 
 
251
 
        document = EV_DOCUMENT (ev_module_new_object (EV_MODULE (info->module)));
252
 
        g_type_module_unuse (info->module);
253
 
 
254
 
        return document;
255
 
}
256
 
 
257
 
static EvBackendInfo *
258
 
get_document_backend_info (EvDocument *document)
259
 
{
260
 
        GList *l;
261
 
 
262
 
        for (l = ev_backends_list; l; l = g_list_next (l)) {
263
 
                EvBackendInfo *info;
264
 
                GType          type_id;
265
 
 
266
 
                info = (EvBackendInfo *)l->data;
267
 
 
268
 
                if (!info->module)
269
 
                        continue;
270
 
 
271
 
                type_id = ev_module_get_object_type (EV_MODULE (info->module));
272
 
 
273
 
                if (G_TYPE_CHECK_INSTANCE_TYPE (document, type_id)) {
274
 
                        return info;
275
 
                }
276
 
        }
277
 
 
278
 
        return NULL;
279
 
}
280
 
 
281
 
const gchar *
282
 
ev_backends_manager_get_document_module_name (EvDocument *document)
283
 
{
284
 
        EvBackendInfo *info;
285
 
 
286
 
        info = get_document_backend_info (document);
287
 
        return info ? info->module_name : NULL;
288
 
}
289
 
 
290
 
static EvTypeInfo *
291
 
ev_type_info_new (const gchar *desc, const gchar **mime_types)
292
 
{
293
 
        EvTypeInfo *info;
294
 
 
295
 
        info = g_new (EvTypeInfo, 1);
296
 
 
297
 
        info->desc = desc;
298
 
        info->mime_types = mime_types;
299
 
 
300
 
        return info;
301
 
}
302
 
 
303
 
EvTypeInfo *
304
 
ev_backends_manager_get_document_type_info (EvDocument *document)
305
 
{
306
 
        EvBackendInfo *info;
307
 
 
308
 
        info = get_document_backend_info (document);
309
 
        return info ?
310
 
                ev_type_info_new (info->type_desc,
311
 
                                  (const gchar **)info->mime_types)
312
 
                : NULL;
313
 
}
314
 
 
315
 
GList *
316
 
ev_backends_manager_get_all_types_info (void)
317
 
{
318
 
        GList *l;
319
 
        GList *retval = NULL;
320
 
 
321
 
        for (l = ev_backends_list; l; l = g_list_next (l)) {
322
 
                EvBackendInfo *info;
323
 
                EvTypeInfo    *type_info;
324
 
 
325
 
                info = (EvBackendInfo *)l->data;
326
 
 
327
 
                type_info = ev_type_info_new (info->type_desc,
328
 
                                              (const gchar **)info->mime_types);
329
 
                retval = g_list_prepend (retval, type_info);
330
 
        }
331
 
 
332
 
        return retval;
333
 
}