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