~ubuntu-branches/ubuntu/trusty/evince/trusty-proposed

« back to all changes in this revision

Viewing changes to backend/ev-attachment.c

Tags: upstream-0.5.3
ImportĀ upstreamĀ versionĀ 0.5.3

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) 2006 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
 
18
 */
 
19
 
 
20
#include <glib/gi18n.h>
 
21
#include <glib/gstdio.h>
 
22
#include <libgnomevfs/gnome-vfs.h>
 
23
#include <libgnomevfs/gnome-vfs-mime-handlers.h>
 
24
#include <libgnomevfs/gnome-vfs-mime-utils.h>
 
25
#include "ev-attachment.h"
 
26
 
 
27
enum
 
28
{
 
29
        PROP_0,
 
30
        PROP_NAME,
 
31
        PROP_DESCRIPTION,
 
32
        PROP_MTIME,
 
33
        PROP_CTIME,
 
34
        PROP_SIZE,
 
35
        PROP_DATA
 
36
};
 
37
 
 
38
struct _EvAttachmentPrivate {
 
39
        gchar                   *name;
 
40
        gchar                   *description;
 
41
        GTime                    mtime;
 
42
        GTime                    ctime;
 
43
        gsize                    size;
 
44
        gchar                   *data;
 
45
        gchar                   *mime_type;
 
46
 
 
47
        GnomeVFSMimeApplication *app;
 
48
        gchar                   *tmp_uri;
 
49
};
 
50
 
 
51
#define EV_ATTACHMENT_GET_PRIVATE(object) \
 
52
                (G_TYPE_INSTANCE_GET_PRIVATE ((object), EV_TYPE_ATTACHMENT, EvAttachmentPrivate))
 
53
 
 
54
G_DEFINE_TYPE (EvAttachment, ev_attachment, G_TYPE_OBJECT)
 
55
 
 
56
GQuark
 
57
ev_attachment_error_quark (void)
 
58
{
 
59
        static GQuark error_quark = 0;
 
60
        
 
61
        if (error_quark == 0)
 
62
                error_quark =
 
63
                        g_quark_from_static_string ("ev-attachment-error-quark");
 
64
        
 
65
        return error_quark;
 
66
}
 
67
 
 
68
static void
 
69
ev_attachment_finalize (GObject *object)
 
70
{
 
71
        EvAttachment *attachment = EV_ATTACHMENT (object);
 
72
 
 
73
        if (attachment->priv->name) {
 
74
                g_free (attachment->priv->name);
 
75
                attachment->priv->name = NULL;
 
76
        }
 
77
 
 
78
        if (attachment->priv->description) {
 
79
                g_free (attachment->priv->description);
 
80
                attachment->priv->description = NULL;
 
81
        }
 
82
 
 
83
        if (attachment->priv->data) {
 
84
                g_free (attachment->priv->data);
 
85
                attachment->priv->data = NULL;
 
86
        }
 
87
 
 
88
        if (attachment->priv->mime_type) {
 
89
                g_free (attachment->priv->mime_type);
 
90
                attachment->priv->mime_type = NULL;
 
91
        }
 
92
 
 
93
        if (attachment->priv->app) {
 
94
                gnome_vfs_mime_application_free (attachment->priv->app);
 
95
                attachment->priv->app = NULL;
 
96
        }
 
97
 
 
98
        if (attachment->priv->tmp_uri) {
 
99
                g_unlink (attachment->priv->tmp_uri);
 
100
                g_free (attachment->priv->tmp_uri);
 
101
                attachment->priv->tmp_uri = NULL;
 
102
        }
 
103
 
 
104
        (* G_OBJECT_CLASS (ev_attachment_parent_class)->finalize) (object);
 
105
}
 
106
 
 
107
static void
 
108
ev_attachment_set_property (GObject      *object,
 
109
                            guint         prop_id,
 
110
                            const GValue *value,
 
111
                            GParamSpec   *param_spec)
 
112
{
 
113
        EvAttachment *attachment = EV_ATTACHMENT (object);
 
114
 
 
115
        switch (prop_id) {
 
116
        case PROP_NAME:
 
117
                attachment->priv->name = g_value_dup_string (value);
 
118
                break;
 
119
        case PROP_DESCRIPTION:
 
120
                attachment->priv->description = g_value_dup_string (value);
 
121
                break;
 
122
        case PROP_MTIME:
 
123
                attachment->priv->mtime = g_value_get_ulong (value);
 
124
                break;
 
125
        case PROP_CTIME:
 
126
                attachment->priv->ctime = g_value_get_ulong (value);
 
127
                break;
 
128
        case PROP_SIZE:
 
129
                attachment->priv->size = g_value_get_uint (value);
 
130
                break;
 
131
        case PROP_DATA:
 
132
                attachment->priv->data = g_value_get_pointer (value);
 
133
                attachment->priv->mime_type =
 
134
                        g_strdup (gnome_vfs_get_mime_type_for_data (attachment->priv->data,
 
135
                                                                    attachment->priv->size));
 
136
                break;
 
137
        default:
 
138
                G_OBJECT_WARN_INVALID_PROPERTY_ID (object,
 
139
                                                   prop_id,
 
140
                                                   param_spec);
 
141
                break;
 
142
        }
 
143
}
 
144
 
 
145
static void
 
146
ev_attachment_class_init (EvAttachmentClass *klass)
 
147
{
 
148
        GObjectClass *g_object_class;
 
149
 
 
150
        g_object_class = G_OBJECT_CLASS (klass);
 
151
 
 
152
        g_object_class->set_property = ev_attachment_set_property;
 
153
 
 
154
        g_type_class_add_private (g_object_class, sizeof (EvAttachmentPrivate));
 
155
 
 
156
        /* Properties */
 
157
        g_object_class_install_property (g_object_class,
 
158
                                         PROP_NAME,
 
159
                                         g_param_spec_string ("name",
 
160
                                                              "Name",
 
161
                                                              "The attachment name",
 
162
                                                              NULL,
 
163
                                                              G_PARAM_WRITABLE |
 
164
                                                              G_PARAM_CONSTRUCT_ONLY));
 
165
        g_object_class_install_property (g_object_class,
 
166
                                         PROP_DESCRIPTION,
 
167
                                         g_param_spec_string ("description",
 
168
                                                              "Description",
 
169
                                                              "The attachment description",
 
170
                                                              NULL,
 
171
                                                              G_PARAM_WRITABLE |
 
172
                                                              G_PARAM_CONSTRUCT_ONLY));
 
173
        g_object_class_install_property (g_object_class,
 
174
                                         PROP_MTIME,
 
175
                                         g_param_spec_ulong ("mtime",
 
176
                                                             "ModifiedTime", 
 
177
                                                             "The attachment modification date",
 
178
                                                             0, G_MAXULONG, 0,
 
179
                                                             G_PARAM_WRITABLE |
 
180
                                                             G_PARAM_CONSTRUCT_ONLY));
 
181
        g_object_class_install_property (g_object_class,
 
182
                                         PROP_CTIME,
 
183
                                         g_param_spec_ulong ("ctime",
 
184
                                                             "CreationTime",
 
185
                                                             "The attachment creation date",
 
186
                                                             0, G_MAXULONG, 0,
 
187
                                                             G_PARAM_WRITABLE |
 
188
                                                             G_PARAM_CONSTRUCT_ONLY));
 
189
        g_object_class_install_property (g_object_class,
 
190
                                         PROP_SIZE,
 
191
                                         g_param_spec_uint ("size",
 
192
                                                            "Size",
 
193
                                                            "The attachment size",
 
194
                                                            0, G_MAXUINT, 0,
 
195
                                                            G_PARAM_WRITABLE |
 
196
                                                            G_PARAM_CONSTRUCT_ONLY));
 
197
        g_object_class_install_property (g_object_class,
 
198
                                         PROP_DATA,
 
199
                                         g_param_spec_pointer ("data",
 
200
                                                               "Data",
 
201
                                                               "The attachment data",
 
202
                                                               G_PARAM_WRITABLE |
 
203
                                                               G_PARAM_CONSTRUCT_ONLY));
 
204
        
 
205
        g_object_class->finalize = ev_attachment_finalize;
 
206
}
 
207
 
 
208
static void
 
209
ev_attachment_init (EvAttachment *attachment)
 
210
{
 
211
        attachment->priv = EV_ATTACHMENT_GET_PRIVATE (attachment);
 
212
 
 
213
        attachment->priv->name = NULL;
 
214
        attachment->priv->description = NULL;
 
215
        attachment->priv->data = NULL;
 
216
        attachment->priv->mime_type = NULL;
 
217
 
 
218
        attachment->priv->tmp_uri = NULL;
 
219
}
 
220
 
 
221
EvAttachment *
 
222
ev_attachment_new (const gchar *name,
 
223
                   const gchar *description,
 
224
                   GTime        mtime,
 
225
                   GTime        ctime,
 
226
                   gsize        size,
 
227
                   gpointer     data)
 
228
{
 
229
        EvAttachment *attachment;
 
230
 
 
231
        attachment = g_object_new (EV_TYPE_ATTACHMENT,
 
232
                                   "name", name,
 
233
                                   "description", description,
 
234
                                   "mtime", mtime,
 
235
                                   "ctime", ctime,
 
236
                                   "size", size,
 
237
                                   "data", data,
 
238
                                   NULL);
 
239
 
 
240
        return attachment;
 
241
}
 
242
 
 
243
const gchar *
 
244
ev_attachment_get_name (EvAttachment *attachment)
 
245
{
 
246
        g_return_val_if_fail (EV_IS_ATTACHMENT (attachment), NULL);
 
247
 
 
248
        return attachment->priv->name;
 
249
}
 
250
 
 
251
const gchar *
 
252
ev_attachment_get_description (EvAttachment *attachment)
 
253
{
 
254
        g_return_val_if_fail (EV_IS_ATTACHMENT (attachment), NULL);
 
255
 
 
256
        return attachment->priv->description;
 
257
}
 
258
 
 
259
GTime
 
260
ev_attachment_get_modification_date (EvAttachment *attachment)
 
261
{
 
262
        g_return_val_if_fail (EV_IS_ATTACHMENT (attachment), 0);
 
263
 
 
264
        return attachment->priv->mtime;
 
265
}
 
266
 
 
267
GTime
 
268
ev_attachment_get_creation_date (EvAttachment *attachment)
 
269
{
 
270
        g_return_val_if_fail (EV_IS_ATTACHMENT (attachment), 0);
 
271
 
 
272
        return attachment->priv->ctime;
 
273
}
 
274
 
 
275
const gchar *
 
276
ev_attachment_get_mime_type (EvAttachment *attachment)
 
277
{
 
278
        g_return_val_if_fail (EV_IS_ATTACHMENT (attachment), NULL);
 
279
 
 
280
        return attachment->priv->mime_type;
 
281
}
 
282
 
 
283
gboolean
 
284
ev_attachment_save (EvAttachment *attachment,
 
285
                    const gchar  *uri,
 
286
                    GError      **error)
 
287
{
 
288
        GnomeVFSHandle  *handle = NULL;
 
289
        GnomeVFSFileSize written;
 
290
        GnomeVFSResult   result;
 
291
        
 
292
        g_return_val_if_fail (EV_IS_ATTACHMENT (attachment), FALSE);
 
293
        g_return_val_if_fail (uri != NULL, FALSE);
 
294
 
 
295
        result = gnome_vfs_create (&handle, uri,
 
296
                                   GNOME_VFS_OPEN_WRITE |
 
297
                                   GNOME_VFS_OPEN_TRUNCATE,
 
298
                                   FALSE, 0644);
 
299
        if (result != GNOME_VFS_OK) {
 
300
                g_set_error (error,
 
301
                             EV_ATTACHMENT_ERROR, 
 
302
                             (gint) result,
 
303
                             _("Couldn't save attachment '%s': %s"),
 
304
                             uri, 
 
305
                             gnome_vfs_result_to_string (result));
 
306
                
 
307
                return FALSE;
 
308
        }
 
309
 
 
310
        result = gnome_vfs_write (handle, attachment->priv->data,
 
311
                                  attachment->priv->size, &written);
 
312
        if (result != GNOME_VFS_OK || written < attachment->priv->size){
 
313
                g_set_error (error,
 
314
                             EV_ATTACHMENT_ERROR,
 
315
                             (gint) result,
 
316
                             _("Couldn't save attachment '%s': %s"),
 
317
                             uri,
 
318
                             gnome_vfs_result_to_string (result));
 
319
                
 
320
                gnome_vfs_close (handle);
 
321
 
 
322
                return FALSE;
 
323
        }
 
324
 
 
325
        gnome_vfs_close (handle);
 
326
 
 
327
        return TRUE;
 
328
}
 
329
 
 
330
static gboolean
 
331
ev_attachment_launch_app (EvAttachment *attachment,
 
332
                          GError      **error)
 
333
{
 
334
        GnomeVFSResult result;
 
335
        GList         *uris = NULL;
 
336
 
 
337
        g_assert (attachment->priv->tmp_uri != NULL);
 
338
        g_assert (attachment->priv->app != NULL);
 
339
 
 
340
        uris = g_list_prepend (uris, attachment->priv->tmp_uri);
 
341
        result = gnome_vfs_mime_application_launch (attachment->priv->app,
 
342
                                                    uris);
 
343
 
 
344
        if (result != GNOME_VFS_OK) {
 
345
                g_set_error (error,
 
346
                             EV_ATTACHMENT_ERROR,
 
347
                             (gint) result,
 
348
                             _("Couldn't open attachment '%s': %s"),
 
349
                             attachment->priv->name,
 
350
                             gnome_vfs_result_to_string (result));
 
351
 
 
352
                g_list_free (uris);
 
353
                
 
354
                return FALSE;
 
355
        }
 
356
 
 
357
        g_list_free (uris);
 
358
        
 
359
        return TRUE;
 
360
}
 
361
 
 
362
gboolean
 
363
ev_attachment_open (EvAttachment *attachment,
 
364
                    GError      **error)
 
365
{
 
366
 
 
367
        gboolean                 retval = FALSE;
 
368
        GnomeVFSMimeApplication *default_app = NULL;
 
369
 
 
370
        g_return_val_if_fail (EV_IS_ATTACHMENT (attachment), FALSE);
 
371
        
 
372
        if (!attachment->priv->app) {
 
373
                default_app = gnome_vfs_mime_get_default_application (attachment->priv->mime_type);
 
374
                attachment->priv->app = default_app;
 
375
        }
 
376
 
 
377
        if (!attachment->priv->app) {
 
378
                g_set_error (error,
 
379
                             EV_ATTACHMENT_ERROR,
 
380
                             0,
 
381
                             _("Couldn't open attachment '%s'"),
 
382
                             attachment->priv->name);
 
383
                
 
384
                return FALSE;
 
385
        }
 
386
 
 
387
        if (attachment->priv->tmp_uri &&
 
388
            g_file_test (attachment->priv->tmp_uri, G_FILE_TEST_EXISTS)) {
 
389
                retval = ev_attachment_launch_app (attachment, error);
 
390
        } else {
 
391
                gchar *uri, *filename;
 
392
                
 
393
                filename = g_build_filename (g_get_tmp_dir (), attachment->priv->name, NULL);
 
394
                uri = g_filename_to_uri (filename, NULL, NULL);
 
395
 
 
396
                if (ev_attachment_save (attachment, uri, error)) {
 
397
                        if (attachment->priv->tmp_uri)
 
398
                                g_free (attachment->priv->tmp_uri);
 
399
                        attachment->priv->tmp_uri = g_strdup (filename);
 
400
 
 
401
                        retval = ev_attachment_launch_app (attachment, error);
 
402
                }
 
403
 
 
404
                g_free (filename);
 
405
                g_free (uri);
 
406
        }
 
407
 
 
408
        return retval;
 
409
}