/*
* e-mime-part-utils.c
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) version 3.
*
* 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with the program; if not, see
*
*
* Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
*
*/
#include "e-mime-part-utils.h"
#include
#include
#include
#include
#include "e-util/e-util.h"
static void
mime_part_utils_open_in_cb (GtkAction *action,
CamelMimePart *mime_part)
{
GtkWindow *parent;
GFile *file;
gchar *path;
gchar *uri;
gint fd;
GError *error = NULL;
parent = g_object_get_data (G_OBJECT (action), "parent-window");
fd = e_file_open_tmp (&path, &error);
if (error != NULL)
goto fail;
close (fd);
file = g_file_new_for_path (path);
e_mime_part_utils_save_to_file (mime_part, file, &error);
g_free (path);
if (error != NULL) {
g_object_unref (file);
goto fail;
}
uri = g_file_get_uri (file);
e_show_uri (parent, uri);
g_free (uri);
g_object_unref (file);
return;
fail:
g_warning ("%s", error->message);
g_error_free (error);
}
GList *
e_mime_part_utils_get_apps (CamelMimePart *mime_part)
{
GList *app_info_list;
const gchar *filename;
gchar *content_type;
gchar *mime_type;
gchar *cp;
g_return_val_if_fail (CAMEL_IS_MIME_PART (mime_part), NULL);
filename = camel_mime_part_get_filename (mime_part);
mime_type = camel_content_type_simple (
camel_mime_part_get_content_type (mime_part));
g_return_val_if_fail (mime_type != NULL, NULL);
/* GIO expects lowercase MIME types. */
for (cp = mime_type; *cp != '\0'; cp++)
*cp = g_ascii_tolower (*cp);
content_type = g_content_type_from_mime_type (mime_type);
if (content_type != NULL)
app_info_list = g_app_info_get_all_for_type (content_type);
else
app_info_list = g_app_info_get_all_for_type (mime_type);
g_free (content_type);
if (app_info_list != NULL || filename == NULL)
goto exit;
if (strcmp (mime_type, "application/octet-stream") != 0)
goto exit;
content_type = g_content_type_guess (filename, NULL, 0, NULL);
app_info_list = g_app_info_get_all_for_type (content_type);
g_free (content_type);
exit:
g_free (mime_type);
return app_info_list;
}
gboolean
e_mime_part_utils_save_to_file (CamelMimePart *mime_part,
GFile *file,
GError **error)
{
GFileOutputStream *output_stream;
CamelDataWrapper *content;
CamelStream *stream;
g_return_val_if_fail (CAMEL_IS_MIME_PART (mime_part), FALSE);
g_return_val_if_fail (G_IS_FILE (file), FALSE);
output_stream = g_file_replace (
file, NULL, FALSE, G_FILE_CREATE_NONE, NULL, error);
if (output_stream == NULL)
return FALSE;
/* The CamelStream takes ownership of the GFileOutputStream. */
content = camel_medium_get_content_object (CAMEL_MEDIUM (mime_part));
stream = camel_stream_vfs_new_with_stream (G_OBJECT (output_stream));
/* XXX Camel's streams are synchronous only, so we have to write
* the whole thing in one shot and hope it doesn't block the
* main loop for too long. */
if (camel_data_wrapper_decode_to_stream (content, stream) < 0)
goto file_error;
if (camel_stream_flush (stream) < 0)
goto file_error;
camel_object_unref (stream);
return TRUE;
file_error:
g_set_error (
error, G_FILE_ERROR,
g_file_error_from_errno (errno),
"%s", g_strerror (errno));
camel_object_unref (stream);
return FALSE;
}
void
e_mime_part_utils_add_open_actions (CamelMimePart *mime_part,
GtkUIManager *ui_manager,
GtkActionGroup *action_group,
const gchar *widget_path,
GtkWindow *parent,
guint merge_id)
{
GList *app_info_list;
GList *iter;
g_return_if_fail (CAMEL_IS_MIME_PART (mime_part));
g_return_if_fail (GTK_IS_UI_MANAGER (ui_manager));
g_return_if_fail (GTK_IS_ACTION_GROUP (action_group));
g_return_if_fail (parent == NULL || GTK_IS_WINDOW (parent));
g_return_if_fail (widget_path != NULL);
app_info_list = e_mime_part_utils_get_apps (mime_part);
for (iter = app_info_list; iter != NULL; iter = iter->next) {
GAppInfo *app_info = iter->data;
GtkAction *action;
const gchar *app_executable;
const gchar *app_name;
gchar *action_tooltip;
gchar *action_label;
gchar *action_name;
if (!g_app_info_should_show (app_info))
continue;
app_executable = g_app_info_get_executable (app_info);
app_name = g_app_info_get_name (app_info);
action_name = g_strdup_printf ("open-in-%s", app_executable);
action_label = g_strdup_printf (_("Open in %s..."), app_name);
action_tooltip = g_strdup_printf (
_("Open this attachment in %s"), app_name);
action = gtk_action_new (
action_name, action_label, action_tooltip, NULL);
g_object_set_data (
G_OBJECT (action), "parent-window", parent);
g_signal_connect (
action, "activate",
G_CALLBACK (mime_part_utils_open_in_cb), mime_part);
gtk_action_group_add_action (action_group, action);
gtk_ui_manager_add_ui (
ui_manager, merge_id, widget_path, action_name,
action_name, GTK_UI_MANAGER_AUTO, FALSE);
g_free (action_name);
g_free (action_label);
g_free (action_tooltip);
}
g_list_foreach (app_info_list, (GFunc) g_object_unref, NULL);
g_list_free (app_info_list);
}