From e9a0cfe1a901f41456575a2cd07158f1947b873c Mon Sep 17 00:00:00 2001 From: Milan Crha Date: Thu, 17 Apr 2008 16:59:08 +0000 Subject: ** Fix for bug #526741 (gnome-vfs to gio/gvfs port) 2008-04-17 Milan Crha ** Fix for bug #526741 (gnome-vfs to gio/gvfs port) * configure.in: Drop dependency on gnome-vfs, depend on gio instead. * addressbook/gui/contact-editor/e-contact-editor.c: Do not include gnome-vfs. * calendar/gui/e-meeting-store.c: (start_async_read), (freebusy_async), (async_read): Read data with gio, not with gnome-vfs. * calendar/gui/e-meeting-store.c: (async_close): Function removed. * calendar/gui/migration.c: * calendar/gui/e-memos.c: * calendar/gui/alarm-notify/notify-main.c: * calendar/gui/e-tasks.c: * calendar/gui/main.c: * calendar/gui/e-meeting-list-view.c: Do not include gnome-vfs. * calendar/gui/dialogs/comp-editor.c: (set_attachment_list): * calendar/gui/dialogs/comp-editor.c: (attachment_guess_mime_type): Function removed, use e-util function instead. * calendar/gui/e-cal-popup.c: (temp_save_part): Reflect changes in CamelStreamVFS. * calendar/gui/e-cal-popup.c: (ecalp_apps_open_in), (ecalp_apps_popup_free), (ecalp_standard_menu_factory): Use gio to fill popup and launch app. * calendar/gui/e-cal-component-preview.h: (e_cal_comp_preview_url_requested_cb): * calendar/gui/e-cal-component-preview.c: (e_cal_comp_preview_url_requested_cb): New helper function to manage file:// urls for GtkHTML component. * calendar/gui/e-cal-component-preview.c: (e_cal_component_preview_init): * calendar/gui/e-cal-component-memo-preview.c: (e_cal_comp_preview_url_requested_cb): Use above helper function. * calendar/gui/e-cal-component-memo-preview.c: (url_requested_cb): * calendar/gui/e-cal-component-preview.c: (url_requested_cb): Function removed. * composer/e-msg-composer.h: (e_msg_composer_guess_mime_type): * composer/e-msg-composer.c: (e_msg_composer_guess_mime_type), (handle_uri), (e_msg_composer_add_inline_image_from_file): Use shared e_util_guess_mime_type instead of its own. * e-util/e-gui-utils.c: Do not include gnome-vfs. * e-util/e-util.c: (e_write_file_uri), (e_file_get_save_path): * e-util/e-dialog-utils.c: (e_file_can_save), (e_file_check_local): Use gio instead of gnome-vfs. * e-util/e-util.h: * e-util/e-util.c: (e_util_guess_mime_type), (e_util_filename_to_uri), (e_util_uri_to_filename), (e_util_read_file): New helper functions. * mail/Makefile.am: * mail/em-vfs-stream.h: * mail/em-vfs-stream.c: Removed from project, not used anywhere. * mail/em-menu.c: * mail/em-config.c: Do not include gnome-vfs. * mail/mail-ops.c: (save_messages_exec), (save_part_exec): Changes related to Data Server change of CamelStreamVFS. * mail/em-format.c: (em_format_describe_part): * mail/em-format-html-display.c: (efhd_bonobo_object), (efhd_find_handler), (efhd_use_component), (efhd_bonobo_unknown), (efhd_check_server_prop), (efhd_format_attachment): Drop use of deprecated gnome-vfs functions. * mail/em-utils.c: (em_utils_snoop_type): Use gio to guess the mime_type. * mail/em-popup.c: (emp_apps_open_in), (emp_apps_popup_free), (emp_standard_menu_factory): Use gio to fill popup and launch app. * plugins/import-ics-attachments/icsimporter.c: Do not include gnome-vfs. * plugins/ipod-sync/ical-format.c: (do_save_calendar_ical): * plugins/ipod-sync/ipod-sync.c: (destination_save_addressbook): Write to gio GOutputStream instead of gnome-vfs handle. * plugins/ipod-sync/format-handler.h: (open_for_writing): * plugins/ipod-sync/ipod-sync.c: (open_for_writing): New helper function. * plugins/publish-calendar/publish-format-fb.h: (publish_calendar_as_fb): * plugins/publish-calendar/publish-format-fb.c: (write_calendar), (publish_calendar_as_fb): * plugins/publish-calendar/publish-format-ical.h: (publish_calendar_as_ical): * plugins/publish-calendar/publish-format-ical.c: (write_calendar), (publish_calendar_as_ical): Use gio GOutputStream instead of gnome-vfs handle. * plugins/publish-calendar/url-editor-dialog.c: (create_uri): Use glib function to escape URI. * plugins/publish-calendar/publish-location.c: (migrateURI): Use EUri to parse URI. * plugins/publish-calendar/publish-calendar.c: (publish_online), (unmount_done_cb), (struct mnt_struct), (mount_ready_cb), (ask_password), (ask_question), (mount_first), (publish): Use gio instead of gnome-vfs for opening (remote) files. * plugins/save-calendar/ical-format.c: (do_save_calendar_ical): * plugins/save-calendar/csv-format.c: (do_save_calendar_csv): * plugins/save-calendar/rdf-format.c: (do_save_calendar_rdf): Use gio GOutpuStream instead of gnome-vfs handle. * plugins/save-calendar/format-handler.h: (open_for_writing): * plugins/save-calendar/save-calendar.c: (open_for_writing): New helper function. * shell/e-shell-window-commands.c: (command_quick_reference): Use gio instead of gnome-vfs. * widgets/misc/e-attachment.h: (struct _EAttachment): * widgets/misc/e-attachment.c: (finalise), (init), (attachment_guess_mime_type), (e_attachment_new), (struct DownloadInfo), (download_info_free), (data_ready_cb), (download_to_local_path), (e_attachment_new_remote_file): Use gio instead of gnome-vfs to download remote files. * widgets/misc/e-image-chooser.c: (image_drag_data_received_cb): Use new util function to read file. * widgets/misc/e-attachment-bar.c: (size_to_string): Stolen from gnome-vfs. svn path=/trunk/; revision=35378 --- ChangeLog | 6 + addressbook/ChangeLog | 6 + addressbook/gui/contact-editor/e-contact-editor.c | 1 - calendar/ChangeLog | 31 ++ calendar/gui/alarm-notify/notify-main.c | 1 - calendar/gui/dialogs/comp-editor.c | 24 +- calendar/gui/e-cal-component-memo-preview.c | 30 +- calendar/gui/e-cal-component-preview.c | 51 ++-- calendar/gui/e-cal-component-preview.h | 6 + calendar/gui/e-cal-popup.c | 89 ++++-- calendar/gui/e-meeting-list-view.c | 1 - calendar/gui/e-meeting-store.c | 93 +++--- calendar/gui/e-memos.c | 1 - calendar/gui/e-tasks.c | 1 - calendar/gui/main.c | 1 - calendar/gui/migration.c | 2 - composer/ChangeLog | 9 + composer/e-msg-composer.c | 34 +-- composer/e-msg-composer.h | 1 - configure.in | 14 +- e-util/ChangeLog | 12 + e-util/e-dialog-utils.c | 6 +- e-util/e-gui-utils.c | 1 - e-util/e-util.c | 233 ++++++++++++++- e-util/e-util.h | 6 + mail/ChangeLog | 19 ++ mail/Makefile.am | 2 - mail/em-config.c | 1 - mail/em-format-html-display.c | 186 +----------- mail/em-format.c | 12 +- mail/em-menu.c | 1 - mail/em-popup.c | 75 +++-- mail/em-utils.c | 53 +++- mail/em-vfs-stream.c | 330 ---------------------- mail/em-vfs-stream.h | 60 ---- mail/mail-ops.c | 33 ++- plugins/import-ics-attachments/ChangeLog | 6 + plugins/import-ics-attachments/icsimporter.c | 4 - plugins/ipod-sync/ChangeLog | 10 + plugins/ipod-sync/format-handler.h | 3 + plugins/ipod-sync/ical-format.c | 36 +-- plugins/ipod-sync/ipod-sync.c | 117 +++++--- plugins/publish-calendar/ChangeLog | 16 ++ plugins/publish-calendar/publish-calendar.c | 285 +++++++++++++++---- plugins/publish-calendar/publish-format-fb.c | 41 ++- plugins/publish-calendar/publish-format-fb.h | 4 +- plugins/publish-calendar/publish-format-ical.c | 37 ++- plugins/publish-calendar/publish-format-ical.h | 4 +- plugins/publish-calendar/publish-location.c | 20 +- plugins/publish-calendar/url-editor-dialog.c | 4 +- plugins/save-calendar/ChangeLog | 11 + plugins/save-calendar/csv-format.c | 38 +-- plugins/save-calendar/format-handler.h | 3 + plugins/save-calendar/ical-format.c | 51 +--- plugins/save-calendar/rdf-format.c | 38 +-- plugins/save-calendar/save-calendar.c | 51 +++- shell/ChangeLog | 7 + shell/e-shell-window-commands.c | 24 +- widgets/misc/ChangeLog | 14 + widgets/misc/e-attachment-bar.c | 31 +- widgets/misc/e-attachment.c | 303 ++++++++++++-------- widgets/misc/e-attachment.h | 5 +- widgets/misc/e-image-chooser.c | 40 +-- 63 files changed, 1374 insertions(+), 1261 deletions(-) delete mode 100644 mail/em-vfs-stream.c delete mode 100644 mail/em-vfs-stream.h diff --git a/ChangeLog b/ChangeLog index ea48fbb0f8..1ebe3c4bbb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2008-04-17 Milan Crha + + ** Part of fix for bug #526739 + + * configure.in: Drop dependency on gnome-vfs, depend on gio instead. + 2008-04-11 Suman Manjunath * configure.in: Bump glib package requirement: glib-2.0 >= 2.16.0 diff --git a/addressbook/ChangeLog b/addressbook/ChangeLog index eb6a638120..f84103fe87 100644 --- a/addressbook/ChangeLog +++ b/addressbook/ChangeLog @@ -1,3 +1,9 @@ +2008-04-17 Milan Crha + + ** Part of fix for bug #526739 + + * gui/contact-editor/e-contact-editor.c: Do not include gnome-vfs. + 2008-04-02 Matthew Barnes * gui/widgets/Makefile.am: diff --git a/addressbook/gui/contact-editor/e-contact-editor.c b/addressbook/gui/contact-editor/e-contact-editor.c index 6b033015a7..ab96508435 100644 --- a/addressbook/gui/contact-editor/e-contact-editor.c +++ b/addressbook/gui/contact-editor/e-contact-editor.c @@ -62,7 +62,6 @@ #include "e-util/e-util-private.h" #include "eab-contact-merging.h" -#include #include "e-contact-editor-address.h" #include "e-contact-editor-im.h" diff --git a/calendar/ChangeLog b/calendar/ChangeLog index 59bfb8a5df..98618e0bbf 100644 --- a/calendar/ChangeLog +++ b/calendar/ChangeLog @@ -1,3 +1,34 @@ +2008-04-17 Milan Crha + + ** Part of fix for bug #526739 + + * gui/e-meeting-store.c: (start_async_read), (freebusy_async), + (async_read): Read data with gio, not with gnome-vfs. + * gui/e-meeting-store.c: (async_close): Function removed. + * gui/migration.c: + * gui/e-memos.c: + * gui/alarm-notify/notify-main.c: + * gui/e-tasks.c: + * gui/main.c: + * gui/e-meeting-list-view.c: + Do not include gnome-vfs. + * gui/dialogs/comp-editor.c: (set_attachment_list): + * gui/dialogs/comp-editor.c: (attachment_guess_mime_type): + Function removed, use e-util function instead. + * gui/e-cal-popup.c: (temp_save_part): + Reflect changes in CamelStreamVFS. + * gui/e-cal-popup.c: (ecalp_apps_open_in), (ecalp_apps_popup_free), + (ecalp_standard_menu_factory): Use gio to fill popup and launch app. + * gui/e-cal-component-preview.h: (e_cal_comp_preview_url_requested_cb): + * gui/e-cal-component-preview.c: (e_cal_comp_preview_url_requested_cb): + New helper function to manage file:// urls for GtkHTML component. + * gui/e-cal-component-preview.c: (e_cal_component_preview_init): + * gui/e-cal-component-memo-preview.c: + (e_cal_comp_preview_url_requested_cb): + Use above helper function. + * gui/e-cal-component-memo-preview.c: (url_requested_cb): + * gui/e-cal-component-preview.c: (url_requested_cb): Function removed. + 2008-04-17 Milan Crha ** Fix for bug #523402 diff --git a/calendar/gui/alarm-notify/notify-main.c b/calendar/gui/alarm-notify/notify-main.c index 83c2421d38..b68f28c568 100644 --- a/calendar/gui/alarm-notify/notify-main.c +++ b/calendar/gui/alarm-notify/notify-main.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include #include diff --git a/calendar/gui/dialogs/comp-editor.c b/calendar/gui/dialogs/comp-editor.c index f1308365cf..201a321a87 100644 --- a/calendar/gui/dialogs/comp-editor.c +++ b/calendar/gui/dialogs/comp-editor.c @@ -35,8 +35,6 @@ #include #include #include -#include -#include #include #include #include @@ -2366,26 +2364,6 @@ set_icon_from_comp (CompEditor *editor) } } -static char * -attachment_guess_mime_type (const char *file_name) -{ - GnomeVFSFileInfo *info; - GnomeVFSResult result; - char *type = NULL; - - info = gnome_vfs_file_info_new (); - result = gnome_vfs_get_file_info (file_name, info, - GNOME_VFS_FILE_INFO_GET_MIME_TYPE | - GNOME_VFS_FILE_INFO_FORCE_SLOW_MIME_TYPE | - GNOME_VFS_FILE_INFO_FOLLOW_LINKS); - if (result == GNOME_VFS_OK) - type = g_strdup (gnome_vfs_file_info_get_mime_type (info)); - - gnome_vfs_file_info_unref (info); - - return type; -} - static void set_attachment_list (CompEditor *editor, GSList *attach_list) { @@ -2441,7 +2419,7 @@ set_attachment_list (CompEditor *editor, GSList *attach_list) return; } - mime_type = attachment_guess_mime_type (file_name); + mime_type = e_util_guess_mime_type (file_name); if (mime_type) { if (!g_ascii_strcasecmp (mime_type, "message/rfc822")) { wrapper = (CamelDataWrapper *) camel_mime_message_new (); diff --git a/calendar/gui/e-cal-component-memo-preview.c b/calendar/gui/e-cal-component-memo-preview.c index dd5131eb92..90eeae71a7 100644 --- a/calendar/gui/e-cal-component-memo-preview.c +++ b/calendar/gui/e-cal-component-memo-preview.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include @@ -40,6 +39,7 @@ #include #include "calendar-config.h" #include "e-cal-component-memo-preview.h" +#include "e-cal-component-preview.h" struct _ECalComponentMemoPreviewPrivate { GtkWidget *html; @@ -79,32 +79,6 @@ on_url_cb (GtkHTML *html, const char *url, gpointer data) #endif } -/* Callback used when the user selects a URL in the HTML widget */ -static void -url_requested_cb (GtkHTML *html, const char *url, GtkHTMLStream *stream, gpointer data) -{ - if (!strncmp ("file:///", url, strlen ("file:///"))) { - GnomeVFSHandle *handle; - GnomeVFSResult result; - char buffer[4096]; - - if (gnome_vfs_open (&handle, url, GNOME_VFS_OPEN_READ) == GNOME_VFS_OK) { - do { - GnomeVFSFileSize bread; - - result = gnome_vfs_read (handle, buffer, sizeof (buffer), &bread); - if (result == GNOME_VFS_OK) - gtk_html_stream_write (stream, buffer, bread); - } while (result == GNOME_VFS_OK); - - gnome_vfs_close (handle); - - if (result == GNOME_VFS_ERROR_EOF) - gtk_html_stream_close (stream, GTK_HTML_STREAM_OK); - } - } -} - /* Converts a time_t to a string, relative to the specified timezone */ static char * timet_to_str_with_zone (ECalComponentDateTime *dt, ECal *ecal, icaltimezone *default_zone) @@ -282,7 +256,7 @@ e_cal_component_memo_preview_init (ECalComponentMemoPreview *preview) gtk_html_load_empty (GTK_HTML (priv->html)); g_signal_connect (G_OBJECT (priv->html), "url_requested", - G_CALLBACK (url_requested_cb), NULL); + G_CALLBACK (e_cal_comp_preview_url_requested_cb), NULL); g_signal_connect (G_OBJECT (priv->html), "link_clicked", G_CALLBACK (on_link_clicked), preview); g_signal_connect (G_OBJECT (priv->html), "on_url", diff --git a/calendar/gui/e-cal-component-preview.c b/calendar/gui/e-cal-component-preview.c index a73c10ef66..2ee0ca336f 100644 --- a/calendar/gui/e-cal-component-preview.c +++ b/calendar/gui/e-cal-component-preview.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include @@ -78,27 +77,43 @@ on_url_cb (GtkHTML *html, const char *url, gpointer data) } /* Callback used when the user selects a URL in the HTML widget */ -static void -url_requested_cb (GtkHTML *html, const char *url, GtkHTMLStream *stream, gpointer data) +void +e_cal_comp_preview_url_requested_cb (GtkHTML *html, const char *url, GtkHTMLStream *html_stream, gpointer data) { - if (!strncmp ("file:///", url, strlen ("file:///"))) { - GnomeVFSHandle *handle; - GnomeVFSResult result; - char buffer[4096]; + int len = strlen ("file:///"); + + if (!strncmp ("file:///", url, len)) { + GFile *file; + const char *path = url + len - 1; + + g_return_if_fail (html_stream != NULL); + g_return_if_fail (path != NULL); - if (gnome_vfs_open (&handle, url, GNOME_VFS_OPEN_READ) == GNOME_VFS_OK) { - do { - GnomeVFSFileSize bread; + file = g_file_new_for_path (path); + if (file) { + char buffer[4096]; + GInputStream *stream; - result = gnome_vfs_read (handle, buffer, sizeof (buffer), &bread); - if (result == GNOME_VFS_OK) - gtk_html_stream_write (stream, buffer, bread); - } while (result == GNOME_VFS_OK); + /* ignore errors here */ + stream = G_INPUT_STREAM (g_file_read (file, NULL, NULL)); - gnome_vfs_close (handle); + if (stream) { + gssize bread; + + do { + /* ignore errors here as well */ + bread = g_input_stream_read (stream, buffer, sizeof (buffer), NULL, NULL); + if (bread > 0) + gtk_html_stream_write (html_stream, buffer, bread); + } while (bread > 0); + + g_input_stream_close (stream, NULL, NULL); + g_object_unref (stream); + + gtk_html_stream_close (html_stream, GTK_HTML_STREAM_OK); + } - if (result == GNOME_VFS_ERROR_EOF) - gtk_html_stream_close (stream, GTK_HTML_STREAM_OK); + g_object_unref (file); } } } @@ -328,7 +343,7 @@ e_cal_component_preview_init (ECalComponentPreview *preview) gtk_html_load_empty (GTK_HTML (priv->html)); g_signal_connect (G_OBJECT (priv->html), "url_requested", - G_CALLBACK (url_requested_cb), NULL); + G_CALLBACK (e_cal_comp_preview_url_requested_cb), NULL); g_signal_connect (G_OBJECT (priv->html), "link_clicked", G_CALLBACK (on_link_clicked), preview); g_signal_connect (G_OBJECT (priv->html), "on_url", diff --git a/calendar/gui/e-cal-component-preview.h b/calendar/gui/e-cal-component-preview.h index 93b16cb7c0..1bfb0c2f2e 100644 --- a/calendar/gui/e-cal-component-preview.h +++ b/calendar/gui/e-cal-component-preview.h @@ -26,6 +26,8 @@ #include #include +#include +#include #define E_TYPE_CAL_COMPONENT_PREVIEW (e_cal_component_preview_get_type ()) #define E_CAL_COMPONENT_PREVIEW(obj) (GTK_CHECK_CAST ((obj), E_TYPE_CAL_COMPONENT_PREVIEW, ECalComponentPreview)) @@ -62,4 +64,8 @@ void e_cal_component_preview_set_default_timezone (ECalComponentPreview *preview void e_cal_component_preview_display (ECalComponentPreview *preview, ECal *ecal, ECalComponent *comp); void e_cal_component_preview_clear (ECalComponentPreview *preview); +/* Callback used when GtkHTML widget requests URL */ +void e_cal_comp_preview_url_requested_cb (GtkHTML *html, const char *url, GtkHTMLStream *html_stream, gpointer data); + + #endif /* _E_CAL_COMPONENT_PREVIEW_H_ */ diff --git a/calendar/gui/e-cal-popup.c b/calendar/gui/e-cal-popup.c index caa69f015a..050cf0df89 100644 --- a/calendar/gui/e-cal-popup.c +++ b/calendar/gui/e-cal-popup.c @@ -28,9 +28,7 @@ #include #include - -#include -#include +#include #include "e-cal-popup.h" #include @@ -91,7 +89,7 @@ static char * temp_save_part(CamelMimePart *part, char *path, gboolean file) { const char *filename; - char *tmpdir, *utf8_mfilename = NULL, *mfilename = NULL; + char *tmpdir, *utf8_mfilename = NULL, *mfilename = NULL, *usepath; CamelStream *stream; CamelDataWrapper *wrapper; @@ -134,8 +132,16 @@ temp_save_part(CamelMimePart *part, char *path, gboolean file) g_free(mfilename); } + if (strstr (path, "://")) + usepath = path; + else + usepath = g_strjoin (NULL, "file://", path, NULL); + wrapper = camel_medium_get_content_object (CAMEL_MEDIUM (part)); - stream = camel_stream_vfs_new_with_uri (path, O_WRONLY|O_CREAT|O_TRUNC, 0600); + stream = camel_stream_vfs_new_with_uri (path, CAMEL_STREAM_VFS_CREATE); + + if (usepath != path) + g_free (usepath); if (!stream) { /* TODO handle error conditions */ @@ -293,18 +299,33 @@ ecalp_apps_open_in(EPopup *ep, EPopupItem *item, void *data) path = temp_save_part(part, NULL, FALSE); if (path) { - GnomeVFSMimeApplication *app = item->user_data; - char *uri; + GAppInfo *app = item->user_data; GList *uris = NULL; + GError *error = NULL; + + if (g_app_info_supports_files (app)) { + GFile *file = g_file_new_for_path (path); - uri = gnome_vfs_get_uri_from_local_path(path); - uris = g_list_append(uris, uri); + uris = g_list_append (uris, file); + g_app_info_launch (app, uris, NULL, &error); + g_object_unref (file); + } else { + char *uri; - gnome_vfs_mime_application_launch(app, uris); + uri = e_util_filename_to_uri (path); + uris = g_list_append (uris, uri); - g_free(uri); - g_list_free(uris); - g_free(path); + g_app_info_launch_uris (app, uris, NULL, &error); + g_free (uri); + } + + if (error) { + g_warning ("%s", error->message); + g_error_free (error); + } + + g_list_free (uris); + g_free (path); } } @@ -315,6 +336,9 @@ ecalp_apps_popup_free(EPopup *ep, GSList *free_list, void *data) GSList *n = free_list->next; EPopupItem *item = free_list->data; + if (item->user_data && item->activate == ecalp_apps_open_in) + g_object_unref (item->user_data); + g_free(item->path); g_free(item->label); g_free(item); @@ -366,19 +390,29 @@ ecalp_standard_menu_factory (EPopup *ecalp, void *data) } if (mime_type) { - apps = gnome_vfs_mime_get_all_applications(mime_type); + gchar *cp; - if (apps == NULL && strcmp(mime_type, "application/octet-stream") == 0) { - const char *name_type; + /* does gvfs expect lowercase MIME types? */ + for (cp = mime_type; *cp != '\0'; cp++) + *cp = g_ascii_tolower (*cp); + + /* TODO: g_app_info_get_all_for_type expects content_type, not a mime_type, thus it will work fine + on Linux/Unix systems, but not on Win32. They will add hopefully some function to convert between + these two soon. */ + apps = g_app_info_get_all_for_type (mime_type); + if (apps == NULL && strcmp(mime_type, "application/octet-stream") == 0) { if (filename) { - /* GNOME-VFS will misidentify TNEF attachments as MPEG */ + /* will gvfs misidentify TNEF attachments as MPEG? */ if (!strcmp (filename, "winmail.dat")) - name_type = "application/vnd.ms-tnef"; - else - name_type = gnome_vfs_mime_type_from_name(filename); - if (name_type) - apps = gnome_vfs_mime_get_all_applications(name_type); + apps = g_app_info_get_all_for_type ("application/vnd.ms-tnef"); + else { + char *name_type = e_util_guess_mime_type (filename); + + apps = g_app_info_get_all_for_type (name_type); + + g_free (name_type); + } } } g_free (mime_type); @@ -390,16 +424,19 @@ ecalp_standard_menu_factory (EPopup *ecalp, void *data) menus = g_slist_prepend(menus, (void *)&ecalp_standard_part_apps_bar); for (l = apps, i = 0; l; l = l->next, i++) { - GnomeVFSMimeApplication *app = l->data; + GAppInfo *app = l->data; EPopupItem *item; - if (app->requires_terminal) + if (!g_app_info_should_show (app)) { + g_object_unref (app); + l->data = NULL; continue; + } item = g_malloc0(sizeof(*item)); item->type = E_POPUP_ITEM; item->path = g_strdup_printf("99.object.%02d", i); - item->label = g_strdup_printf(_("Open in %s..."), app->name); + item->label = g_strdup_printf(_("Open in %s..."), g_app_info_get_name (app)); item->activate = ecalp_apps_open_in; item->user_data = app; @@ -409,7 +446,7 @@ ecalp_standard_menu_factory (EPopup *ecalp, void *data) if (open_menus) e_popup_add_items(ecalp, open_menus, NULL, ecalp_apps_popup_free, NULL); - g_list_free(apps); + g_list_free (apps); } } diff --git a/calendar/gui/e-meeting-list-view.c b/calendar/gui/e-meeting-list-view.c index 760df5628b..3b18036841 100644 --- a/calendar/gui/e-meeting-list-view.c +++ b/calendar/gui/e-meeting-list-view.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include diff --git a/calendar/gui/e-meeting-store.c b/calendar/gui/e-meeting-store.c index 88b83233e0..cc9498c5b0 100644 --- a/calendar/gui/e-meeting-store.c +++ b/calendar/gui/e-meeting-store.c @@ -28,7 +28,7 @@ #include #include #include -#include +#include #include #include #include @@ -81,8 +81,6 @@ struct _EMeetingStoreQueueData { static GObjectClass *parent_class = NULL; -static void start_async_read (GnomeVFSAsyncHandle *handle, GnomeVFSResult result, gpointer data); - static icalparameter_cutype text_to_type (const char *type) { @@ -1114,6 +1112,8 @@ replace_string (gchar *string, gchar *from_value, gchar *to_value) return replaced; } +static void start_async_read (const char *uri, gpointer data); + typedef struct { ECal *client; time_t startt; @@ -1139,7 +1139,6 @@ freebusy_async (gpointer data) char *fburi = NULL; static GStaticMutex mutex = G_STATIC_MUTEX_INIT; EMeetingStorePrivate *priv = fbd->store->priv; - GnomeVFSAsyncHandle *handle; if (fbd->client) { /* FIXME this a work around for getting all th free busy information for the users @@ -1177,9 +1176,7 @@ freebusy_async (gpointer data) if (fburi) { priv->num_queries++; - gnome_vfs_async_open (&handle, fburi, GNOME_VFS_OPEN_READ, - GNOME_VFS_PRIORITY_DEFAULT, start_async_read, - fbd->qdata); + start_async_read (fburi, fbd->qdata); g_free (fburi); } else if (default_fb_uri != NULL && !g_str_equal (default_fb_uri, "")) { gchar *tmp_fb_uri; @@ -1192,10 +1189,7 @@ freebusy_async (gpointer data) default_fb_uri = replace_string (tmp_fb_uri, DOMAIN_SUB, split_email[1]); priv->num_queries++; - gnome_vfs_async_open (&handle, default_fb_uri, GNOME_VFS_OPEN_READ, - GNOME_VFS_PRIORITY_DEFAULT, start_async_read, - fbd->qdata); - + start_async_read (default_fb_uri, fbd->qdata); g_free (tmp_fb_uri); g_strfreev (split_email); g_free (default_fb_uri); @@ -1375,59 +1369,72 @@ refresh_queue_add (EMeetingStore *store, int row, } static void -async_close (GnomeVFSAsyncHandle *handle, - GnomeVFSResult result, - gpointer data) +async_read (GObject *source_object, GAsyncResult *res, gpointer data) { EMeetingStoreQueueData *qdata = data; + GError *error = NULL; + GInputStream *istream; + gssize read; - process_free_busy (qdata, qdata->string->str); -} + g_return_if_fail (source_object != NULL); + g_return_if_fail (G_IS_INPUT_STREAM (source_object)); -static void -async_read (GnomeVFSAsyncHandle *handle, - GnomeVFSResult result, - gpointer buffer, - GnomeVFSFileSize requested, - GnomeVFSFileSize read, - gpointer data) -{ - EMeetingStoreQueueData *qdata = data; - GnomeVFSFileSize buf_size = BUF_SIZE - 1; + istream = G_INPUT_STREAM (source_object); - if (result != GNOME_VFS_OK && result != GNOME_VFS_ERROR_EOF) { - gnome_vfs_async_close (handle, async_close, qdata); - return; - } + read = g_input_stream_read_finish (istream, res, &error); - ((char *)buffer)[read] = '\0'; - qdata->string = g_string_append (qdata->string, buffer); + if (error || read < 0) { + g_warning ("Read finish failed: %s", error ? error->message : "Unknown error"); + if (error) + g_error_free (error); - if (result == GNOME_VFS_ERROR_EOF) { - gnome_vfs_async_close (handle, async_close, qdata); + g_input_stream_close (istream, NULL, NULL); + g_object_unref (istream); + process_free_busy (qdata, qdata->string->str); return; } - gnome_vfs_async_read (handle, qdata->buffer, buf_size, async_read, qdata); + if (read == 0) { + g_input_stream_close (istream, NULL, NULL); + g_object_unref (istream); + process_free_busy (qdata, qdata->string->str); + } else { + qdata->buffer[read] = '\0'; + qdata->string = g_string_append (qdata->string, qdata->buffer); + + g_input_stream_read_async (istream, qdata->buffer, BUF_SIZE - 1, G_PRIORITY_DEFAULT, NULL, async_read, qdata); + } } static void -start_async_read (GnomeVFSAsyncHandle *handle, - GnomeVFSResult result, - gpointer data) +start_async_read (const char *uri, gpointer data) { EMeetingStoreQueueData *qdata = data; - GnomeVFSFileSize buf_size = BUF_SIZE - 1; + GError *error = NULL; + GFile *file; + GInputStream *istream; + + g_return_if_fail (uri != NULL); + g_return_if_fail (data != NULL); qdata->store->priv->num_queries--; - if (result != GNOME_VFS_OK) { - g_warning ("Unable to access free/busy url: %s", - gnome_vfs_result_to_string (result)); + file = g_file_new_for_uri (uri); + + g_return_if_fail (file != NULL); + + istream = G_INPUT_STREAM (g_file_read (file, NULL, &error)); + + if (error) { + g_warning ("Unable to access free/busy url: %s", error->message); + g_error_free (error); process_callbacks (qdata); return; } - gnome_vfs_async_read (handle, qdata->buffer, buf_size, async_read, qdata); + if (!istream) + process_callbacks (qdata); + else + g_input_stream_read_async (istream, qdata->buffer, BUF_SIZE - 1, G_PRIORITY_DEFAULT, NULL, async_read, qdata); } void diff --git a/calendar/gui/e-memos.c b/calendar/gui/e-memos.c index c62205fff5..08ce5f84c8 100644 --- a/calendar/gui/e-memos.c +++ b/calendar/gui/e-memos.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include diff --git a/calendar/gui/e-tasks.c b/calendar/gui/e-tasks.c index 6167f4a70c..7e55b99d20 100644 --- a/calendar/gui/e-tasks.c +++ b/calendar/gui/e-tasks.c @@ -28,7 +28,6 @@ #include #include -#include #include #include
#include diff --git a/calendar/gui/main.c b/calendar/gui/main.c index 3f15b77c8e..a38ec7fcfb 100644 --- a/calendar/gui/main.c +++ b/calendar/gui/main.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include diff --git a/calendar/gui/migration.c b/calendar/gui/migration.c index 5ac2547d9d..cf670fefb6 100644 --- a/calendar/gui/migration.c +++ b/calendar/gui/migration.c @@ -33,8 +33,6 @@ #include #include -#include -#include #include #include #include diff --git a/composer/ChangeLog b/composer/ChangeLog index 6fa47caa1f..bd6c1a3037 100644 --- a/composer/ChangeLog +++ b/composer/ChangeLog @@ -1,3 +1,12 @@ +2008-04-17 Milan Crha + + ** Part of fix for bug #526739 + + * e-msg-composer.h: (e_msg_composer_guess_mime_type): + * e-msg-composer.c: (e_msg_composer_guess_mime_type), (handle_uri), + (e_msg_composer_add_inline_image_from_file): + Use shared e_util_guess_mime_type instead of its own. + 2008-04-14 Matthew Barnes * e-composer-autosave.c (e_composer_autosave_unregister): diff --git a/composer/e-msg-composer.c b/composer/e-msg-composer.c index ac9f452f07..276db10ce8 100644 --- a/composer/e-msg-composer.c +++ b/composer/e-msg-composer.c @@ -62,7 +62,6 @@ #include #include -#include #include @@ -3948,7 +3947,7 @@ handle_uri (EMsgComposer *composer, return; if (!g_ascii_strcasecmp (url->protocol, "file")) { - type = e_msg_composer_guess_mime_type (uri); + type = e_util_guess_mime_type (uri + strlen ("file://")); if (!type) return; @@ -4180,7 +4179,7 @@ e_msg_composer_add_inline_image_from_file (EMsgComposer *composer, camel_data_wrapper_construct_from_stream (wrapper, stream); camel_object_unref (CAMEL_OBJECT (stream)); - mime_type = e_msg_composer_guess_mime_type (dec_file_name); + mime_type = e_util_guess_mime_type (dec_file_name); if (mime_type == NULL) mime_type = g_strdup ("application/octet-stream"); camel_data_wrapper_set_mime_type (wrapper, mime_type); @@ -4532,35 +4531,6 @@ e_msg_composer_get_reply_to (EMsgComposer *composer) return address; } -/** - * e_msg_composer_guess_mime_type: - * @filename: filename - * - * Returns the guessed mime type of the file given by @filename. - **/ -gchar * -e_msg_composer_guess_mime_type (const gchar *filename) -{ - GnomeVFSFileInfo *info; - GnomeVFSResult result; - gchar *type = NULL; - - g_return_val_if_fail (filename != NULL, NULL); - - info = gnome_vfs_file_info_new (); - result = gnome_vfs_get_file_info ( - filename, info, - GNOME_VFS_FILE_INFO_GET_MIME_TYPE | - GNOME_VFS_FILE_INFO_FORCE_SLOW_MIME_TYPE | - GNOME_VFS_FILE_INFO_FOLLOW_LINKS); - if (result == GNOME_VFS_OK) - type = g_strdup (gnome_vfs_file_info_get_mime_type (info)); - - gnome_vfs_file_info_unref (info); - - return type; -} - /** * e_msg_composer_get_raw_message_text: * diff --git a/composer/e-msg-composer.h b/composer/e-msg-composer.h index 251c170426..54dc906171 100644 --- a/composer/e-msg-composer.h +++ b/composer/e-msg-composer.h @@ -125,7 +125,6 @@ CamelInternetAddress * void e_msg_composer_clear_inlined_table (EMsgComposer *composer); -gchar * e_msg_composer_guess_mime_type (const gchar *filename); void e_msg_composer_set_enable_autosave (EMsgComposer *composer, gboolean enabled); diff --git a/configure.in b/configure.in index 6fe28c1dde..5618e7ca81 100644 --- a/configure.in +++ b/configure.in @@ -15,7 +15,6 @@ m4_define([glib_minimum_version], [2.16.0]) m4_define([gtk_minimum_version], [2.12.0]) m4_define([eds_minimum_version], [2.23.1]) m4_define([gnome_icon_theme_minimum_version], [2.19.91]) -m4_define([gnome_vfs_minimum_version], [2.4.0]) m4_define([libbonobo_minimum_version], [2.20.3]) m4_define([libbonoboui_minimum_version], [2.4.2]) m4_define([libgtkhtml_minimum_version], [3.19.1]) @@ -168,7 +167,6 @@ PKG_CHECK_MODULES(GNOME_PLATFORM, [glib-2.0 >= glib_minimum_version gtk+-2.0 >= gtk_minimum_version gconf-2.0 >= gconf_minimum_version - gnome-vfs-2.0 >= gnome_vfs_minimum_version libbonobo-2.0 >= libbonobo_minimum_version libbonoboui-2.0 >= libbonoboui_minimum_version libglade-2.0 >= libglade_minimum_version @@ -1363,7 +1361,7 @@ AC_SUBST(BONOBOUI_REQUIRED) dnl --- Flags to get all the GNOME stuff -FULL_GNOME_DEPS="libbonoboui-2.0 gnome-vfs-2.0 libgnomeui-2.0 libglade-2.0" +FULL_GNOME_DEPS="libbonoboui-2.0 gconf-2.0 gthread-2.0 gobject-2.0 libgnomeui-2.0 libglade-2.0" CPPFLAGS_save="$CPPFLAGS" CPPFLAGS="$CPPFLAGS `$PKG_CONFIG --cflags-only-I libgnomeui-2.0`" @@ -1453,7 +1451,7 @@ EVO_SET_COMPILE_FLAGS(TZDIALOG, libecal-$EDS_PACKAGE, $GNOME_PLATFORM_CFLAGS, $G AC_SUBST(TZDIALOG_CFLAGS) AC_SUBST(TZDIALOG_LIBS) -EVO_SET_COMPILE_FLAGS(E_WIDGETS, libbonoboui-2.0 gnome-vfs-module-2.0 libgnomeui-2.0 libglade-2.0 libedataserverui-$EDS_PACKAGE libedataserver-$EDS_PACKAGE) +EVO_SET_COMPILE_FLAGS(E_WIDGETS, libbonoboui-2.0 gio-2.0 gconf-2.0 gobject-2.0 libgnomeui-2.0 libglade-2.0 libedataserverui-$EDS_PACKAGE libedataserver-$EDS_PACKAGE) AC_SUBST(E_WIDGETS_CFLAGS) AC_SUBST(E_WIDGETS_LIBS) @@ -1488,14 +1486,14 @@ AM_CONDITIONAL(NM_SUPPORT_GLIB, test x$NM_SUPPORT_GLIB = xyes) AM_CONDITIONAL(NM_SUPPORT, test x$NM_SUPPORT = xyes) -EVO_SET_COMPILE_FLAGS(SHELL, libgnomeui-2.0 libbonoboui-2.0 libglade-2.0 gnome-vfs-2.0 libgtkhtml-$GTKHTML_PACKAGE $NM_SUPPORT_PACKAGES) +EVO_SET_COMPILE_FLAGS(SHELL, libgnomeui-2.0 libbonoboui-2.0 libglade-2.0 gio-2.0 gconf-2.0 gobject-2.0 libgtkhtml-$GTKHTML_PACKAGE $NM_SUPPORT_PACKAGES) AC_SUBST(SHELL_CFLAGS) AC_SUBST(SHELL_LIBS) dnl --- evolution-addressbook flags -EVOLUTION_ADDRESSBOOK_DEPS="libbonoboui-2.0 libglade-2.0 libgnomeui-2.0 gnome-vfs-2.0 libgtkhtml-$GTKHTML_PACKAGE libebook-$EDS_PACKAGE libedataserverui-$EDS_PACKAGE camel-$EDS_PACKAGE gtkhtml-editor" +EVOLUTION_ADDRESSBOOK_DEPS="libbonoboui-2.0 libglade-2.0 libgnomeui-2.0 gio-2.0 gconf-2.0 gobject-2.0 libgtkhtml-$GTKHTML_PACKAGE libebook-$EDS_PACKAGE libedataserverui-$EDS_PACKAGE camel-$EDS_PACKAGE gtkhtml-editor" EVO_SET_COMPILE_FLAGS(EVOLUTION_ADDRESSBOOK, $EVOLUTION_ADDRESSBOOK_DEPS) AC_SUBST(EVOLUTION_ADDRESSBOOK_CFLAGS) @@ -1524,7 +1522,7 @@ EVO_SET_COMPILE_FLAGS(LIBSOUP, libsoup-2.4 >= 2.3.0) AC_SUBST(LIBSOUP_CFLAGS) AC_SUBST(LIBSOUP_LIBS) -EVO_SET_COMPILE_FLAGS(EVOLUTION_CALENDAR, libgnomeui-2.0 libbonoboui-2.0 libglade-2.0 gnome-vfs-module-2.0 libgtkhtml-$GTKHTML_PACKAGE libebook-$EDS_PACKAGE libecal-$EDS_PACKAGE libedataserverui-$EDS_PACKAGE $HAL_REQUIREMENT $libnotify gtkhtml-editor) +EVO_SET_COMPILE_FLAGS(EVOLUTION_CALENDAR, libgnomeui-2.0 libbonoboui-2.0 libglade-2.0 gio-2.0 gconf-2.0 gobject-2.0 libgtkhtml-$GTKHTML_PACKAGE libebook-$EDS_PACKAGE libecal-$EDS_PACKAGE libedataserverui-$EDS_PACKAGE $HAL_REQUIREMENT $libnotify gtkhtml-editor) AC_SUBST(EVOLUTION_CALENDAR_CFLAGS) AC_SUBST(EVOLUTION_CALENDAR_LIBS) @@ -1536,7 +1534,7 @@ fi dnl --- evolution-mail flags -EVO_SET_COMPILE_FLAGS(EVOLUTION_MAIL, camel-provider-$EDS_PACKAGE libgnomeui-2.0 libbonoboui-2.0 libglade-2.0 gnome-vfs-module-2.0 libgtkhtml-$GTKHTML_PACKAGE gtkhtml-editor bonobo-activation-2.0 $mozilla_nss libebook-$EDS_PACKAGE libedataserverui-$EDS_PACKAGE) +EVO_SET_COMPILE_FLAGS(EVOLUTION_MAIL, camel-provider-$EDS_PACKAGE libgnomeui-2.0 libbonoboui-2.0 libglade-2.0 gio-2.0 gconf-2.0 gobject-2.0 libgtkhtml-$GTKHTML_PACKAGE gtkhtml-editor bonobo-activation-2.0 $mozilla_nss libebook-$EDS_PACKAGE libedataserverui-$EDS_PACKAGE) AC_SUBST(EVOLUTION_MAIL_CFLAGS) AC_SUBST(EVOLUTION_MAIL_LIBS) diff --git a/e-util/ChangeLog b/e-util/ChangeLog index 5291429431..8df4256595 100644 --- a/e-util/ChangeLog +++ b/e-util/ChangeLog @@ -1,3 +1,15 @@ +2008-04-17 Milan Crha + + ** Part of fix for bug #526739 + + * e-gui-utils.c: Do not include gnome-vfs. + * e-util.c: (e_write_file_uri), (e_file_get_save_path): + * e-dialog-utils.c: (e_file_can_save), (e_file_check_local): + Use gio instead of gnome-vfs. + * e-util.h: + * e-util.c: (e_util_guess_mime_type), (e_util_filename_to_uri), + (e_util_uri_to_filename), (e_util_read_file): New helper functions. + 2008-04-12 Matthew Barnes * e-util-labels.c (e_util_labels_add_with_dlg): diff --git a/e-util/e-dialog-utils.c b/e-util/e-dialog-utils.c index 1c75dc83e5..8207e18181 100644 --- a/e-util/e-dialog-utils.c +++ b/e-util/e-dialog-utils.c @@ -49,8 +49,6 @@ #include #include -#include - #include "e-util/e-util.h" #include "e-util/e-error.h" @@ -408,7 +406,7 @@ e_file_can_save(GtkWindow *parent, const char *uri) if (!e_file_check_local(uri)) return TRUE; - path = gnome_vfs_get_local_path_from_uri(uri); + path = e_util_uri_to_filename (uri); if (!path) return FALSE; @@ -438,7 +436,7 @@ e_file_check_local (const char *name) { char *uri; - uri = gnome_vfs_get_local_path_from_uri(name); + uri = e_util_uri_to_filename (name); if (uri) { g_free(uri); return TRUE; diff --git a/e-util/e-gui-utils.c b/e-util/e-gui-utils.c index 5a828dedf6..4da3e6dcfe 100644 --- a/e-util/e-gui-utils.c +++ b/e-util/e-gui-utils.c @@ -29,7 +29,6 @@ #include #include -#include #include /** diff --git a/e-util/e-util.c b/e-util/e-util.c index 50bd7eab70..f1bc8968c4 100644 --- a/e-util/e-util.c +++ b/e-util/e-util.c @@ -38,8 +38,8 @@ #include #include #include +#include #include -#include #ifdef G_OS_WIN32 #include @@ -164,29 +164,59 @@ e_int_compare (gconstpointer x, gconstpointer y) gint e_write_file_uri (const gchar *filename, const gchar *data) { - guint64 length = strlen(data); - guint64 bytes; - GnomeVFSResult result; - GnomeVFSHandle *handle = NULL; + gsize length = strlen (data); + gssize bytes; + GFile *file; + GOutputStream *stream; + GError *error = NULL; - result = gnome_vfs_create (&handle, filename, GNOME_VFS_OPEN_WRITE, FALSE, 0644); - if (result != GNOME_VFS_OK) { + file = g_file_new_for_path (filename); + if (!file) { g_warning ("Couldn't save item"); return 1; } + stream = G_OUTPUT_STREAM (g_file_replace (file, NULL, FALSE, G_FILE_CREATE_NONE, NULL, &error)); + g_object_unref (file); + + if (!stream || error) { + g_warning ("Couldn't save item%s%s", error ? ": " : "", error ? error->message : ""); + + if (stream) + g_object_unref (stream); + + if (error) + g_error_free (error); + + return 1; + } + while (length > 0) { - gnome_vfs_write(handle, data, length, &bytes); - if (bytes > 0) { + bytes = g_output_stream_write_all (stream, data, length, NULL, NULL, &error); + if (bytes > 0 && !error) { length -= bytes; data += bytes; } else { - gnome_vfs_close(handle); + g_warning ("Couldn't save item%s%s", error ? ": " : "", error ? error->message : ""); + + if (error) + g_error_free (error); + + g_output_stream_close (stream, NULL, NULL); + g_object_unref (stream); + return 1; } } - gnome_vfs_close (handle); + g_output_stream_close (stream, NULL, &error); + g_object_unref (stream); + + if (error) { + g_warning ("Couldn't close output stream: %s", error->message); + g_error_free (error); + } + return 0; } @@ -1042,8 +1072,16 @@ e_file_get_save_path (void) } g_object_unref(gconf); - if (uri == NULL) - uri = gnome_vfs_get_uri_from_local_path(g_get_home_dir()); + if (uri == NULL) { + GFile *file; + + file = g_file_new_for_path (g_get_home_dir ()); + if (file) { + uri = g_file_get_uri (file); + g_object_unref (file); + } + } + return (uri); } @@ -1096,3 +1134,172 @@ e_file_lock_exists () return g_file_test (fname, G_FILE_TEST_EXISTS); } + +/** + * e_util_guess_mime_type: + * @filename: it's a local file name, or URI. + * Returns: NULL or newly allocated string with a mime_type of the given file. Free with g_free. + * + * Guesses mime_type for the given file_name. + **/ +char * +e_util_guess_mime_type (const char *filename) +{ + GFile *file; + GFileInfo *fi; + char *mime_type; + + g_return_val_if_fail (filename != NULL, NULL); + + if (strstr (filename, "://")) + file = g_file_new_for_uri (filename); + else + file = g_file_new_for_path (filename); + + if (!file) + return NULL; + + fi = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE, G_FILE_QUERY_INFO_NONE, NULL, NULL); + if (!fi) { + g_object_unref (file); + return NULL; + } + + mime_type = g_content_type_get_mime_type (g_file_info_get_content_type (fi)); + + g_object_unref (fi); + g_object_unref (file); + + return mime_type; +} + +/** + * e_util_filename_to_uri: + * @filename: local file name. + * Returns: either newly allocated string or NULL. Free with g_free. + * + * Converts local file name to URI. + **/ +char * +e_util_filename_to_uri (const char *filename) +{ + GFile *file; + char *uri = NULL; + + g_return_val_if_fail (filename != NULL, NULL); + + file = g_file_new_for_path (filename); + + if (file) { + uri = g_file_get_uri (file); + g_object_unref (file); + } + + return uri; +} + +/** + * e_util_uri_to_filename: + * @uri: uri. + * Returns: either newly allocated string or NULL. Free with g_free. + * + * Converts URI to local file name. NULL indicates no such local file name exists. + **/ +char * +e_util_uri_to_filename (const char *uri) +{ + GFile *file; + char *filename = NULL; + + g_return_val_if_fail (uri != NULL, NULL); + + file = g_file_new_for_uri (uri); + + if (file) { + filename = g_file_get_path (file); + g_object_unref (file); + } + + return filename; +} + +/** + * e_util_read_file: + * @filename: File name to read. + * @filename_is_uri: Whether the file name is URI, if not, then it's a local path. + * @buffer: Read content or the file. Should not be NULL. Returned value should be freed with g_free. + * @read: Number of actually read bytes. Should not be NULL. + * @error: Here will be returned an error from reading operations. Can be NULL. Not every time is set when returned FALSE. + * Returns: Whether was reading successful or not. + * + * Reads synchronously content of the file, to which is pointed either by path or by URI. + * Mount point should be already mounted when calling this function. + **/ +gboolean +e_util_read_file (const char *filename, gboolean filename_is_uri, char **buffer, gsize *read, GError **error) +{ + GFile *file; + GFileInfo *info; + GError *err = NULL; + gboolean res = FALSE; + + g_return_val_if_fail (filename != NULL, FALSE); + g_return_val_if_fail (buffer != NULL, FALSE); + g_return_val_if_fail (read != NULL, FALSE); + + *buffer = NULL; + *read = 0; + + if (filename_is_uri) + file = g_file_new_for_uri (filename); + else + file = g_file_new_for_path (filename); + + g_return_val_if_fail (file != NULL, FALSE); + + info = g_file_query_info (file, G_FILE_ATTRIBUTE_STANDARD_SIZE, G_FILE_QUERY_INFO_NONE, NULL, &err); + + if (!err && info) { + guint64 sz; + char *buff; + + sz = g_file_info_get_attribute_uint64 (info, G_FILE_ATTRIBUTE_STANDARD_SIZE); + buff = g_malloc (sizeof (char) * sz); + + if (buff) { + GInputStream *stream; + + stream = G_INPUT_STREAM (g_file_read (file, NULL, &err)); + + if (!err && stream) { + res = g_input_stream_read_all (stream, buff, sz, read, NULL, &err); + + if (err) + res = FALSE; + + if (res) + *buffer = buff; + else + g_free (buff); + } + + if (stream) + g_object_unref (stream); + } + } + + if (info) + g_object_unref (info); + + g_object_unref (file); + + if (err) { + if (error) + *error = err; + else + g_error_free (err); + } + + return res; +} + diff --git a/e-util/e-util.h b/e-util/e-util.h index 15003d7226..0f76e9e29e 100644 --- a/e-util/e-util.h +++ b/e-util/e-util.h @@ -117,6 +117,12 @@ gboolean e_file_lock_create (void); void e_file_lock_destroy (void); gboolean e_file_lock_exists (void); +char *e_util_guess_mime_type (const char *filename); +char *e_util_filename_to_uri (const char *filename); +char *e_util_uri_to_filename (const char *uri); + +gboolean e_util_read_file (const char *filename, gboolean filename_is_uri, char **buffer, gsize *read, GError **error); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/mail/ChangeLog b/mail/ChangeLog index fbddc2eb8e..027e2b1fb8 100644 --- a/mail/ChangeLog +++ b/mail/ChangeLog @@ -1,3 +1,22 @@ +2008-04-17 Milan Crha + + ** Part of fix for bug #526739 + + * Makefile.am: + * em-vfs-stream.h: + * em-vfs-stream.c: Removed from project, not used anywhere. + * em-menu.c: + * em-config.c: Do not include gnome-vfs. + * mail-ops.c: (save_messages_exec), (save_part_exec): + Changes related to Data Server change of CamelStreamVFS. + * em-format.c: (em_format_describe_part): + * em-format-html-display.c: (efhd_bonobo_object), (efhd_find_handler), + (efhd_use_component), (efhd_bonobo_unknown), (efhd_check_server_prop), + (efhd_format_attachment): Drop use of deprecated gnome-vfs functions. + * em-utils.c: (em_utils_snoop_type): Use gio to guess the mime_type. + * em-popup.c: (emp_apps_open_in), (emp_apps_popup_free), + (emp_standard_menu_factory): Use gio to fill popup and launch app. + 2008-04-16 Shuai Liu ** Fix for bug #528358 diff --git a/mail/Makefile.am b/mail/Makefile.am index 3cbd23c825..e286a47908 100644 --- a/mail/Makefile.am +++ b/mail/Makefile.am @@ -78,7 +78,6 @@ mailinclude_HEADERS = \ em-stripsig-filter.h \ em-sync-stream.h \ em-utils.h \ - em-vfs-stream.h \ mail-autofilter.h \ mail-component.h \ mail-config.h \ @@ -161,7 +160,6 @@ libevolution_mail_la_SOURCES = \ em-vfolder-editor.h \ em-vfolder-rule.c \ em-vfolder-rule.h \ - em-vfs-stream.c \ mail-autofilter.c \ mail-component-factory.c \ mail-component.c \ diff --git a/mail/em-config.c b/mail/em-config.c index 80869faa4b..e7fdf6964f 100644 --- a/mail/em-config.c +++ b/mail/em-config.c @@ -39,7 +39,6 @@ #include #include -#include #include "em-config.h" #include "libedataserver/e-msgport.h" diff --git a/mail/em-format-html-display.c b/mail/em-format-html-display.c index 64dbae3377..be0bfa3c87 100644 --- a/mail/em-format-html-display.c +++ b/mail/em-format-html-display.c @@ -66,7 +66,6 @@ #include -#include #include #include @@ -210,9 +209,6 @@ static void efhd_format_secure(EMFormat *emf, CamelStream *stream, CamelMimePart static void efhd_complete(EMFormat *); gboolean efhd_mnemonic_show_bar (GtkWidget *widget, gboolean focus, GtkWidget *efhd); -static gboolean efhd_bonobo_object(EMFormatHTML *efh, GtkHTMLEmbedded *eb, EMFormatHTMLPObject *pobject); -static gboolean efhd_use_component(const char *mime_type); - static void efhd_builtin_init(EMFormatHTMLDisplayClass *efhc); enum { @@ -1326,37 +1322,9 @@ efhd_builtin_init(EMFormatHTMLDisplayClass *efhc) /* ********************************************************************** */ -static void -efhd_bonobo_unknown(EMFormat *emf, CamelStream *stream, CamelMimePart *part, const EMFormatHandler *info) -{ - char *classid; - - classid = g_strdup_printf("bonobo-unknown:///em-format-html-display/%s", emf->part_id->str); - em_format_html_add_pobject((EMFormatHTML *)emf, sizeof(EMFormatHTMLPObject), classid, part, efhd_bonobo_object); - camel_stream_printf(stream, "
\n", classid, info->mime_type); - g_free(classid); -} - -/* ********************************************************************** */ - static const EMFormatHandler *efhd_find_handler(EMFormat *emf, const char *mime_type) { - const EMFormatHandler *handle; - - if ( (handle = ((EMFormatClass *)efhd_parent)->find_handler(emf, mime_type)) == NULL - && efhd_use_component(mime_type) - && (handle = g_hash_table_lookup(efhd_bonobo_handlers, mime_type)) == NULL) { - EMFormatHandler *h = g_malloc0(sizeof(*h)); - - h->mime_type = g_strdup(mime_type); - h->handler = efhd_bonobo_unknown; - h->flags = EM_FORMAT_HANDLER_INLINE_DISPOSITION; - g_hash_table_insert(efhd_bonobo_handlers, h->mime_type, h); - - handle = h; - } - - return handle; + return ((EMFormatClass *)efhd_parent)->find_handler(emf, mime_type); } static void efhd_format_clone(EMFormat *emf, CamelFolder *folder, const char *uid, CamelMimeMessage *msg, EMFormat *src) @@ -1980,152 +1948,6 @@ efhd_attachment_frame(EMFormat *emf, CamelStream *stream, EMFormatPURI *puri) } } -static gboolean -efhd_bonobo_object(EMFormatHTML *efh, GtkHTMLEmbedded *eb, EMFormatHTMLPObject *pobject) -{ - CamelDataWrapper *wrapper; - Bonobo_ServerInfo *component; - GtkWidget *embedded; - Bonobo_PersistStream persist; - CORBA_Environment ev; - CamelStreamMem *cstream; - BonoboStream *bstream; - BonoboControlFrame *control_frame; - Bonobo_PropertyBag prop_bag; - - component = gnome_vfs_mime_get_default_component(eb->type); - if (component == NULL) - return FALSE; - - embedded = bonobo_widget_new_control(component->iid, NULL); - CORBA_free(component); - if (embedded == NULL) - return FALSE; - - CORBA_exception_init(&ev); - - control_frame = bonobo_widget_get_control_frame((BonoboWidget *)embedded); - prop_bag = bonobo_control_frame_get_control_property_bag(control_frame, NULL); - if (prop_bag != CORBA_OBJECT_NIL) { - /* - * Now we can take care of business. Currently, the only control - * that needs something passed to it through a property bag is - * the iTip control, and it needs only the From email address, - * but perhaps in the future we can generalize this section of code - * to pass a bunch of useful things to all embedded controls. - */ - const CamelInternetAddress *from; - char *from_address; - - from = camel_mime_message_get_from((CamelMimeMessage *)((EMFormat *)efh)->message); - from_address = camel_address_encode((CamelAddress *)from); - bonobo_property_bag_client_set_value_string(prop_bag, "from_address", from_address, &ev); - g_free(from_address); - - Bonobo_Unknown_unref(prop_bag, &ev); - } - - persist = (Bonobo_PersistStream)Bonobo_Unknown_queryInterface(bonobo_widget_get_objref((BonoboWidget *)embedded), - "IDL:Bonobo/PersistStream:1.0", &ev); - if (persist == CORBA_OBJECT_NIL) { - g_object_ref_sink(embedded); - CORBA_exception_free(&ev); - return FALSE; - } - - /* Write the data to a CamelStreamMem... */ - cstream = (CamelStreamMem *)camel_stream_mem_new(); - wrapper = camel_medium_get_content_object((CamelMedium *)pobject->part); - if (FALSE && !g_ascii_strncasecmp (eb->type, "text/", 5)) { - /* do charset conversion, etc */ - d(printf("performing charset conversion for %s component\n", eb->type)); - em_format_format_text((EMFormat *)efh, (CamelStream *)cstream, wrapper); - } else { - camel_data_wrapper_decode_to_stream (wrapper, (CamelStream *) cstream); - } - - /* ...convert the CamelStreamMem to a BonoboStreamMem... */ - bstream = bonobo_stream_mem_create((char *)cstream->buffer->data, cstream->buffer->len, TRUE, FALSE); - camel_object_unref(cstream); - - /* ...and hydrate the PersistStream from the BonoboStream. */ - Bonobo_PersistStream_load(persist, - bonobo_object_corba_objref(BONOBO_OBJECT (bstream)), - eb->type, &ev); - bonobo_object_unref(BONOBO_OBJECT (bstream)); - Bonobo_Unknown_unref(persist, &ev); - CORBA_Object_release(persist, &ev); - - if (ev._major != CORBA_NO_EXCEPTION) { - g_object_ref_sink(embedded); - CORBA_exception_free(&ev); - return FALSE; - } - CORBA_exception_free(&ev); - - gtk_widget_show(embedded); - gtk_container_add(GTK_CONTAINER (eb), embedded); - - return TRUE; -} - -static gboolean -efhd_check_server_prop(Bonobo_ServerInfo *component, const char *propname, const char *value) -{ - CORBA_sequence_CORBA_string stringv; - Bonobo_ActivationProperty *prop; - int i; - - prop = bonobo_server_info_prop_find(component, propname); - if (!prop || prop->v._d != Bonobo_ACTIVATION_P_STRINGV) - return FALSE; - - stringv = prop->v._u.value_stringv; - for (i = 0; i < stringv._length; i++) { - if (!g_ascii_strcasecmp(value, stringv._buffer[i])) - return TRUE; - } - - return FALSE; -} - -static gboolean -efhd_use_component(const char *mime_type) -{ - GList *components, *iter; - Bonobo_ServerInfo *component = NULL; - - /* should this cache it? */ - - if (g_ascii_strcasecmp(mime_type, "text/x-vcard") != 0 - && g_ascii_strcasecmp(mime_type, "text/calendar") != 0) { - const char **mime_types; - int i; - - mime_types = mail_config_get_allowable_mime_types(); - for (i = 0; mime_types[i]; i++) { - if (!g_ascii_strcasecmp(mime_types[i], mime_type)) - goto type_ok; - } - return FALSE; - } -type_ok: - components = gnome_vfs_mime_get_all_components (mime_type); - for (iter = components; iter; iter = iter->next) { - Bonobo_ServerInfo *comp = iter->data; - - comp = iter->data; - if (efhd_check_server_prop(comp, "repo_ids", "IDL:Bonobo/PersistStream:1.0") - && efhd_check_server_prop(comp, "bonobo:supported_mime_types", mime_type)) { - component = comp; - break; - } - } - gnome_vfs_mime_component_list_free (components); - - return component != NULL; -} - static void attachment_bar_arrow_clicked(GtkWidget *w, EMFormatHTMLDisplay *efhd) { @@ -2472,12 +2294,6 @@ efhd_format_attachment(EMFormat *emf, CamelStream *stream, CamelMimePart *part, if (handle) { if (info->shown) handle->handler(emf, stream, part, handle); - } else if (efhd_use_component(mime_type)) { - g_free(classid); /* messy */ - - classid = g_strdup_printf("bonobo-unknown:///em-format-html-display/%s", emf->part_id->str); - em_format_html_add_pobject((EMFormatHTML *)emf, sizeof(EMFormatHTMLPObject), classid, part, efhd_bonobo_object); - camel_stream_printf(stream, "
>\n", classid, mime_type); } g_free(classid); diff --git a/mail/em-format.c b/mail/em-format.c index 2bdea062ed..ddf8693790 100644 --- a/mail/em-format.c +++ b/mail/em-format.c @@ -28,10 +28,8 @@ #include #include -#include -#include -#include #include +#include #include #include @@ -1150,11 +1148,13 @@ em_format_describe_part(CamelMimePart *part, const char *mime_type) { GString *stext; const char *text; - char *out; + char *out, *desc; stext = g_string_new(""); - text = gnome_vfs_mime_get_description(mime_type); - g_string_append_printf(stext, _("%s attachment"), text?text:mime_type); + /* TODO: mime_type isn't content_type on some systems (Win32), thus this will not work there. */ + desc = g_content_type_get_description (mime_type); + g_string_append_printf (stext, _("%s attachment"), desc ? desc : mime_type); + g_free (desc); if ((text = camel_mime_part_get_filename (part))) g_string_append_printf(stext, " (%s)", text); if ((text = camel_mime_part_get_description(part))) diff --git a/mail/em-menu.c b/mail/em-menu.c index 69fc7839f8..77a93aba18 100644 --- a/mail/em-menu.c +++ b/mail/em-menu.c @@ -39,7 +39,6 @@ #include #include -#include #include "em-menu.h" #include "libedataserver/e-msgport.h" diff --git a/mail/em-popup.c b/mail/em-popup.c index 0ee4fdae5d..b727bf552f 100644 --- a/mail/em-popup.c +++ b/mail/em-popup.c @@ -28,6 +28,9 @@ #include #include +#include + +#include #include #include @@ -39,9 +42,6 @@ #include #include -#include -#include -#include #include "em-popup.h" #include "libedataserver/e-msgport.h" @@ -644,8 +644,6 @@ static EPopupItem emp_standard_uri_popups[] = { #define LEN(x) (sizeof(x)/sizeof(x[0])) -#include - static void emp_apps_open_in(EPopup *ep, EPopupItem *item, void *data) { @@ -660,18 +658,33 @@ emp_apps_open_in(EPopup *ep, EPopupItem *item, void *data) path = em_utils_temp_save_part(target->widget, part, TRUE); if (path) { - GnomeVFSMimeApplication *app = item->user_data; - char *uri; + GAppInfo *app = item->user_data; GList *uris = NULL; + GError *error = NULL; - uri = gnome_vfs_get_uri_from_local_path(path); - uris = g_list_append(uris, uri); + if (g_app_info_supports_files (app)) { + GFile *file = g_file_new_for_path (path); - gnome_vfs_mime_application_launch(app, uris); + uris = g_list_append (uris, file); + g_app_info_launch (app, uris, NULL, &error); + g_object_unref (file); + } else { + char *uri; - g_free(uri); - g_list_free(uris); - g_free(path); + uri = e_util_filename_to_uri (path); + uris = g_list_append (uris, uri); + + g_app_info_launch_uris (app, uris, NULL, &error); + g_free (uri); + } + + if (error) { + g_warning ("%s", error->message); + g_error_free (error); + } + + g_list_free (uris); + g_free (path); } } @@ -682,6 +695,9 @@ emp_apps_popup_free(EPopup *ep, GSList *free_list, void *data) GSList *n = free_list->next; EPopupItem *item = free_list->data; + if (item->user_data && item->activate == emp_apps_open_in) + g_object_unref (item->user_data); + g_free(item->path); g_free(item->label); g_free(item); @@ -790,23 +806,27 @@ emp_standard_menu_factory(EPopup *emp, void *data) if (mime_type) { gchar *cp; - /* GNOME-VFS expects lowercase MIME types. */ + /* does gvfs expect lowercase MIME types? */ for (cp = mime_type; *cp != '\0'; cp++) *cp = g_ascii_tolower (*cp); - apps = gnome_vfs_mime_get_all_applications(mime_type); + /* TODO: g_app_info_get_all_for_type expects content_type, not a mime_type, thus it will work fine + on Linux/Unix systems, but not on Win32. They will add hopefully some function to convert between + these two soon. */ + apps = g_app_info_get_all_for_type (mime_type); if (apps == NULL && strcmp(mime_type, "application/octet-stream") == 0) { - const char *name_type; - if (filename) { - /* GNOME-VFS will misidentify TNEF attachments as MPEG */ + /* will gvfs misidentify TNEF attachments as MPEG? */ if (!strcmp (filename, "winmail.dat")) - name_type = "application/vnd.ms-tnef"; - else - name_type = gnome_vfs_mime_type_from_name(filename); - if (name_type) - apps = gnome_vfs_mime_get_all_applications(name_type); + apps = g_app_info_get_all_for_type ("application/vnd.ms-tnef"); + else { + char *name_type = e_util_guess_mime_type (filename); + + apps = g_app_info_get_all_for_type (name_type); + + g_free (name_type); + } } } @@ -818,16 +838,19 @@ emp_standard_menu_factory(EPopup *emp, void *data) menus = g_slist_prepend(menus, (void *)&emp_standard_part_apps_bar); for (l = apps, i = 0; l; l = l->next, i++) { - GnomeVFSMimeApplication *app = l->data; + GAppInfo *app = l->data; EPopupItem *item; - if (app->requires_terminal) + if (!g_app_info_should_show (app)) { + g_object_unref (app); + l->data = NULL; continue; + } item = g_malloc0(sizeof(*item)); item->type = E_POPUP_ITEM; item->path = g_strdup_printf("99.object.%02d", i); - item->label = g_strdup_printf(_("Open in %s..."), app->name); + item->label = g_strdup_printf(_("Open in %s..."), g_app_info_get_name (app)); item->activate = emp_apps_open_in; item->user_data = app; diff --git a/mail/em-utils.c b/mail/em-utils.c index ee77391e97..53e2fff906 100644 --- a/mail/em-utils.c +++ b/mail/em-utils.c @@ -52,11 +52,10 @@ #include #include -#include -#include -#include #include +#include + #include "mail-component.h" #include "mail-mt.h" #include "mail-ops.h" @@ -2199,30 +2198,40 @@ em_utils_contact_photo (struct _CamelInternetAddress *cia, gboolean local) const char * em_utils_snoop_type(CamelMimePart *part) { - const char *filename, *name_type = NULL, *magic_type = NULL; + /* cache is here only to be able still return const char * */ + static GHashTable *types_cache = NULL; + + const char *filename; + char *name_type = NULL, *magic_type = NULL, *res, *tmp; CamelDataWrapper *dw; filename = camel_mime_part_get_filename (part); if (filename) { - /* GNOME-VFS will misidentify TNEF attachments as MPEG */ + /* will GVFS misidentify TNEF attachments as MPEG? */ if (!strcmp (filename, "winmail.dat")) return "application/vnd.ms-tnef"; - name_type = gnome_vfs_mime_type_from_name(filename); + name_type = e_util_guess_mime_type (filename); } dw = camel_medium_get_content_object((CamelMedium *)part); if (!camel_data_wrapper_is_offline(dw)) { CamelStreamMem *mem = (CamelStreamMem *)camel_stream_mem_new(); - if (camel_data_wrapper_decode_to_stream(dw, (CamelStream *)mem) > 0) - magic_type = gnome_vfs_get_mime_type_for_data(mem->buffer->data, mem->buffer->len); + if (camel_data_wrapper_decode_to_stream(dw, (CamelStream *)mem) > 0) { + char *ct = g_content_type_guess (filename, mem->buffer->data, mem->buffer->len, NULL); + + if (ct) + magic_type = g_content_type_get_mime_type (ct); + + g_free (ct); + } camel_object_unref(mem); } d(printf("snooped part, magic_type '%s' name_type '%s'\n", magic_type, name_type)); - /* If GNOME-VFS doesn't recognize the data by magic, but it + /* If gvfs doesn't recognize the data by magic, but it * contains English words, it will call it text/plain. If the * filename-based check came up with something different, use * that instead and if it returns "application/octet-stream" @@ -2233,11 +2242,31 @@ em_utils_snoop_type(CamelMimePart *part) if (name_type && (!strcmp(magic_type, "text/plain") || !strcmp(magic_type, "application/octet-stream"))) - return name_type; + res = name_type; else - return magic_type; + res = magic_type; } else - return name_type; + res = name_type; + + + if (res != name_type) + g_free (name_type); + + if (res != magic_type) + g_free (magic_type); + + if (!types_cache) + types_cache = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) g_free, (GDestroyNotify) NULL); + + tmp = g_hash_table_lookup (types_cache, res); + if (tmp) { + g_free (res); + res = tmp; + } else { + g_hash_table_insert (types_cache, res, res); + } + + return res; /* We used to load parts to check their type, we dont anymore, see bug #11778 for some discussion */ diff --git a/mail/em-vfs-stream.c b/mail/em-vfs-stream.c deleted file mode 100644 index 290ea86a4d..0000000000 --- a/mail/em-vfs-stream.c +++ /dev/null @@ -1,330 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- - * - * Authors: Michael Zucchi - * - * Copyright 2004 Ximian, Inc. (www.ximian.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - * A GnomeVFS to CamelStream mapper. - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include - -#include - -#include "em-vfs-stream.h" - -#ifndef EINPROGRESS -#define EINPROGRESS EAGAIN -#endif -#ifndef ELOOP -#define ELOOP EIO -#endif - -#define LOG_STREAM - -#define d(x) - -#define EMVS_CLASS(x) ((EMVFSStreamClass *)(((CamelObject *)(x))->klass)) - -static CamelStreamClass *parent_class = NULL; - -static void -em_vfs_stream_init (CamelObject *object) -{ - /*EMVFSStream *emvfs = (EMVFSStream *)object;*/ -} - -static void -em_vfs_stream_finalize (CamelObject *object) -{ - EMVFSStream *emvfs = (EMVFSStream *)object; - - if (emvfs->handle) - gnome_vfs_close(emvfs->handle); -} - -static void -emvfs_set_errno(GnomeVFSResult res) -{ - switch(res) { - case GNOME_VFS_OK: - g_warning("em-vfs-stream: calling set_errno with no error"); - break; - case GNOME_VFS_ERROR_NOT_FOUND: - case GNOME_VFS_ERROR_HOST_NOT_FOUND: - case GNOME_VFS_ERROR_INVALID_HOST_NAME: - case GNOME_VFS_ERROR_HOST_HAS_NO_ADDRESS: - case GNOME_VFS_ERROR_SERVICE_NOT_AVAILABLE: - errno = ENOENT; - break; - case GNOME_VFS_ERROR_GENERIC: - case GNOME_VFS_ERROR_INTERNAL: - case GNOME_VFS_ERROR_IO: - case GNOME_VFS_ERROR_EOF: /* will be caught by read before here anyway */ - case GNOME_VFS_ERROR_SERVICE_OBSOLETE: - case GNOME_VFS_ERROR_PROTOCOL_ERROR: - default: - errno = EIO; - break; - case GNOME_VFS_ERROR_BAD_PARAMETERS: - case GNOME_VFS_ERROR_NOT_SUPPORTED: - case GNOME_VFS_ERROR_INVALID_URI: - case GNOME_VFS_ERROR_NOT_OPEN: - case GNOME_VFS_ERROR_INVALID_OPEN_MODE: - case GNOME_VFS_ERROR_NOT_SAME_FILE_SYSTEM: - errno = EINVAL; - break; - case GNOME_VFS_ERROR_CORRUPTED_DATA: /* not sure about these */ - case GNOME_VFS_ERROR_WRONG_FORMAT: - case GNOME_VFS_ERROR_BAD_FILE: - errno = EBADF; - break; - case GNOME_VFS_ERROR_TOO_BIG: - errno = E2BIG; - break; - case GNOME_VFS_ERROR_NO_SPACE: - errno = ENOSPC; - break; - case GNOME_VFS_ERROR_READ_ONLY: - case GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM: - errno = EROFS; - break; - case GNOME_VFS_ERROR_TOO_MANY_OPEN_FILES: - errno = EMFILE; - break; - case GNOME_VFS_ERROR_NOT_A_DIRECTORY: - errno = ENOTDIR; - break; - case GNOME_VFS_ERROR_IN_PROGRESS: - errno = EINPROGRESS; - break; - case GNOME_VFS_ERROR_INTERRUPTED: - errno = EINTR; - break; - case GNOME_VFS_ERROR_FILE_EXISTS: - errno = EEXIST; - case GNOME_VFS_ERROR_LOOP: - errno = ELOOP; - break; - case GNOME_VFS_ERROR_ACCESS_DENIED: - case GNOME_VFS_ERROR_NOT_PERMITTED: - case GNOME_VFS_ERROR_LOGIN_FAILED: - errno = EPERM; - break; - case GNOME_VFS_ERROR_IS_DIRECTORY: - case GNOME_VFS_ERROR_DIRECTORY_NOT_EMPTY: /* ?? */ - errno = EISDIR; - break; - case GNOME_VFS_ERROR_NO_MEMORY: - errno = ENOMEM; - break; - case GNOME_VFS_ERROR_CANCELLED: - errno = EINTR; - break; - case GNOME_VFS_ERROR_DIRECTORY_BUSY: - errno = EBUSY; - break; - case GNOME_VFS_ERROR_TOO_MANY_LINKS: - errno = EMLINK; - break; - case GNOME_VFS_ERROR_NAME_TOO_LONG: - errno = ENAMETOOLONG; - break; - } -} - -static ssize_t -emvfs_read(CamelStream *stream, char *buffer, size_t n) -{ - EMVFSStream *emvfs = EM_VFS_STREAM (stream); - GnomeVFSFileSize count; - GnomeVFSResult res; - - if (emvfs->handle == NULL) { - errno = EINVAL; - return -1; - } - - /* TODO: handle camel cancellation? */ - - res = gnome_vfs_read(emvfs->handle, buffer, n, &count); - if (res == GNOME_VFS_OK) - return (ssize_t)count; - else if (res == GNOME_VFS_ERROR_EOF) { - stream->eos = TRUE; - return 0; - } - - emvfs_set_errno(res); - - return -1; -} - -static ssize_t -emvfs_write(CamelStream *stream, const char *buffer, size_t n) -{ - EMVFSStream *emvfs = EM_VFS_STREAM (stream); - GnomeVFSFileSize count; - GnomeVFSResult res; - - if (emvfs->handle == NULL) { - errno = EINVAL; - return -1; - } - - res = gnome_vfs_write(emvfs->handle, buffer, n, &count); - if (res == GNOME_VFS_OK) - return (ssize_t)count; - - emvfs_set_errno(res); - - return -1; -} - -static int -emvfs_close(CamelStream *stream) -{ - EMVFSStream *emvfs = EM_VFS_STREAM (stream); - GnomeVFSResult res; - - if (emvfs->handle == NULL) { - errno = EINVAL; - return -1; - } - - res = gnome_vfs_close(emvfs->handle); - emvfs->handle = NULL; - if (res == GNOME_VFS_OK) - return 0; - - emvfs_set_errno(res); - - return -1; -} - -static off_t -emvfs_seek(CamelSeekableStream *stream, off_t offset, CamelStreamSeekPolicy policy) -{ - EMVFSStream *emvfs = EM_VFS_STREAM (stream); - GnomeVFSSeekPosition vpolicy; - GnomeVFSFileSize pos; - GnomeVFSResult res; - - if (emvfs->handle == NULL) { - errno = EINVAL; - return -1; - } - - switch (policy) { - case CAMEL_STREAM_SET: - default: - vpolicy = GNOME_VFS_SEEK_START; - break; - case CAMEL_STREAM_CUR: - vpolicy = GNOME_VFS_SEEK_CURRENT; - break; - case CAMEL_STREAM_END: - vpolicy = GNOME_VFS_SEEK_END; - break; - } - - if ( (res = gnome_vfs_seek(emvfs->handle, vpolicy, offset)) == GNOME_VFS_OK - && (res = gnome_vfs_tell(emvfs->handle, &pos)) == GNOME_VFS_OK) - return pos; - - emvfs_set_errno(res); - - return -1; -} - -static off_t -emvfs_tell(CamelSeekableStream *stream) -{ - EMVFSStream *emvfs = EM_VFS_STREAM (stream); - GnomeVFSFileSize pos; - GnomeVFSResult res; - - if (emvfs->handle == NULL) { - errno = EINVAL; - return -1; - } - - if ((res = gnome_vfs_tell(emvfs->handle, &pos)) == GNOME_VFS_OK) - return pos; - - emvfs_set_errno(res); - - return -1; -} - -static void -em_vfs_stream_class_init (EMVFSStreamClass *klass) -{ - ((CamelStreamClass *)klass)->read = emvfs_read; - ((CamelStreamClass *)klass)->write = emvfs_write; - ((CamelStreamClass *)klass)->close = emvfs_close; - - ((CamelSeekableStreamClass *)klass)->seek = emvfs_seek; - ((CamelSeekableStreamClass *)klass)->tell = emvfs_tell; - /* set_bounds? */ -} - -CamelType -em_vfs_stream_get_type (void) -{ - static CamelType type = CAMEL_INVALID_TYPE; - - if (type == CAMEL_INVALID_TYPE) { - parent_class = (CamelStreamClass *)camel_seekable_stream_get_type(); - type = camel_type_register ((CamelType)parent_class, - "EMVFSStream", - sizeof (EMVFSStream), - sizeof (EMVFSStreamClass), - (CamelObjectClassInitFunc) em_vfs_stream_class_init, - NULL, - (CamelObjectInitFunc) em_vfs_stream_init, - (CamelObjectFinalizeFunc) em_vfs_stream_finalize); - } - - return type; -} - -/** - * emvfs_stream_new: - * @handle: - * - * Create a new camel stream from a GnomeVFS handle. The camel stream - * will own the handle from now on. - * - * Return value: A CamelStream that will talk to @handle. This function cannot fail. - **/ -EMVFSStream * -emvfs_stream_new(GnomeVFSHandle *handle) -{ - EMVFSStream *emvfs; - - emvfs = (EMVFSStream *)camel_object_new(em_vfs_stream_get_type()); - emvfs->handle = handle; - - return emvfs; -} diff --git a/mail/em-vfs-stream.h b/mail/em-vfs-stream.h deleted file mode 100644 index 2095472fab..0000000000 --- a/mail/em-vfs-stream.h +++ /dev/null @@ -1,60 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- - * - * Authors: Michael Zucchi - * - * Copyright 2004 Ximian, Inc. (www.ximian.com) - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License as published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this program; if not, write to the - * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef EM_VFS_STREAM_H -#define EM_VFS_STREAM_H - -#ifdef __cplusplus -extern "C" { -#pragma } -#endif /* __cplusplus */ - -#define EM_VFS_STREAM_TYPE (em_vfs_stream_get_type ()) -#define EM_VFS_STREAM(obj) (CAMEL_CHECK_CAST((obj), EM_VFS_STREAM_TYPE, EMVFSStream)) -#define EM_VFS_STREAM_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), EM_VFS_STREAM_TYPE, EMVFSStreamClass)) -#define EM_IS_VFS_STREAM(o) (CAMEL_CHECK_TYPE((o), EM_VFS_STREAM_TYPE)) - -#include -#include -#include - -typedef struct _EMVFSStream EMVFSStream; -typedef struct _EMVFSStreamClass EMVFSStreamClass; - -struct _EMVFSStream { - CamelSeekableStream parent_stream; - - GnomeVFSHandle *handle; -}; - -struct _EMVFSStreamClass { - CamelSeekableStreamClass parent_class; -}; - -CamelType em_vfs_stream_get_type (void); -EMVFSStream *emvfs_stream_new(GnomeVFSHandle *handle); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - -#endif /* EM_VFS_STREAM_H */ diff --git a/mail/mail-ops.c b/mail/mail-ops.c index d13740570d..77bb37fa62 100644 --- a/mail/mail-ops.c +++ b/mail/mail-ops.c @@ -2016,14 +2016,22 @@ save_messages_exec (struct _save_messages_msg *m) CamelMimeFilterFrom *from_filter; CamelStream *stream; int i; - char *from; + char *from, *path; - stream = camel_stream_vfs_new_with_uri (m->path, O_WRONLY | O_CREAT | O_TRUNC, 0666); + if (strstr (m->path, "://")) + path = m->path; + else + path = g_strjoin (NULL, "file://", m->path, NULL); + + stream = camel_stream_vfs_new_with_uri (path, CAMEL_STREAM_VFS_CREATE); from_filter = camel_mime_filter_from_new(); filtered_stream = camel_stream_filter_new_with_stream(stream); camel_stream_filter_add(filtered_stream, (CamelMimeFilter *)from_filter); camel_object_unref(from_filter); + if (path != m->path) + g_free (path); + for (i=0; iuids->len; i++) { CamelMimeMessage *message; int pc = ((i+1) * 100) / m->uids->len; @@ -2122,21 +2130,34 @@ save_part_exec (struct _save_part_msg *m) { CamelDataWrapper *content; CamelStream *stream; + char *path; + + if (strstr (m->path, "://")) + path = m->path; + else + path = g_strjoin (NULL, "file://", m->path, NULL); if(!m->readonly){ - if (!(stream = camel_stream_vfs_new_with_uri (m->path, O_WRONLY | O_CREAT | O_TRUNC, 0644))) { + if (!(stream = camel_stream_vfs_new_with_uri (path, CAMEL_STREAM_VFS_CREATE))) { camel_exception_setv (&m->base.ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot create output file: %s:\n %s"), - m->path, g_strerror (errno)); + path, g_strerror (errno)); + if (path != m->path) + g_free (path); return; } - } else if (!(stream = camel_stream_vfs_new_with_uri (m->path, O_WRONLY | O_CREAT | O_TRUNC, 0444))) { + } else if (!(stream = camel_stream_vfs_new_with_uri (path, CAMEL_STREAM_VFS_CREATE))) { camel_exception_setv (&m->base.ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot create output file: %s:\n %s"), - m->path, g_strerror (errno)); + path, g_strerror (errno)); + if (path != m->path) + g_free (path); return; } + if (path != m->path) + g_free (path); + content = camel_medium_get_content_object (CAMEL_MEDIUM (m->part)); if (camel_data_wrapper_decode_to_stream (content, stream) == -1 diff --git a/plugins/import-ics-attachments/ChangeLog b/plugins/import-ics-attachments/ChangeLog index dfc443ce64..68a87d906b 100644 --- a/plugins/import-ics-attachments/ChangeLog +++ b/plugins/import-ics-attachments/ChangeLog @@ -1,3 +1,9 @@ +2008-04-17 Milan Crha + + ** Part of fix for bug #526739 + + * icsimporter.c: Do not include gnome-vfs. + 2007-02-20 Paul Bolle ** Fix for bug #517082 diff --git a/plugins/import-ics-attachments/icsimporter.c b/plugins/import-ics-attachments/icsimporter.c index c869db35d9..7b9172c379 100644 --- a/plugins/import-ics-attachments/icsimporter.c +++ b/plugins/import-ics-attachments/icsimporter.c @@ -39,10 +39,6 @@ #include #include "e-util/e-error.h" #include "e-util/e-icon-factory.h" -#include -#include -#include -#include #include #include #include diff --git a/plugins/ipod-sync/ChangeLog b/plugins/ipod-sync/ChangeLog index 804f29b157..d6f2a15aef 100644 --- a/plugins/ipod-sync/ChangeLog +++ b/plugins/ipod-sync/ChangeLog @@ -1,3 +1,13 @@ +2008-04-17 Milan Crha + + ** Part of fix for bug #526739 + + * ical-format.c: (do_save_calendar_ical): + * ipod-sync.c: (destination_save_addressbook): + Write to gio GOutputStream instead of gnome-vfs handle. + * format-handler.h: (open_for_writing): + * ipod-sync.c: (open_for_writing): New helper function. + 2008-01-07 João Vale ** Fix for bug #375580 diff --git a/plugins/ipod-sync/format-handler.h b/plugins/ipod-sync/format-handler.h index 7b53efeb2e..badafd7965 100644 --- a/plugins/ipod-sync/format-handler.h +++ b/plugins/ipod-sync/format-handler.h @@ -25,6 +25,7 @@ #include #include +#include #include #include #include @@ -45,3 +46,5 @@ struct _FormatHandler }; FormatHandler *ical_format_handler_new (void); + +GOutputStream *open_for_writing (GtkWindow *parent, const char *uri, GError **error); diff --git a/plugins/ipod-sync/ical-format.c b/plugins/ipod-sync/ical-format.c index 76dc433c69..f5005c1bda 100644 --- a/plugins/ipod-sync/ical-format.c +++ b/plugins/ipod-sync/ical-format.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include @@ -37,7 +36,6 @@ #include #include #include -#include #include #include "format-handler.h" @@ -80,8 +78,7 @@ do_save_calendar_ical (FormatHandler *handler, EPlugin *ep, ECalPopupTargetSourc error = NULL; if (e_cal_get_object_list (source_client, "#t", &objects, &error)) { - GnomeVFSResult result; - GnomeVFSHandle *handle; + GOutputStream *stream; while (objects != NULL) { icalcomponent *icalcomp = objects->data; @@ -93,29 +90,22 @@ do_save_calendar_ical (FormatHandler *handler, EPlugin *ep, ECalPopupTargetSourc } /* save the file */ - result = gnome_vfs_open (&handle, dest_uri, GNOME_VFS_OPEN_WRITE); - if (result != GNOME_VFS_OK) { - if ((result = gnome_vfs_create (&handle, dest_uri, GNOME_VFS_OPEN_WRITE, - TRUE, GNOME_VFS_PERM_USER_ALL)) != GNOME_VFS_OK) { - display_error_message (gtk_widget_get_toplevel (GTK_WIDGET (target->selector)), - gnome_vfs_result_to_string (result)); - } - } + stream = open_for_writing (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (target->selector))), dest_uri, &error); - if (result == GNOME_VFS_OK) { - char *ical_str; - GnomeVFSFileSize bytes_written; + if (stream && !error) { + char *ical_str = icalcomponent_as_ical_string (top_level); - ical_str = icalcomponent_as_ical_string (top_level); - if ((result = gnome_vfs_write (handle, (gconstpointer) ical_str, strlen (ical_str), &bytes_written)) - != GNOME_VFS_OK) { - display_error_message (gtk_widget_get_toplevel (GTK_WIDGET (target->selector)), - gnome_vfs_result_to_string (result)); - } + g_output_stream_write_all (stream, ical_str, strlen (ical_str), NULL, NULL, &error); + g_output_stream_close (stream); - gnome_vfs_close (handle); + g_free (ical_str); } - } else { + + if (stream) + g_object_unref (stream); + } + + if (error) { display_error_message (gtk_widget_get_toplevel (GTK_WIDGET (target->selector)), error->message); g_error_free (error); } diff --git a/plugins/ipod-sync/ipod-sync.c b/plugins/ipod-sync/ipod-sync.c index bca4242810..c60d19c818 100644 --- a/plugins/ipod-sync/ipod-sync.c +++ b/plugins/ipod-sync/ipod-sync.c @@ -40,7 +40,6 @@ #include #include #include -#include #include #include "format-handler.h" @@ -62,6 +61,56 @@ display_error_message (GtkWidget *parent, const char *message) gtk_widget_destroy (dialog); } +/* Returns output stream for the uri, or NULL on any error. + When done with the stream, just g_output_stream_close and g_object_unref it. + It will ask for overwrite if file already exists. +*/ +GOutputStream * +open_for_writing (GtkWindow *parent, const char *uri, GError **error) +{ + GFile *file; + GFileOutputStream *fostream; + GError *err = NULL; + + g_return_val_if_fail (uri != NULL, NULL); + + file = g_file_new_for_uri (uri); + + g_return_val_if_fail (file != NULL, NULL); + + fostream = g_file_create (file, G_FILE_CREATE_NONE, NULL, &err); + + if (err && err->code == G_IO_ERROR_EXISTS) { + g_error_clear (&err); + + if (e_error_run (parent, E_ERROR_ASK_FILE_EXISTS_OVERWRITE, uri, NULL) == GTK_RESPONSE_OK) { + fostream = g_file_replace (file, NULL, FALSE, G_FILE_CREATE_NONE, NULL, &err); + + if (err && fostream) { + g_object_unref (fostream); + fostream = NULL; + } + } else if (fostream) { + g_object_unref (fostream); + fostream = NULL; + } + } + + g_object_unref (file); + + if (error && err) + *error = err; + else if (err) + g_error_free (err); + + if (fostream) + return G_OUTPUT_STREAM (fostream); + + return NULL; +} + + + static void destination_save_addressbook (EPlugin *ep, EABPopupTargetSource *target) { @@ -70,9 +119,9 @@ destination_save_addressbook (EPlugin *ep, EABPopupTargetSource *target) GList *contacts, *tmp; ESource *primary_source; gchar *uri; + GOutputSream *stream; + GError *error = NULL; char *dest_uri = NULL; - GnomeVFSResult result; - GnomeVFSHandle *handle; char *mount = ipod_get_mount(); primary_source = e_source_selector_peek_primary_selection (target->selector); @@ -96,50 +145,50 @@ destination_save_addressbook (EPlugin *ep, EABPopupTargetSource *target) e_book_get_contacts (book, query, &contacts, NULL); e_book_query_unref (query); - result = gnome_vfs_open (&handle, dest_uri, GNOME_VFS_OPEN_WRITE); - - if (result != GNOME_VFS_OK) { - if ((result = gnome_vfs_create (&handle, dest_uri, GNOME_VFS_OPEN_WRITE, - TRUE, GNOME_VFS_PERM_USER_ALL)) != GNOME_VFS_OK) { - display_error_message (gtk_widget_get_toplevel (GTK_WIDGET (target->selector)), - gnome_vfs_result_to_string (result)); - } - } - - if (result == GNOME_VFS_OK) { - GnomeVFSFileSize bytes_written; + stream = open_for_writing (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (target->selector))), dest_uri, &error); + if (stream && !error) { for (tmp = contacts; tmp; tmp=tmp->next) { - EContact *contact = tmp->data; - gchar *temp = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30); - gchar *vcard; - gchar *converted_vcard; - gsize vcard_latin1_length; - - vcard = g_strconcat(temp, "\r\n", NULL); - converted_vcard = g_convert(vcard, -1, "ISO-8859-1", "UTF-8", NULL, &vcard_latin1_length, NULL); - if ((result = gnome_vfs_write (handle, (gconstpointer) converted_vcard, vcard_latin1_length, &bytes_written)) - != GNOME_VFS_OK) { - display_error_message (gtk_widget_get_toplevel (GTK_WIDGET (target->selector)), - gnome_vfs_result_to_string (result)); - } - - g_object_unref (contact); - g_free (temp); - g_free (vcard); - g_free (converted_vcard); + EContact *contact = tmp->data; + gchar *temp = e_vcard_to_string (E_VCARD (contact), EVC_FORMAT_VCARD_30); + gchar *vcard; + gchar *converted_vcard; + gsize vcard_latin1_length; + + vcard = g_strconcat (temp, "\r\n", NULL); + converted_vcard = g_convert (vcard, -1, "ISO-8859-1", "UTF-8", NULL, &vcard_latin1_length, NULL); + g_output_stream_write_all (stream, converted_vcard, vcard_latin1_length, NULL, NULL, &error); + + if (error) { + display_error_message (gtk_widget_get_toplevel (GTK_WIDGET (target->selector)), error->message); + g_error_clear (&error); + } + + g_object_unref (contact); + g_free (temp); + g_free (vcard); + g_free (converted_vcard); } + + g_output_stream_close (stream); } + if (stream) + g_object_unref (stream); + sync(); if (contacts != NULL) g_list_free (contacts); - gnome_vfs_close (handle); g_object_unref (book); g_free (dest_uri); g_free (uri); + + if (error) { + display_error_message (gtk_widget_get_toplevel (GTK_WIDGET (target->selector)), error->message); + g_error_free (error); + } } static void diff --git a/plugins/publish-calendar/ChangeLog b/plugins/publish-calendar/ChangeLog index 7d1a09468e..7837857825 100644 --- a/plugins/publish-calendar/ChangeLog +++ b/plugins/publish-calendar/ChangeLog @@ -1,3 +1,19 @@ +2008-04-17 Milan Crha + + ** Part of fix for bug #526739 + + * publish-format-fb.h: (publish_calendar_as_fb): + * publish-format-fb.c: (write_calendar), (publish_calendar_as_fb): + * publish-format-ical.h: (publish_calendar_as_ical): + * publish-format-ical.c: (write_calendar), (publish_calendar_as_ical): + Use gio GOutputStream instead of gnome-vfs handle. + * url-editor-dialog.c: (create_uri): Use glib function to escape URI. + * publish-location.c: (migrateURI): Use EUri to parse URI. + * publish-calendar.c: (publish_online), (unmount_done_cb), + (struct mnt_struct), (mount_ready_cb), (ask_password), (ask_question), + (mount_first), (publish): + Use gio instead of gnome-vfs for opening (remote) files. + 2007-12-14 Tobias Mueller Patch by diff --git a/plugins/publish-calendar/publish-calendar.c b/plugins/publish-calendar/publish-calendar.c index fd5b283c1a..29788afa39 100644 --- a/plugins/publish-calendar/publish-calendar.c +++ b/plugins/publish-calendar/publish-calendar.c @@ -24,7 +24,8 @@ #include #include #include -#include +#include +#include #include #include #include @@ -62,16 +63,229 @@ publish_uri_async (EPublishUri *uri) } } +static void +publish_online (EPublishUri *uri, GFile *file, GError **perror) +{ + GOutputStream *stream; + GError *error = NULL; + + stream = G_OUTPUT_STREAM (g_file_replace (file, NULL, FALSE, G_FILE_CREATE_NONE, NULL, &error)); + + if (!stream || error) { + if (stream) + g_object_unref (stream); + + if (perror) { + *perror = error; + } else if (error) { + g_warning ("Couldn't open %s: %s", uri->location, error->message); + g_error_free (error); + } else { + g_warning ("Couldn't open %s: Unknown error", uri->location); + } + return; + } + + switch (uri->publish_format) { + case URI_PUBLISH_AS_ICAL: + publish_calendar_as_ical (stream, uri); + break; + case URI_PUBLISH_AS_FB: + publish_calendar_as_fb (stream, uri); + break; + /* + case URI_PUBLISH_AS_HTML: + publish_calendar_as_html (handle, uri); + break; + */ + } + + update_timestamp (uri); + + g_output_stream_close (stream, NULL, NULL); + g_object_unref (stream); +} + +static void +unmount_done_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) +{ + GError *error = NULL; + + g_mount_unmount_finish (G_MOUNT (source_object), res, &error); + + if (error) { + g_warning ("Unmount failed: %s", error->message); + g_error_free (error); + } + + g_object_unref (source_object); +} + +struct mnt_struct { + EPublishUri *uri; + GFile *file; + GMountOperation *mount_op; +}; + +static void +mount_ready_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) +{ + struct mnt_struct *ms = (struct mnt_struct *) user_data; + GError *error = NULL; + GMount *mount; + + g_file_mount_enclosing_volume_finish (G_FILE (source_object), res, &error); + + if (error) { + if (error->code != G_IO_ERROR_CANCELLED) + g_warning ("Mount of %s failed: %s", ms->uri->location, error->message); + + g_error_free (error); + if (ms) + g_object_unref (ms->mount_op); + g_free (ms); + + g_object_unref (source_object); + + return; + } + + g_return_if_fail (ms != NULL); + + publish_online (ms->uri, ms->file, NULL); + + g_object_unref (ms->mount_op); + g_free (ms); + + mount = g_file_find_enclosing_mount (G_FILE (source_object), NULL, NULL); + if (mount) + g_mount_unmount (mount, G_MOUNT_UNMOUNT_NONE, NULL, unmount_done_cb, NULL); + + g_object_unref (source_object); +} + +static void +ask_password (GMountOperation *op, const gchar *message, const gchar *default_user, const gchar *default_domain, GAskPasswordFlags flags, gpointer user_data) +{ + struct mnt_struct *ms = (struct mnt_struct *) user_data; + gchar *username, *password; + gboolean req_pass = FALSE; + EUri *euri; + + g_return_if_fail (ms != NULL); + + /* we can ask only for a password */ + if ((flags & G_ASK_PASSWORD_NEED_PASSWORD) == 0) + return; + + euri = e_uri_new (ms->uri->location); + username = euri->user; + password = e_passwords_get_password ("Calendar", ms->uri->location); + req_pass = ((username && *username) && !(ms->uri->service_type == TYPE_ANON_FTP && + !strcmp (username, "anonymous"))) ? TRUE:FALSE; + + if (!password && req_pass) { + gboolean remember = FALSE; + + password = e_passwords_ask_password (_("Enter password"), "", ms->uri->location, message, + E_PASSWORDS_REMEMBER_FOREVER|E_PASSWORDS_SECRET|E_PASSWORDS_ONLINE, + &remember, + NULL); + + if (!password) { + /* user canceled password dialog */ + g_mount_operation_reply (op, G_MOUNT_OPERATION_ABORTED); + e_uri_free (euri); + + return; + } + } + + if (!req_pass) + g_mount_operation_set_anonymous (op, TRUE); + else { + g_mount_operation_set_anonymous (op, FALSE); + g_mount_operation_set_username (op, username); + g_mount_operation_set_password (op, password); + } + + g_mount_operation_reply (op, G_MOUNT_OPERATION_HANDLED); + + e_uri_free (euri); +} + +static void +ask_question (GMountOperation *op, const char *message, const char *choices[]) +{ + /* this has been stolen from file-chooser */ + GtkWidget *dialog; + int cnt, len; + char *primary; + const char *secondary = NULL; + int res; + + primary = strstr (message, "\n"); + if (primary) { + secondary = primary + 1; + primary = g_strndup (message, strlen (message) - strlen (primary)); + } + + gdk_threads_enter (); + dialog = gtk_message_dialog_new (NULL, + 0, GTK_MESSAGE_QUESTION, + GTK_BUTTONS_NONE, "%s", primary); + g_free (primary); + + if (secondary) { + gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), + "%s", secondary); + } + + if (choices) { + /* First count the items in the list then + * add the buttons in reverse order */ + for (len = 0; choices[len] != NULL; len++) { + ; + } + + for (cnt = len - 1; cnt >= 0; cnt--) { + gtk_dialog_add_button (GTK_DIALOG (dialog), choices[cnt], cnt); + } + } + + res = gtk_dialog_run (GTK_DIALOG (dialog)); + if (res >= 0) { + g_mount_operation_set_choice (op, res); + g_mount_operation_reply (op, G_MOUNT_OPERATION_HANDLED); + } else { + g_mount_operation_reply (op, G_MOUNT_OPERATION_ABORTED); + } + + gtk_widget_destroy (GTK_WIDGET (dialog)); + gdk_threads_leave (); +} + +static void +mount_first (EPublishUri *uri, GFile *file) +{ + struct mnt_struct *ms = g_malloc (sizeof (struct mnt_struct)); + + ms->uri = uri; + ms->file = g_object_ref (file); + ms->mount_op = g_mount_operation_new (); + + g_signal_connect (ms->mount_op, "ask-password", G_CALLBACK (ask_password), ms); + g_signal_connect (ms->mount_op, "ask-question", G_CALLBACK (ask_question), ms); + + g_file_mount_enclosing_volume (file, G_MOUNT_MOUNT_NONE, ms->mount_op, NULL, mount_ready_cb, ms); +} + static void publish (EPublishUri *uri) { if (online) { - GnomeVFSURI *vfs_uri = NULL; - GnomeVFSResult result; - GnomeVFSHandle *handle; - gchar *password; - const char *username; - gboolean req_pass = FALSE; + GError *error = NULL; + GFile *file; if (g_slist_find (queued_publishes, uri)) queued_publishes = g_slist_remove (queued_publishes, uri); @@ -79,60 +293,25 @@ publish (EPublishUri *uri) if (!uri->enabled) return; - vfs_uri = gnome_vfs_uri_new (uri->location); + file = g_file_new_for_uri (uri->location); - password = e_passwords_get_password ("Calendar", uri->location); - username = gnome_vfs_uri_get_user_name (vfs_uri); - req_pass = ((username && *username) && !(uri->service_type == TYPE_ANON_FTP && - !strcmp (username, "anonymous"))) ? TRUE:FALSE; + g_return_if_fail (file != NULL); - if (!password && req_pass) { - gboolean remember = FALSE; - char *prompt = g_strdup_printf (_("Enter the password for `%s'"), uri->location); + publish_online (uri, file, &error); - password = e_passwords_ask_password (_("Enter password"), "", uri->location, prompt, - E_PASSWORDS_REMEMBER_FOREVER|E_PASSWORDS_SECRET|E_PASSWORDS_ONLINE, - &remember, - NULL); - g_free (prompt); - } - - gnome_vfs_uri_set_password (vfs_uri, password); - - if (vfs_uri == NULL) { - fprintf (stderr, "Couldn't create uri %s\n", uri->location); - /* FIXME: EError */ - g_free (password); - return; - } + if (error && error->domain == G_IO_ERROR && error->code == G_IO_ERROR_NOT_MOUNTED) { + g_error_free (error); + error = NULL; - result = gnome_vfs_create_uri (&handle, vfs_uri, GNOME_VFS_OPEN_WRITE, FALSE, 0666); - if (result != GNOME_VFS_OK) { - /* FIXME: EError */ - fprintf (stderr, "Couldn't open %s: %s\n", uri->location, gnome_vfs_result_to_string (result)); - g_free (password); - return; + mount_first (uri, file); } - switch (uri->publish_format) { - case URI_PUBLISH_AS_ICAL: - publish_calendar_as_ical (handle, uri); - break; - case URI_PUBLISH_AS_FB: - publish_calendar_as_fb (handle, uri); - break; -/* - case URI_PUBLISH_AS_HTML: - publish_calendar_as_html (handle, uri); - break; -*/ + if (error) { + g_warning ("Couldn't open %s: %s", uri->location, error->message); + g_error_free (error); } - update_timestamp (uri); - - result = gnome_vfs_close (handle); - gnome_vfs_uri_unref (vfs_uri); - g_free (password); + g_object_unref (file); } else { if (g_slist_find (queued_publishes, uri) == NULL) queued_publishes = g_slist_prepend (queued_publishes, uri); diff --git a/plugins/publish-calendar/publish-format-fb.c b/plugins/publish-calendar/publish-format-fb.c index 7a4eae3b65..711b68cea7 100644 --- a/plugins/publish-calendar/publish-format-fb.c +++ b/plugins/publish-calendar/publish-format-fb.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include @@ -32,7 +31,7 @@ #include "publish-format-fb.h" static gboolean -write_calendar (gchar *uid, ESourceList *source_list, GnomeVFSHandle *handle) +write_calendar (gchar *uid, ESourceList *source_list, GOutputStream *stream) { ESource *source; ECal *client = NULL; @@ -43,6 +42,7 @@ write_calendar (gchar *uid, ESourceList *source_list, GnomeVFSHandle *handle) icalcomponent *top_level; char *email = NULL; GList *users = NULL; + gboolean res = FALSE; utc = icaltimezone_get_utc_timezone (); start = time_day_begin_with_zone (start, utc); @@ -57,9 +57,11 @@ write_calendar (gchar *uid, ESourceList *source_list, GnomeVFSHandle *handle) } if (!e_cal_open (client, TRUE, &error)) { - /* FIXME: EError */ + if (error) { + g_warning ("%s", error->message); + g_error_free (error); + } g_object_unref (client); - g_error_free (error); return FALSE; } @@ -73,8 +75,6 @@ write_calendar (gchar *uid, ESourceList *source_list, GnomeVFSHandle *handle) if (e_cal_get_free_busy (client, users, start, end, &objects, &error)) { char *ical_string; - GnomeVFSFileSize bytes_written; - GnomeVFSResult result; while (objects) { ECalComponent *comp = objects->data; @@ -84,33 +84,27 @@ write_calendar (gchar *uid, ESourceList *source_list, GnomeVFSHandle *handle) } ical_string = icalcomponent_as_ical_string (top_level); - if ((result = gnome_vfs_write (handle, (gconstpointer) ical_string, strlen (ical_string), &bytes_written)) != GNOME_VFS_OK) { - /* FIXME: EError */ - gnome_vfs_close (handle); - return FALSE; - } - } else { - /* FIXME: EError */ - g_object_unref (client); - g_error_free (error); - if (users) - g_list_free (users); - g_free (email); + res = g_output_stream_write_all (stream, ical_string, strlen (ical_string), NULL, NULL, &error); - return FALSE; + g_free (ical_string); } if (users) g_list_free (users); g_free (email); - g_object_unref (client); - return TRUE; + + if (error) { + g_warning ("%s", error->message); + g_error_free (error); + } + + return res; } void -publish_calendar_as_fb (GnomeVFSHandle *handle, EPublishUri *uri) +publish_calendar_as_fb (GOutputStream *stream, EPublishUri *uri) { GSList *l; ESourceList *source_list; @@ -123,7 +117,8 @@ publish_calendar_as_fb (GnomeVFSHandle *handle, EPublishUri *uri) l = uri->events; while (l) { gchar *uid = l->data; - write_calendar (uid, source_list, handle); + if (!write_calendar (uid, source_list, stream)) + break; l = g_slist_next (l); } g_object_unref (source_list); diff --git a/plugins/publish-calendar/publish-format-fb.h b/plugins/publish-calendar/publish-format-fb.h index c6af2a886e..69be11394e 100644 --- a/plugins/publish-calendar/publish-format-fb.h +++ b/plugins/publish-calendar/publish-format-fb.h @@ -19,12 +19,12 @@ * */ -#include +#include #include "publish-location.h" #ifndef PUBLISH_FORMAT_FB_H #define PUBLISH_FORMAT_FB_H -void publish_calendar_as_fb (GnomeVFSHandle *handle, EPublishUri *uri); +void publish_calendar_as_fb (GOutputStream *stream, EPublishUri *uri); #endif diff --git a/plugins/publish-calendar/publish-format-ical.c b/plugins/publish-calendar/publish-format-ical.c index 5f620accc9..b1f160d98e 100644 --- a/plugins/publish-calendar/publish-format-ical.c +++ b/plugins/publish-calendar/publish-format-ical.c @@ -21,7 +21,6 @@ #include #include -#include #include #include #include @@ -65,13 +64,14 @@ append_tz_to_comp (gpointer key, gpointer value, icalcomponent *toplevel) } static gboolean -write_calendar (gchar *uid, ESourceList *source_list, GnomeVFSHandle *handle) +write_calendar (gchar *uid, ESourceList *source_list, GOutputStream *stream) { ESource *source; ECal *client = NULL; GError *error = NULL; GList *objects; icalcomponent *top_level; + gboolean res = FALSE; source = e_source_list_peek_source_by_uid (source_list, uid); if (source) @@ -82,9 +82,11 @@ write_calendar (gchar *uid, ESourceList *source_list, GnomeVFSHandle *handle) } if (!e_cal_open (client, TRUE, &error)) { - /* FIXME: EError */ + if (error) { + g_warning ("%s", error->message); + g_error_free (error); + } g_object_unref (client); - g_error_free (error); return FALSE; } @@ -93,8 +95,6 @@ write_calendar (gchar *uid, ESourceList *source_list, GnomeVFSHandle *handle) if (e_cal_get_object_list (client, "#t", &objects, &error)) { char *ical_string; - GnomeVFSFileSize bytes_written = 0; - GnomeVFSResult result; CompTzData tdata; tdata.zones = g_hash_table_new (g_str_hash, g_str_equal); @@ -113,24 +113,22 @@ write_calendar (gchar *uid, ESourceList *source_list, GnomeVFSHandle *handle) tdata.zones = NULL; ical_string = icalcomponent_as_ical_string (top_level); - if ((result = gnome_vfs_write (handle, (gconstpointer) ical_string, strlen (ical_string), &bytes_written)) != GNOME_VFS_OK) { - /* FIXME: EError */ - gnome_vfs_close (handle); - return FALSE; - } - } else { - /* FIXME: EError */ - g_object_unref (client); - g_error_free (error); - return FALSE; + res = g_output_stream_write_all (stream, ical_string, strlen (ical_string), NULL, NULL, &error); + g_free (ical_string); } g_object_unref (client); - return TRUE; + + if (error) { + g_warning ("%s", error->message); + g_error_free (error); + } + + return res; } void -publish_calendar_as_ical (GnomeVFSHandle *handle, EPublishUri *uri) +publish_calendar_as_ical (GOutputStream *stream, EPublishUri *uri) { GSList *l; ESourceList *source_list; @@ -143,7 +141,8 @@ publish_calendar_as_ical (GnomeVFSHandle *handle, EPublishUri *uri) l = uri->events; while (l) { gchar *uid = l->data; - write_calendar (uid, source_list, handle); + if (!write_calendar (uid, source_list, stream)) + break; l = g_slist_next (l); } g_object_unref (source_list); diff --git a/plugins/publish-calendar/publish-format-ical.h b/plugins/publish-calendar/publish-format-ical.h index 35040d110a..ae76bc076f 100644 --- a/plugins/publish-calendar/publish-format-ical.h +++ b/plugins/publish-calendar/publish-format-ical.h @@ -19,12 +19,12 @@ * */ -#include +#include #include "publish-location.h" #ifndef PUBLISH_FORMAT_ICAL_H #define PUBLISH_FORMAT_ICAL_H -void publish_calendar_as_ical (GnomeVFSHandle *handle, EPublishUri *uri); +void publish_calendar_as_ical (GOutputStream *stream, EPublishUri *uri); #endif diff --git a/plugins/publish-calendar/publish-location.c b/plugins/publish-calendar/publish-location.c index e4414a8109..34793bf932 100644 --- a/plugins/publish-calendar/publish-location.c +++ b/plugins/publish-calendar/publish-location.c @@ -24,7 +24,7 @@ #include "publish-location.h" #include #include -#include +#include #include #include @@ -36,8 +36,8 @@ migrateURI (const gchar *xml, xmlDocPtr doc) xmlChar *location, *enabled, *frequency, *username; xmlNodePtr root, p; EPublishUri *uri; - GnomeVFSURI *vfs_uri; gchar *password, *temp; + EUri *euri; client = gconf_client_get_default (); uris = gconf_client_get_list (client, "/apps/evolution/calendar/publish/uris", GCONF_VALUE_STRING, NULL); @@ -59,18 +59,22 @@ migrateURI (const gchar *xml, xmlDocPtr doc) frequency = xmlGetProp (root, (const unsigned char *)"frequency"); username = xmlGetProp (root, (const unsigned char *)"username"); - vfs_uri = gnome_vfs_uri_new ((char *)location); + euri = e_uri_new ((const char *)location); - if (!vfs_uri) { + if (!euri) { g_warning ("Could not form the uri for %s \n", location); goto cleanup; } - gnome_vfs_uri_set_user_name ((GnomeVFSURI *)vfs_uri, (char *)username); - temp = gnome_vfs_uri_to_string (vfs_uri, GNOME_VFS_URI_HIDE_TOPLEVEL_METHOD | GNOME_VFS_URI_HIDE_PASSWORD); - uri->location = g_strdup_printf ("dav://%s", temp); + if (euri->user) + g_free (euri->user); + + euri->user = g_strdup ((const char *)username); + + temp = e_uri_to_string (euri, FALSE); + uri->location = g_strdup_printf ("dav://%s", strstr (temp, "//") + 2); g_free (temp); - gnome_vfs_uri_unref (vfs_uri); + e_uri_free (euri); if (enabled != NULL) uri->enabled = atoi ((char *)enabled); diff --git a/plugins/publish-calendar/url-editor-dialog.c b/plugins/publish-calendar/url-editor-dialog.c index 627c64fa87..f818cabb67 100644 --- a/plugins/publish-calendar/url-editor-dialog.c +++ b/plugins/publish-calendar/url-editor-dialog.c @@ -23,7 +23,7 @@ #include "url-editor-dialog.h" #include #include -#include +#include #include #include @@ -46,7 +46,7 @@ create_uri (UrlEditorDialog *dialog) server = g_strdup (gtk_entry_get_text (GTK_ENTRY (dialog->server_entry))); file = g_strdup (gtk_entry_get_text (GTK_ENTRY (dialog->file_entry))); port = g_strdup (gtk_entry_get_text (GTK_ENTRY (dialog->port_entry))); - username = gnome_vfs_escape_string (gtk_entry_get_text (GTK_ENTRY (dialog->username_entry))); + username = g_uri_escape_string (gtk_entry_get_text (GTK_ENTRY (dialog->username_entry)), "", FALSE); password = g_strdup (gtk_entry_get_text (GTK_ENTRY (dialog->password_entry))); switch (uri->service_type) { diff --git a/plugins/save-calendar/ChangeLog b/plugins/save-calendar/ChangeLog index 0b6ecdaf34..3488ec9432 100644 --- a/plugins/save-calendar/ChangeLog +++ b/plugins/save-calendar/ChangeLog @@ -1,3 +1,14 @@ +2008-04-17 Milan Crha + + ** Part of fix for bug #526739 + + * ical-format.c: (do_save_calendar_ical): + * csv-format.c: (do_save_calendar_csv): + * rdf-format.c: (do_save_calendar_rdf): + Use gio GOutpuStream instead of gnome-vfs handle. + * format-handler.h: (open_for_writing): + * save-calendar.c: (open_for_writing): New helper function. + 2008-02-18 Srinivasa Ragavan * ical-format.c: (do_save_calendar_ical): Patch from OpenSUSE diff --git a/plugins/save-calendar/csv-format.c b/plugins/save-calendar/csv-format.c index e26b758cd4..4709b18305 100644 --- a/plugins/save-calendar/csv-format.c +++ b/plugins/save-calendar/csv-format.c @@ -36,7 +36,6 @@ #include #include "calendar/common/authentication.h" #include -#include #include #include "e-util/e-error.h" @@ -323,14 +322,11 @@ do_save_calendar_csv (FormatHandler *handler, EPlugin *ep, ECalPopupTargetSource ECal *source_client; GError *error = NULL; GList *objects=NULL; - GnomeVFSResult result; - GnomeVFSHandle *handle; - GnomeVFSURI *uri; + GOutputStream *stream; GString *line = NULL; CsvConfig *config = NULL; CsvPluginData *d = handler->data; const gchar *tmp = NULL; - gboolean doit = TRUE; if (!dest_uri) return; @@ -356,22 +352,9 @@ do_save_calendar_csv (FormatHandler *handler, EPlugin *ep, ECalPopupTargetSource config->quote = userstring_to_systemstring (tmp?tmp:"\""); config->header = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (d->header_check)); - uri = gnome_vfs_uri_new (dest_uri); + stream = open_for_writing (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (target->selector))), dest_uri, &error); - result = gnome_vfs_open_uri (&handle, uri, GNOME_VFS_OPEN_READ); - if (result == GNOME_VFS_OK) - doit = e_error_run(GTK_WINDOW(gtk_widget_get_toplevel (GTK_WIDGET (target->selector))), - E_ERROR_ASK_FILE_EXISTS_OVERWRITE, dest_uri, NULL) == GTK_RESPONSE_OK; - - if (doit) { - result = gnome_vfs_open_uri (&handle, uri, GNOME_VFS_OPEN_WRITE); - if (result != GNOME_VFS_OK) { - gnome_vfs_create (&handle, dest_uri, GNOME_VFS_OPEN_WRITE, TRUE, GNOME_VFS_PERM_USER_ALL); - result = gnome_vfs_open_uri (&handle, uri, GNOME_VFS_OPEN_WRITE); - } - } - - if (result == GNOME_VFS_OK && doit && e_cal_get_object_list_as_comp (source_client, "#t", &objects, NULL)) { + if (stream && e_cal_get_object_list_as_comp (source_client, "#t", &objects, NULL)) { if (config->header) { @@ -406,11 +389,10 @@ do_save_calendar_csv (FormatHandler *handler, EPlugin *ep, ECalPopupTargetSource line = g_string_append (line, config->newline); - gnome_vfs_write (handle, line->str, line->len, NULL); + g_output_stream_write_all (stream, line->str, line->len, NULL, NULL, NULL); g_string_free (line, TRUE); } - while (objects != NULL) { ECalComponent *comp = objects->data; gchar *delimiter_temp = NULL; @@ -513,7 +495,7 @@ do_save_calendar_csv (FormatHandler *handler, EPlugin *ep, ECalPopupTargetSource * http://www.gnome.org/projects/evolution/developer-doc/libecal/ECalComponent.html * #e-cal-component-get-last-modified */ - gnome_vfs_write (handle, line->str, line->len, NULL); + g_output_stream_write_all (stream, line->str, line->len, NULL, NULL, &error); /* It's written, so we can free it */ g_string_free (line, TRUE); @@ -521,9 +503,12 @@ do_save_calendar_csv (FormatHandler *handler, EPlugin *ep, ECalPopupTargetSource objects = g_list_next (objects); } - gnome_vfs_close (handle); + g_output_stream_close (stream, NULL, NULL); } + if (stream) + g_object_unref (stream); + g_object_unref (source_client); g_free (config->delimiter); @@ -531,6 +516,11 @@ do_save_calendar_csv (FormatHandler *handler, EPlugin *ep, ECalPopupTargetSource g_free (config->newline); g_free (config); + if (error) { + display_error_message (gtk_widget_get_toplevel (GTK_WIDGET (target->selector)), error); + g_error_free (error); + } + return; } diff --git a/plugins/save-calendar/format-handler.h b/plugins/save-calendar/format-handler.h index 0dd23f6022..41b2cfb68f 100644 --- a/plugins/save-calendar/format-handler.h +++ b/plugins/save-calendar/format-handler.h @@ -25,6 +25,7 @@ #include #include +#include #include #include #include @@ -47,3 +48,5 @@ struct _FormatHandler FormatHandler *csv_format_handler_new (void); FormatHandler *ical_format_handler_new (void); FormatHandler *rdf_format_handler_new (void); + +GOutputStream *open_for_writing (GtkWindow *parent, const char *uri, GError **error); diff --git a/plugins/save-calendar/ical-format.c b/plugins/save-calendar/ical-format.c index a5a533206d..b871657280 100644 --- a/plugins/save-calendar/ical-format.c +++ b/plugins/save-calendar/ical-format.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include @@ -37,7 +36,6 @@ #include #include #include -#include #include #include "format-handler.h" @@ -96,8 +94,6 @@ do_save_calendar_ical (FormatHandler *handler, EPlugin *ep, ECalPopupTargetSourc GError *error = NULL; GList *objects; icalcomponent *top_level = NULL; - GnomeVFSURI *uri; - gboolean doit = TRUE; primary_source = e_source_selector_peek_primary_selection (target->selector); @@ -118,9 +114,8 @@ do_save_calendar_ical (FormatHandler *handler, EPlugin *ep, ECalPopupTargetSourc error = NULL; if (e_cal_get_object_list (source_client, "#t", &objects, &error)) { - GnomeVFSResult result; - GnomeVFSHandle *handle; CompTzData tdata; + GOutputStream *stream; tdata.zones = g_hash_table_new (g_str_hash, g_str_equal); tdata.ecal = source_client; @@ -141,38 +136,20 @@ do_save_calendar_ical (FormatHandler *handler, EPlugin *ep, ECalPopupTargetSourc tdata.zones = NULL; /* save the file */ - uri = gnome_vfs_uri_new (dest_uri); - - result = gnome_vfs_open_uri (&handle, uri, GNOME_VFS_OPEN_READ); - if (result == GNOME_VFS_OK) - doit = e_error_run(GTK_WINDOW(gtk_widget_get_toplevel (GTK_WIDGET (target->selector))), - E_ERROR_ASK_FILE_EXISTS_OVERWRITE, dest_uri, NULL) == GTK_RESPONSE_OK; - - if (doit) { - result = gnome_vfs_open (&handle, dest_uri, GNOME_VFS_OPEN_WRITE); - if (result != GNOME_VFS_OK) { - if ((result = gnome_vfs_create (&handle, dest_uri, GNOME_VFS_OPEN_WRITE, - TRUE, GNOME_VFS_PERM_USER_ALL)) != GNOME_VFS_OK) { - display_error_message (gtk_widget_get_toplevel (GTK_WIDGET (target->selector)), - gnome_vfs_result_to_string (result)); - } - } - - if (result == GNOME_VFS_OK) { - char *ical_str; - GnomeVFSFileSize bytes_written; - - ical_str = icalcomponent_as_ical_string (top_level); - if ((result = gnome_vfs_write (handle, (gconstpointer) ical_str, strlen (ical_str), &bytes_written)) - != GNOME_VFS_OK) { - display_error_message (gtk_widget_get_toplevel (GTK_WIDGET (target->selector)), - gnome_vfs_result_to_string (result)); - } - - gnome_vfs_close (handle); - } + stream = open_for_writing (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (target->selector))), dest_uri, &error); + + if (stream) { + char *ical_str = icalcomponent_as_ical_string (top_level); + + g_output_stream_write_all (stream, ical_str, strlen (ical_str), NULL, NULL, &error); + g_output_stream_close (stream, NULL, NULL); + + g_object_unref (stream); + g_free (ical_str); } - } else { + } + + if (error) { display_error_message (gtk_widget_get_toplevel (GTK_WIDGET (target->selector)), error->message); g_error_free (error); } diff --git a/plugins/save-calendar/rdf-format.c b/plugins/save-calendar/rdf-format.c index 445dbd6cbf..6963c4bf10 100644 --- a/plugins/save-calendar/rdf-format.c +++ b/plugins/save-calendar/rdf-format.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include @@ -196,11 +195,8 @@ do_save_calendar_rdf (FormatHandler *handler, EPlugin *ep, ECalPopupTargetSource ECal *source_client; GError *error = NULL; GList *objects=NULL; - GnomeVFSResult result; - GnomeVFSHandle *handle; - GnomeVFSURI *uri; gchar *temp = NULL; - gboolean doit = TRUE; + GOutputStream *stream; if (!dest_uri) return; @@ -216,23 +212,9 @@ do_save_calendar_rdf (FormatHandler *handler, EPlugin *ep, ECalPopupTargetSource return; } - uri = gnome_vfs_uri_new (dest_uri); + stream = open_for_writing (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (target->selector))), dest_uri, &error); - result = gnome_vfs_open_uri (&handle, uri, GNOME_VFS_OPEN_READ); - if (result == GNOME_VFS_OK) - doit = e_error_run(GTK_WINDOW(gtk_widget_get_toplevel (GTK_WIDGET (target->selector))), - E_ERROR_ASK_FILE_EXISTS_OVERWRITE, dest_uri, NULL) == GTK_RESPONSE_OK; - - if (doit) { - result = gnome_vfs_open_uri (&handle, uri, GNOME_VFS_OPEN_WRITE); - if (result != GNOME_VFS_OK) { - gnome_vfs_create (&handle, dest_uri, GNOME_VFS_OPEN_WRITE, TRUE, GNOME_VFS_PERM_USER_ALL); - result = gnome_vfs_open_uri (&handle, uri, GNOME_VFS_OPEN_WRITE); - } - } - - - if (result == GNOME_VFS_OK && doit && e_cal_get_object_list_as_comp (source_client, "#t", &objects, NULL)) { + if (stream && e_cal_get_object_list_as_comp (source_client, "#t", &objects, NULL)) { xmlBufferPtr buffer=xmlBufferCreate(); xmlDocPtr doc = xmlNewDoc((xmlChar *) "1.0"); xmlNodePtr fnode = doc->children; @@ -367,18 +349,26 @@ do_save_calendar_rdf (FormatHandler *handler, EPlugin *ep, ECalPopupTargetSource objects = g_list_next (objects); } - /* I used a buffer rather than xmlDocDump: I want gnome-vfs support */ + /* I used a buffer rather than xmlDocDump: I want gio support */ xmlNodeDump (buffer, doc, doc->children, 2, 1); - gnome_vfs_write (handle, xmlBufferContent (buffer), xmlBufferLength (buffer), NULL); + g_output_stream_write_all (stream, xmlBufferContent (buffer), xmlBufferLength (buffer), NULL, NULL, &error); + g_output_stream_close (stream, NULL, NULL); xmlBufferFree (buffer); xmlFreeDoc (doc); - gnome_vfs_close (handle); } + if (stream) + g_object_unref (stream); + g_object_unref (source_client); + if (error) { + display_error_message (gtk_widget_get_toplevel (GTK_WIDGET (target->selector)), error); + g_error_free (error); + } + return; } diff --git a/plugins/save-calendar/save-calendar.c b/plugins/save-calendar/save-calendar.c index f65dd64a5f..0ed4030b8b 100644 --- a/plugins/save-calendar/save-calendar.c +++ b/plugins/save-calendar/save-calendar.c @@ -28,6 +28,7 @@ #include #include +#include #include #include #include @@ -37,7 +38,7 @@ #include #include #include -#include +#include #include #include "format-handler.h" @@ -208,6 +209,54 @@ ask_destination_and_save (EPlugin *ep, ECalPopupTargetSource *target, ECalSource } +/* Returns output stream for the uri, or NULL on any error. + When done with the stream, just g_output_stream_close and g_object_unref it. + It will ask for overwrite if file already exists. +*/ +GOutputStream * +open_for_writing (GtkWindow *parent, const char *uri, GError **error) +{ + GFile *file; + GFileOutputStream *fostream; + GError *err = NULL; + + g_return_val_if_fail (uri != NULL, NULL); + + file = g_file_new_for_uri (uri); + + g_return_val_if_fail (file != NULL, NULL); + + fostream = g_file_create (file, G_FILE_CREATE_NONE, NULL, &err); + + if (err && err->code == G_IO_ERROR_EXISTS) { + g_clear_error (&err); + + if (e_error_run (parent, E_ERROR_ASK_FILE_EXISTS_OVERWRITE, uri, NULL) == GTK_RESPONSE_OK) { + fostream = g_file_replace (file, NULL, FALSE, G_FILE_CREATE_NONE, NULL, &err); + + if (err && fostream) { + g_object_unref (fostream); + fostream = NULL; + } + } else if (fostream) { + g_object_unref (fostream); + fostream = NULL; + } + } + + g_object_unref (file); + + if (error && err) + *error = err; + else if (err) + g_error_free (err); + + if (fostream) + return G_OUTPUT_STREAM (fostream); + + return NULL; +} + void org_gnome_save_calendar (EPlugin *ep, ECalPopupTargetSource *target) { diff --git a/shell/ChangeLog b/shell/ChangeLog index 7c26a8a006..6165e85386 100644 --- a/shell/ChangeLog +++ b/shell/ChangeLog @@ -1,3 +1,10 @@ +2008-04-17 Milan Crha + + ** Part of fix for bug #526739 + + * e-shell-window-commands.c: (command_quick_reference): + Use gio instead of gnome-vfs. + 2008-04-07 Ondrej Jirman ** Fix for bug #525238 diff --git a/shell/e-shell-window-commands.c b/shell/e-shell-window-commands.c index 38477f67a7..424306d380 100644 --- a/shell/e-shell-window-commands.c +++ b/shell/e-shell-window-commands.c @@ -31,9 +31,7 @@ #include #include -#include -#include -#include +#include #include @@ -781,7 +779,6 @@ command_quick_reference (BonoboUIComponent *uih, const char *path) { char *quickref; - GnomeVFSMimeApplication *app; const gchar * const *language_names; language_names = g_get_language_names (); @@ -796,20 +793,21 @@ command_quick_reference (BonoboUIComponent *uih, quickref = g_build_filename (EVOLUTION_HELPDIR, "quickref", lang, "quickref.pdf", NULL); if (g_file_test (quickref, G_FILE_TEST_EXISTS)) { - app = gnome_vfs_mime_get_default_application ("application/pdf"); + GFile *file = g_file_new_for_path (quickref); - if (app) { - GList *uris = NULL; - char *uri; + if (file) { + GError *error = NULL; + char *uri = g_file_get_uri (file); - uri = gnome_vfs_get_uri_from_local_path (quickref); - uris = g_list_append (uris, uri); + g_app_info_launch_default_for_uri (uri, NULL, &error); - gnome_vfs_mime_application_launch (app, uris); + if (error) { + g_warning ("%s", error->message); + g_error_free (error); + } + g_object_unref (file); g_free (uri); - g_list_free (uris); - gnome_vfs_mime_application_free (app); } g_free (quickref); diff --git a/widgets/misc/ChangeLog b/widgets/misc/ChangeLog index dd708047a7..608a0db842 100644 --- a/widgets/misc/ChangeLog +++ b/widgets/misc/ChangeLog @@ -1,3 +1,17 @@ +2008-04-17 Milan Crha + + ** Part of fix for bug #526739 + + * e-attachment.h: (struct _EAttachment): + * e-attachment.c: (finalise), (init), (attachment_guess_mime_type), + (e_attachment_new), (struct DownloadInfo), (download_info_free), + (data_ready_cb), (download_to_local_path), + (e_attachment_new_remote_file): + Use gio instead of gnome-vfs to download remote files. + * e-image-chooser.c: (image_drag_data_received_cb): + Use new util function to read file. + * e-attachment-bar.c: (size_to_string): Stolen from gnome-vfs. + 2008-04-14 Matthew Barnes * e-attachment-bar.c diff --git a/widgets/misc/e-attachment-bar.c b/widgets/misc/e-attachment-bar.c index ac25f628dd..0ef3ba21f7 100644 --- a/widgets/misc/e-attachment-bar.c +++ b/widgets/misc/e-attachment-bar.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include @@ -95,15 +94,31 @@ static void update (EAttachmentBar *bar); static char * size_to_string (gulong size) { - char *size_string; + /* code copied from gnome-vfs */ + #define KILOBYTE_FACTOR 1024.0 + #define MEGABYTE_FACTOR (1024.0 * 1024.0) + #define GIGABYTE_FACTOR (1024.0 * 1024.0 * 1024.0) - /* FIXME: The following should probably go into a separate module, as - we might have to do the same thing in other places as well. Also, - I am not sure this will be OK for all the languages. */ - - size_string = gnome_vfs_format_file_size_for_display (size); + if (size < (gulong) KILOBYTE_FACTOR) { + return g_strdup_printf (ngettext ("%u byte", "%u bytes",(guint) size), (guint) size); + } else { + gdouble displayed_size; + + if (size < (gulong) MEGABYTE_FACTOR) { + displayed_size = (gdouble) size / KILOBYTE_FACTOR; + return g_strdup_printf (_("%.1f KB"), displayed_size); + } else if (size < (gulong) GIGABYTE_FACTOR) { + displayed_size = (gdouble) size / MEGABYTE_FACTOR; + return g_strdup_printf (_("%.1f MB"), displayed_size); + } else { + displayed_size = (gdouble) size / GIGABYTE_FACTOR; + return g_strdup_printf (_("%.1f GB"), displayed_size); + } + } - return size_string; + #undef KILOBYTE_FACTOR + #undef MEGABYTE_FACTOR + #undef GIGABYTE_FACTOR } /* Attachment handling functions. */ diff --git a/widgets/misc/e-attachment.c b/widgets/misc/e-attachment.c index 1383335499..27729b396f 100644 --- a/widgets/misc/e-attachment.c +++ b/widgets/misc/e-attachment.c @@ -29,7 +29,7 @@ #include #ifdef G_OS_WIN32 -/* Include early (as the gnome-vfs stuff below will +/* Include early (as the gio stuff below will * include it anyway, sigh) to workaround the DATADIR problem. * (and the headers it includes) stomps all over the * namespace like a baboon on crack, and especially the DATADIR enum @@ -50,12 +50,13 @@ #include #include #include -#include +#include #include #include #include +#include "e-util/e-util.h" #include "e-util/e-error.h" #include "e-util/e-mktemp.h" #include "e-util/e-util-private.h" @@ -97,8 +98,11 @@ finalise (GObject *object) if (attachment->pixbuf_cache != NULL) g_object_unref (attachment->pixbuf_cache); } else { - if (attachment->handle) - gnome_vfs_async_cancel(attachment->handle); + if (attachment->cancellable) { + /* the operation is still running, so cancel it */ + g_cancellable_cancel (attachment->cancellable); + attachment->cancellable = NULL; + } g_free (attachment->description); } @@ -170,6 +174,7 @@ init (EAttachment *attachment) attachment->sign = CAMEL_CIPHER_VALIDITY_SIGN_NONE; attachment->encrypt = CAMEL_CIPHER_VALIDITY_ENCRYPT_NONE; attachment->store_uri = NULL; + attachment->cancellable = NULL; } GType @@ -226,57 +231,31 @@ file_ext_is (const char *file_name, const char *ext) static char * attachment_guess_mime_type (const char *file_name) { - GnomeVFSFileInfo *info; - GnomeVFSResult result; - char *type = NULL; - - info = gnome_vfs_file_info_new (); - result = gnome_vfs_get_file_info (file_name, info, - GNOME_VFS_FILE_INFO_GET_MIME_TYPE | - GNOME_VFS_FILE_INFO_FORCE_SLOW_MIME_TYPE | - GNOME_VFS_FILE_INFO_FOLLOW_LINKS); - - if (result != GNOME_VFS_OK) { - CamelURL *url; - char *uri; - - url = camel_url_new ("file://", NULL); - camel_url_set_path (url, file_name); - uri = camel_url_to_string (url, 0); - camel_url_free (url); - - result = gnome_vfs_get_file_info (uri, info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE | GNOME_VFS_FILE_INFO_FORCE_SLOW_MIME_TYPE | GNOME_VFS_FILE_INFO_FOLLOW_LINKS); - - g_free (uri); - } - - if (result == GNOME_VFS_OK) { - gchar *content = NULL; + char *type; + gchar *content = NULL; - type = g_strdup (gnome_vfs_file_info_get_mime_type (info)); + type = e_util_guess_mime_type (file_name); - if (type && strcmp (type, "text/directory") == 0 && - file_ext_is (file_name, ".vcf") && - g_file_get_contents (file_name, &content, NULL, NULL) && - content) { - EVCard *vc = e_vcard_new_from_string (content); - if (vc) { - g_free (type); - g_object_unref (G_OBJECT (vc)); + if (type && strcmp (type, "text/directory") == 0 && + file_ext_is (file_name, ".vcf") && + g_file_get_contents (file_name, &content, NULL, NULL) && + content) { + EVCard *vc = e_vcard_new_from_string (content); - type = g_strdup ("text/x-vcard"); - } + if (vc) { + g_free (type); + g_object_unref (G_OBJECT (vc)); + type = g_strdup ("text/x-vcard"); } - g_free (content); } - gnome_vfs_file_info_unref (info); + g_free (content); if (type) { - /* gnome_vfs can sometimes return invalid type, so check for it */ + /* Check if returned mime_type is valid */ CamelContentType *ctype = camel_content_type_decode (type); if (!ctype) { @@ -376,7 +355,7 @@ e_attachment_new (const char *file_name, const char *disposition, CamelException new->body = part; new->size = statbuf.st_size; new->guessed_type = TRUE; - new->handle = NULL; + new->cancellable = NULL; new->is_available_local = TRUE; new->file_name = filename; @@ -389,93 +368,173 @@ e_attachment_new (const char *file_name, const char *disposition, CamelException } -typedef struct DownloadInfo { +typedef struct { EAttachment *attachment; char *file_name; char *uri; GtkWindow *parent; /* for error dialog */ + + guint64 file_size; /* zero indicates unknown size */ + GInputStream *istream; /* read from here ... */ + GOutputStream *ostream; /* ...and write into this. */ + gboolean was_error; + GCancellable *cancellable; + + void *buffer; /* read into this, not more than buffer_size bytes */ + gsize buffer_size; } DownloadInfo; -static int -async_progress_update_cb (GnomeVFSAsyncHandle *handle, - GnomeVFSXferProgressInfo *info, - DownloadInfo *download_info) +static void +download_info_free (DownloadInfo *download_info) { - switch (info->status) { - case GNOME_VFS_XFER_PROGRESS_STATUS_OK: - if (info->file_size) { - download_info->attachment->percentage = info->bytes_copied*100/info->file_size; - g_signal_emit (download_info->attachment, signals[UPDATE], 0); + /* if there was an error, then free attachment too */ + if (download_info->was_error) + g_object_unref (download_info->attachment); + + if (download_info->ostream) + g_object_unref (download_info->ostream); + + if (download_info->istream) + g_object_unref (download_info->istream); + + if (download_info->cancellable) + g_object_unref (download_info->cancellable); + + g_free (download_info->file_name); + g_free (download_info->uri); + g_free (download_info->buffer); + g_free (download_info); +} + +static void +data_ready_cb (GObject *source_object, GAsyncResult *res, gpointer user_data) +{ + DownloadInfo *download_info = (DownloadInfo *)user_data; + GError *error = NULL; + gssize read; + + g_return_if_fail (download_info != NULL); + + if (g_cancellable_is_cancelled (download_info->cancellable)) { + /* finish the operation and close both streams */ + g_input_stream_read_finish (G_INPUT_STREAM (source_object), res, NULL); + + g_output_stream_close (download_info->ostream, NULL, NULL); + g_input_stream_close (download_info->istream, NULL, NULL); + + /* The only way how to get this canceled is in EAttachment's finalize method, + and because the download_info_free free's the attachment on error, + then do not consider cancellation as an error. */ + download_info_free (download_info); + return; + } + + read = g_input_stream_read_finish (G_INPUT_STREAM (source_object), res, &error); + + if (!error) + g_output_stream_write_all (download_info->ostream, download_info->buffer, read, NULL, download_info->cancellable, &error); + + if (error) { + download_info->was_error = error->domain != G_IO_ERROR || error->code != G_IO_ERROR_CANCELLED; + if (download_info->was_error) + e_error_run (download_info->parent, "mail-composer:no-attach", download_info->uri, error->message, NULL); + + g_error_free (error); + + download_info->attachment->cancellable = NULL; + download_info_free (download_info); + return; + } + + if (read == 0) { + CamelException ex; + + /* done with reading */ + g_output_stream_close (download_info->ostream, NULL, NULL); + g_input_stream_close (download_info->istream, NULL, NULL); + + download_info->attachment->cancellable = NULL; + + camel_exception_init (&ex); + e_attachment_build_remote_file (download_info->file_name, download_info->attachment, "attachment", &ex); + + if (camel_exception_is_set (&ex)) { + download_info->was_error = TRUE; + e_error_run (download_info->parent, "mail-composer:no-attach", download_info->uri, camel_exception_get_description (&ex), NULL); + camel_exception_clear (&ex); + } + + download_info->attachment->percentage = -1; + download_info->attachment->is_available_local = TRUE; + g_signal_emit (download_info->attachment, signals[UPDATE], 0); + + download_info_free (download_info); + return; + } else if (download_info->file_size) { + download_info->attachment->percentage = read * 100 / download_info->file_size; + download_info->file_size -= MIN (download_info->file_size, read); + g_signal_emit (download_info->attachment, signals[UPDATE], 0); + } else { + download_info->attachment->percentage = 0; + g_signal_emit (download_info->attachment, signals[UPDATE], 0); + } + + /* read next chunk */ + g_input_stream_read_async (download_info->istream, download_info->buffer, download_info->buffer_size, G_PRIORITY_DEFAULT, download_info->cancellable, data_ready_cb, download_info); +} + +static gboolean +download_to_local_path (DownloadInfo *download_info, CamelException *ex) +{ + GError *error = NULL; + GFile *src = g_file_new_for_uri (download_info->uri); + GFile *des = g_file_new_for_path (download_info->file_name); + gboolean res = FALSE; + + g_return_val_if_fail (src != NULL && des != NULL, FALSE); + + download_info->ostream = G_OUTPUT_STREAM (g_file_replace (des, NULL, FALSE, G_FILE_CREATE_NONE, NULL, &error)); + + if (download_info->ostream && !error) { + GFileInfo *fi; + + fi = g_file_query_info (src, G_FILE_ATTRIBUTE_STANDARD_SIZE, G_FILE_QUERY_INFO_NONE, NULL, NULL); + + if (fi) { + download_info->file_size = g_file_info_get_attribute_uint64 (fi, G_FILE_ATTRIBUTE_STANDARD_SIZE); + g_object_unref (fi); } else { - download_info->attachment->percentage = 0; - g_signal_emit (download_info->attachment, signals[UPDATE], 0); + download_info->file_size = 0; } - if (info->phase == GNOME_VFS_XFER_PHASE_COMPLETED) { - CamelException ex; - - if (!info->file_size) { - if (info->vfs_status == GNOME_VFS_OK) - info->vfs_status = GNOME_VFS_ERROR_EOF; - goto error_msg; - } - - download_info->attachment->handle = NULL; - camel_exception_init (&ex); - e_attachment_build_remote_file (download_info->file_name, download_info->attachment, "attachment", &ex); - if (camel_exception_is_set (&ex)) { - e_error_run (download_info->parent, "mail-composer:no-attach", - download_info->uri, camel_exception_get_description (&ex), NULL); - camel_exception_clear (&ex); - goto error; - } - download_info->attachment->percentage = -1; - download_info->attachment->is_available_local = TRUE; - g_signal_emit (download_info->attachment, signals[UPDATE], 0); - g_free (download_info->file_name); - g_free (download_info->uri); - g_free (download_info); + download_info->istream = G_INPUT_STREAM (g_file_read (src, NULL, &error)); + + if (download_info->istream && !error) { + download_info->cancellable = g_cancellable_new (); + download_info->attachment->cancellable = download_info->cancellable; + download_info->buffer_size = 10240; /* max 10KB chunk */ + download_info->buffer = g_malloc (sizeof (char) * download_info->buffer_size); + + g_input_stream_read_async (download_info->istream, download_info->buffer, download_info->buffer_size, G_PRIORITY_DEFAULT, download_info->cancellable, data_ready_cb, download_info); + + res = TRUE; } - return TRUE; - case GNOME_VFS_XFER_PROGRESS_STATUS_VFSERROR: - error_msg: - e_error_run (download_info->parent, "mail-composer:no-attach", - download_info->uri, gnome_vfs_result_to_string (info->vfs_status), NULL); - error: - g_object_unref (download_info->attachment); - g_free (download_info->file_name); - g_free (download_info->uri); - g_free (download_info); - return FALSE; - default: - break; } - return TRUE; -} + if (error) { + /* propagate error */ + if (ex) + camel_exception_set (ex, CAMEL_EXCEPTION_SYSTEM, error->message); -static void -download_to_local_path (GnomeVFSURI *source_uri, GnomeVFSURI *target_uri, DownloadInfo *download_info) + g_error_free (error); + download_info->was_error = TRUE; + download_info_free (download_info); + } -{ - GList *source_uri_list; - GList *target_uri_list; - - source_uri_list = g_list_append (NULL, source_uri); - target_uri_list = g_list_append (NULL, target_uri); - - /* Callback info */ - gnome_vfs_async_xfer (&download_info->attachment->handle, /* handle_return */ - source_uri_list, /* source_uri_list */ - target_uri_list, /* target_uri_list */ - GNOME_VFS_XFER_DEFAULT, /* xfer_options */ - GNOME_VFS_XFER_ERROR_MODE_ABORT, /* error_mode */ - GNOME_VFS_XFER_OVERWRITE_MODE_REPLACE, /* overwrite_mode */ - GNOME_VFS_PRIORITY_DEFAULT, /* priority */ - (GnomeVFSAsyncXferProgressCallback) async_progress_update_cb, - download_info, /* update_callback_data */ - NULL, /* progress_sync_callback */ - NULL); /* sync_callback_data */ + g_object_unref (src); + g_object_unref (des); + + return res; } EAttachment * @@ -497,19 +556,23 @@ e_attachment_new_remote_file (GtkWindow *error_dlg_parent, const char *uri, cons new->body = NULL; new->size = 0; new->guessed_type = FALSE; - new->handle = NULL; + new->cancellable = NULL; new->is_available_local = FALSE; new->percentage = 0; new->file_name = g_build_filename (path, base, NULL); g_free (base); - download_info = g_new (DownloadInfo, 1); + download_info = g_new0 (DownloadInfo, 1); download_info->attachment = new; download_info->file_name = g_strdup (new->file_name); download_info->uri = g_strdup (uri); download_info->parent = error_dlg_parent; - download_to_local_path (gnome_vfs_uri_new (uri), gnome_vfs_uri_new (new->file_name), download_info); + download_info->was_error = FALSE; + + /* it frees all on the error, so do not free it twice */ + if (!download_to_local_path (download_info, ex)) + return NULL; return new; } diff --git a/widgets/misc/e-attachment.h b/widgets/misc/e-attachment.h index 3b03a0aa72..d2cf892c11 100644 --- a/widgets/misc/e-attachment.h +++ b/widgets/misc/e-attachment.h @@ -31,7 +31,7 @@ #include #include #include -#include +#include #ifdef __cplusplus extern "C" { @@ -59,7 +59,8 @@ struct _EAttachment { GdkPixbuf *pixbuf_cache; - GnomeVFSAsyncHandle *handle; + GCancellable *cancellable; + gboolean is_available_local; int percentage; char *file_name; diff --git a/widgets/misc/e-image-chooser.c b/widgets/misc/e-image-chooser.c index 5dae27527f..f3fb4070ba 100644 --- a/widgets/misc/e-image-chooser.c +++ b/widgets/misc/e-image-chooser.c @@ -29,12 +29,12 @@ #include #include -#include #include #include "e-image-chooser.h" #include "e-util/e-util-marshal.h" #include "e-util/e-icon-factory.h" +#include "e-util/e-util.h" struct _EImageChooserPrivate { @@ -409,46 +409,30 @@ image_drag_data_received_cb (GtkWidget *widget, target_type = gdk_atom_name (selection_data->target); if (!strcmp (target_type, URI_LIST_TYPE)) { - GnomeVFSResult result; - GnomeVFSHandle *handle; + GError *error = NULL; char *uri; char *nl = strstr ((char *)selection_data->data, "\r\n"); char *buf = NULL; - /* Why can't we change the info parameter to a GnomeVFSFileInfo and use that? */ - GnomeVFSFileInfo file_info; + gsize read = 0; if (nl) uri = g_strndup ((char *)selection_data->data, nl - (char*)selection_data->data); else uri = g_strdup ((char *)selection_data->data); - result = gnome_vfs_open (&handle, uri, GNOME_VFS_OPEN_READ); - if (result == GNOME_VFS_OK) { - result = gnome_vfs_get_file_info_from_handle (handle, &file_info, GNOME_VFS_FILE_INFO_DEFAULT); - if (result == GNOME_VFS_OK) { - GnomeVFSFileSize num_read; - - buf = g_malloc (file_info.size); - - if ((result = gnome_vfs_read (handle, buf, file_info.size, &num_read)) == GNOME_VFS_OK) { - if (set_image_from_data (chooser, buf, num_read)) { - handled = TRUE; - } else { - /* XXX we should pop up a warning dialog here */ - g_free (buf); - } - } else { - g_free (buf); - } + if (e_util_read_file (uri, TRUE, &buf, &read, &error) && read > 0 && buf) { + if (set_image_from_data (chooser, buf, read)) { + handled = TRUE; } - - gnome_vfs_close (handle); - } - else { - printf ("gnome_vfs_open failed (%s)\n", gnome_vfs_result_to_string (result)); } + g_free (buf); g_free (uri); + + if (error) { + g_warning ("%s", error->message); + g_error_free (error); + } } gtk_drag_finish (context, handled, FALSE, time); -- cgit