root/trunk/libtinymailui-gtk/tny-gtk-mime-part-save-strategy.c

Revision 3666 (checked in by jdapena, 7 months ago)

* Use GOnce registering all types in tinymail to make

registering thread-safe.

Line 
1 /* libtinymailui-gtk - The Tiny Mail UI library for Gtk+
2  * Copyright (C) 2006-2007 Philip Van Hoof <pvanhoof@gnome.org>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with self library; if not, write to the
16  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19
20 /**
21  * TnyGtkMimePartSaveStrategy:
22  *
23  * a #TnyMimePartSaveStrategy that saves a #TnyMimePart using a file dialog
24  * in Gtk+ and GnomeVFS if available.
25  *
26  * free-function: g_object_unref
27  **/
28
29 #include <config.h>
30
31 #include <glib/gi18n-lib.h>
32
33 #include <unistd.h>
34 #include <fcntl.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <sys/stat.h>
38 #include <sys/types.h>
39
40 #include <string.h>
41 #include <gtk/gtk.h>
42 #include <tny-gtk-mime-part-save-strategy.h>
43 #include <tny-gtk-text-buffer-stream.h>
44 #include <tny-gtk-attach-list-model.h>
45
46 #include <tny-mime-part.h>
47
48 #ifdef GNOME
49 #include <tny-vfs-stream.h>
50 #include <libgnomevfs/gnome-vfs.h>
51 #include <libgnomevfs/gnome-vfs-utils.h>
52 #else
53 #include <tny-fs-stream.h>
54 #endif
55
56 static GObjectClass *parent_class = NULL;
57
58 typedef struct _TnyGtkMimePartSaveStrategyPriv TnyGtkMimePartSaveStrategyPriv;
59
60 struct _TnyGtkMimePartSaveStrategyPriv
61 {
62         TnyStatusCallback status_callback;
63         gpointer status_user_data;
64 };
65
66 #define TNY_GTK_MIME_PART_SAVE_STRATEGY_GET_PRIVATE(o) \
67         (G_TYPE_INSTANCE_GET_PRIVATE ((o), TNY_TYPE_GTK_MIME_PART_SAVE_STRATEGY, TnyGtkMimePartSaveStrategyPriv))
68
69
70 #ifdef GNOME
71
72 static gboolean
73 gtk_save_to_file (const gchar *uri, TnyMimePart *part, TnyMimePartSaveStrategy *self)
74 {
75         TnyGtkMimePartSaveStrategyPriv *priv = TNY_GTK_MIME_PART_SAVE_STRATEGY_GET_PRIVATE (self);
76         GnomeVFSResult result;
77         GnomeVFSHandle *handle;
78         TnyStream *stream = NULL;
79
80         result = gnome_vfs_create (&handle, uri,
81                 GNOME_VFS_OPEN_WRITE, FALSE, 0777);
82
83         if (G_UNLIKELY (result != GNOME_VFS_OK))
84                 return FALSE;
85
86         stream = tny_vfs_stream_new (handle);
87         tny_mime_part_decode_to_stream_async (part, stream, NULL,
88                 priv->status_callback, priv->status_user_data);
89
90         /* This also closes the handle */   
91         g_object_unref (stream);
92
93         return TRUE;
94 }
95 #else
96 static gboolean
97 gtk_save_to_file (const gchar *local_filename, TnyMimePart *part, TnyMimePartSaveStrategy *self)
98 {
99         TnyGtkMimePartSaveStrategyPriv *priv = TNY_GTK_MIME_PART_SAVE_STRATEGY_GET_PRIVATE (self);
100         int fd = open (local_filename, O_WRONLY | O_CREAT,  S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
101
102         if (fd != -1)
103         {
104                 TnyStream *stream = tny_fs_stream_new (fd);
105                 tny_mime_part_decode_to_stream_async (part, stream, NULL,
106                         priv->status_callback, priv->status_user_data);
107
108                 /* This also closes the file descriptor */
109                 g_object_unref (stream);
110                 return TRUE;
111         }
112
113         return FALSE;
114 }
115 #endif
116
117
118 static void
119 tny_gtk_mime_part_save_strategy_perform_save (TnyMimePartSaveStrategy *self, TnyMimePart *part)
120 {
121         TNY_GTK_MIME_PART_SAVE_STRATEGY_GET_CLASS (self)->perform_save(self, part);
122         return;
123 }
124
125 static void
126 tny_gtk_mime_part_save_strategy_perform_save_default (TnyMimePartSaveStrategy *self, TnyMimePart *part)
127 {
128         GtkFileChooserDialog *dialog;
129         gboolean destr=FALSE;
130
131         g_assert (TNY_IS_MIME_PART (part));
132
133         dialog = GTK_FILE_CHOOSER_DIALOG
134                 (gtk_file_chooser_dialog_new (_("Save File"), NULL,
135                 GTK_FILE_CHOOSER_ACTION_SAVE,
136                 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_SAVE,
137                 GTK_RESPONSE_ACCEPT, NULL));
138
139         /* gtk_file_chooser_set_do_overwrite_confirmation
140                 (GTK_FILE_CHOOSER (dialog), TRUE); */
141
142         gtk_file_chooser_set_current_folder
143                 (GTK_FILE_CHOOSER (dialog), g_get_home_dir ());
144
145 /* TNY TODO: detect this at runtime */
146 #ifndef GNOME
147         gtk_file_chooser_set_local_only (GTK_FILE_CHOOSER (dialog), TRUE);
148 #endif
149
150         gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog),
151                 tny_mime_part_get_filename (part));
152
153         if (G_LIKELY (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT))
154         {
155                 gchar *uri;
156
157 /* TNY TODO: detect this at runtime */
158 #ifdef GNOME
159                 uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (dialog));
160 #else
161                 uri = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
162 #endif
163                 if (uri)
164                 {
165                         if (!gtk_save_to_file (uri, part, self))
166                         {
167                                 GtkWidget *errd;
168
169                                 gtk_widget_destroy (GTK_WIDGET (dialog));
170                                 destr = TRUE;
171                                 errd = gtk_message_dialog_new (NULL,
172                                         GTK_DIALOG_DESTROY_WITH_PARENT,
173                                         GTK_MESSAGE_ERROR,
174                                         GTK_BUTTONS_CLOSE,
175                                         _("Saving to %s failed\n"), uri);
176                                 gtk_dialog_run (GTK_DIALOG (errd));
177                                 gtk_widget_destroy (GTK_WIDGET (errd));
178                         }
179
180                         g_free (uri);
181                 }
182         }
183
184         if (!destr)
185                 gtk_widget_destroy (GTK_WIDGET (dialog));
186
187         return;
188 }
189
190
191 /**
192  * tny_gtk_mime_part_save_strategy_new:
193  * @status_callback: (null-ok): a #TnyStatusCallback for when status information happens or NULL
194  * @status_user_data: (null-ok): user data for @status_callback
195  *
196  * Create a new #TnyMimePartSaveStrategy It will use the #GtkFileChooserDialog type and if
197  * available consume its support for GnomeVFS.
198  *
199  * Whenever data must be retrieved or takes long to load, @status_callback will
200  * be called to let the outside world know about what this compenent is doing.
201  *
202  * returns: (caller-owns): a new #TnyMimePartSaveStrategy
203  * since: 1.0
204  * audience: application-developer
205  **/
206 TnyMimePartSaveStrategy*
207 tny_gtk_mime_part_save_strategy_new (TnyStatusCallback status_callback, gpointer status_user_data)
208 {
209         TnyGtkMimePartSaveStrategy *self = g_object_new (TNY_TYPE_GTK_MIME_PART_SAVE_STRATEGY, NULL);
210         TnyGtkMimePartSaveStrategyPriv *priv= TNY_GTK_MIME_PART_SAVE_STRATEGY_GET_PRIVATE (self);
211
212         priv->status_callback = status_callback;
213         priv->status_user_data = status_user_data;
214
215         return TNY_MIME_PART_SAVE_STRATEGY (self);
216 }
217
218 static void
219 tny_gtk_mime_part_save_strategy_instance_init (GTypeInstance *instance, gpointer g_class)
220 {
221         TnyGtkMimePartSaveStrategyPriv *priv = TNY_GTK_MIME_PART_SAVE_STRATEGY_GET_PRIVATE (instance);
222
223         priv->status_callback = NULL;
224         priv->status_user_data = NULL;
225
226         return;
227 }
228
229 static void
230 tny_gtk_mime_part_save_strategy_finalize (GObject *object)
231 {
232         (*parent_class->finalize) (object);
233
234         return;
235 }
236
237 static void
238 tny_gtk_mime_part_save_strategy_init (gpointer g, gpointer iface_data)
239 {
240         TnyMimePartSaveStrategyIface *klass = (TnyMimePartSaveStrategyIface *)g;
241
242         klass->perform_save= tny_gtk_mime_part_save_strategy_perform_save;
243
244         return;
245 }
246
247 static void
248 tny_gtk_mime_part_save_strategy_class_init (TnyGtkMimePartSaveStrategyClass *class)
249 {
250         GObjectClass *object_class;
251
252         parent_class = g_type_class_peek_parent (class);
253         object_class = (GObjectClass*) class;
254
255         class->perform_save= tny_gtk_mime_part_save_strategy_perform_save_default;
256
257         object_class->finalize = tny_gtk_mime_part_save_strategy_finalize;
258
259         g_type_class_add_private (object_class, sizeof (TnyGtkMimePartSaveStrategyPriv));
260
261         return;
262 }
263
264 static gpointer
265 tny_gtk_mime_part_save_strategy_register_type (gpointer notused)
266 {
267         GType type = 0;
268
269         static const GTypeInfo info =
270                 {
271                   sizeof (TnyGtkMimePartSaveStrategyClass),
272                   NULL,   /* base_init */
273                   NULL,   /* base_finalize */
274                   (GClassInitFunc) tny_gtk_mime_part_save_strategy_class_init,   /* class_init */
275                   NULL,   /* class_finalize */
276                   NULL,   /* class_data */
277                   sizeof (TnyGtkMimePartSaveStrategy),
278                   0,      /* n_preallocs */
279                   tny_gtk_mime_part_save_strategy_instance_init,    /* instance_init */
280                   NULL
281                 };
282
283         static const GInterfaceInfo tny_gtk_mime_part_save_strategy_info =
284                 {
285                   (GInterfaceInitFunc) tny_gtk_mime_part_save_strategy_init, /* interface_init */
286                   NULL,         /* interface_finalize */
287                   NULL          /* interface_data */
288                 };
289
290         type = g_type_register_static (G_TYPE_OBJECT,
291                                        "TnyGtkMimePartSaveStrategy",
292                                        &info, 0);
293
294         g_type_add_interface_static (type, TNY_TYPE_MIME_PART_SAVE_STRATEGY,
295                                      &tny_gtk_mime_part_save_strategy_info);
296
297         return GUINT_TO_POINTER (type);
298 }
299
300 GType
301 tny_gtk_mime_part_save_strategy_get_type (void)
302 {
303         static GOnce once = G_ONCE_INIT;
304         g_once (&once, tny_gtk_mime_part_save_strategy_register_type, NULL);
305         return GPOINTER_TO_UINT (once.retval);
306 }
Note: See TracBrowser for help on using the browser.