aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--composer/e-msg-composer.c73
-rw-r--r--configure.in4
-rw-r--r--e-util/e-util.c27
-rw-r--r--e-util/e-util.h2
-rw-r--r--mail/e-attachment-handler-mail.c160
-rw-r--r--mail/em-popup.c568
-rw-r--r--plugins/save-attachments/ChangeLog102
-rw-r--r--plugins/save-attachments/Makefile.am31
-rw-r--r--plugins/save-attachments/org-gnome-save-attachments.eplug.xml26
-rw-r--r--plugins/save-attachments/org-gnome-save-attachments.xml20
-rw-r--r--plugins/save-attachments/save-attachments.c392
-rw-r--r--widgets/misc/Makefile.am2
-rw-r--r--widgets/misc/e-attachment-handler.c34
-rw-r--r--widgets/misc/e-attachment-handler.h11
-rw-r--r--widgets/misc/e-attachment-paned.c17
-rw-r--r--widgets/misc/e-attachment-paned.h8
-rw-r--r--widgets/misc/e-attachment-store.c338
-rw-r--r--widgets/misc/e-attachment-store.h5
-rw-r--r--widgets/misc/e-attachment-view.c614
-rw-r--r--widgets/misc/e-attachment-view.h18
-rw-r--r--widgets/misc/e-attachment.c25
-rw-r--r--widgets/misc/e-mime-part-utils.c223
-rw-r--r--widgets/misc/e-mime-part-utils.h46
23 files changed, 693 insertions, 2053 deletions
diff --git a/composer/e-msg-composer.c b/composer/e-msg-composer.c
index f6e85b78c8..ad61b1b461 100644
--- a/composer/e-msg-composer.c
+++ b/composer/e-msg-composer.c
@@ -133,39 +133,6 @@ enum {
LAST_SIGNAL
};
-enum {
- DND_TYPE_MESSAGE_RFC822,
- DND_TYPE_X_UID_LIST,
- DND_TYPE_TEXT_URI_LIST,
- DND_TYPE_NETSCAPE_URL,
- DND_TYPE_TEXT_VCARD,
- DND_TYPE_TEXT_CALENDAR
-};
-
-static GtkTargetEntry drop_types[] = {
- { "message/rfc822", 0, DND_TYPE_MESSAGE_RFC822 },
- { "x-uid-list", 0, DND_TYPE_X_UID_LIST },
- { "text/uri-list", 0, DND_TYPE_TEXT_URI_LIST },
- { "_NETSCAPE_URL", 0, DND_TYPE_NETSCAPE_URL },
- { "text/x-vcard", 0, DND_TYPE_TEXT_VCARD },
- { "text/calendar", 0, DND_TYPE_TEXT_CALENDAR }
-};
-
-static struct {
- gchar *target;
- GdkAtom atom;
- guint32 actions;
-} drag_info[] = {
- { "message/rfc822", NULL, GDK_ACTION_COPY },
- { "x-uid-list", NULL, GDK_ACTION_ASK |
- GDK_ACTION_MOVE |
- GDK_ACTION_COPY },
- { "text/uri-list", NULL, GDK_ACTION_COPY },
- { "_NETSCAPE_URL", NULL, GDK_ACTION_COPY },
- { "text/x-vcard", NULL, GDK_ACTION_COPY },
- { "text/calendar", NULL, GDK_ACTION_COPY }
-};
-
static gpointer parent_class;
static guint signals[LAST_SIGNAL];
@@ -1844,8 +1811,13 @@ msg_composer_drag_data_received (GtkWidget *widget,
composer = E_MSG_COMPOSER (gtk_widget_get_toplevel (widget));
view = e_msg_composer_get_attachment_view (composer);
- e_attachment_view_drag_data_received (
- view, context, x, y, selection, info, time);
+ /* Forward the data to the attachment view. Note that calling
+ * e_attachment_view_drag_data_received() will not work because
+ * that function only handles the case where all the other drag
+ * handlers have failed. */
+ e_attachment_paned_drag_data_received (
+ E_ATTACHMENT_PANED (view),
+ context, x, y, selection, info, time);
}
static void
@@ -1900,7 +1872,6 @@ msg_composer_paste_clipboard (GtkhtmlEditor *editor)
GtkWidget *widget;
gchar *filename;
gchar *uri;
- gint fd;
GError *error = NULL;
composer = E_MSG_COMPOSER (editor);
@@ -1924,14 +1895,13 @@ msg_composer_paste_clipboard (GtkhtmlEditor *editor)
goto chainup;
/* Reserve a temporary file. */
- fd = e_file_open_tmp (&filename, &error);
- if (error != NULL) {
- g_warning ("%s", error->message);
+ filename = e_mktemp (NULL);
+ if (filename == NULL) {
+ g_warning ("%s", g_strerror (errno));
g_object_unref (pixbuf);
g_error_free (error);
return;
}
- close (fd);
/* Save the pixbuf as a temporary file in image/png format. */
if (!gdk_pixbuf_save (pixbuf, filename, "png", &error, NULL)) {
@@ -2197,11 +2167,6 @@ msg_composer_class_init (EMsgComposerClass *class)
GtkObjectClass *gtk_object_class;
GtkWidgetClass *widget_class;
GtkhtmlEditorClass *editor_class;
- gint ii;
-
- for (ii = 0; ii < G_N_ELEMENTS (drag_info); ii++)
- drag_info[ii].atom =
- gdk_atom_intern (drag_info[ii].target, FALSE);
parent_class = g_type_class_peek_parent (class);
g_type_class_add_private (class, sizeof (EMsgComposerPrivate));
@@ -2265,10 +2230,14 @@ msg_composer_init (EMsgComposer *composer)
EAttachmentView *view;
EAttachmentStore *store;
EComposerHeaderTable *table;
+ GdkDragAction drag_actions;
+ GtkTargetList *target_list;
+ GtkTargetEntry *targets;
GtkUIManager *manager;
GtkhtmlEditor *editor;
GtkHTML *html;
const gchar *id;
+ gint n_targets;
composer->priv = E_MSG_COMPOSER_GET_PRIVATE (composer);
@@ -2277,6 +2246,7 @@ msg_composer_init (EMsgComposer *composer)
editor = GTKHTML_EDITOR (composer);
html = gtkhtml_editor_get_html (editor);
manager = gtkhtml_editor_get_ui_manager (editor);
+ view = e_msg_composer_get_attachment_view (composer);
all_composers = g_slist_prepend (all_composers, composer);
table = E_COMPOSER_HEADER_TABLE (composer->priv->header_table);
@@ -2285,16 +2255,20 @@ msg_composer_init (EMsgComposer *composer)
/* Drag-and-Drop Support */
-#if 0 /* KILL-BONOBO */
+ target_list = e_attachment_view_get_target_list (view);
+ drag_actions = e_attachment_view_get_drag_actions (view);
+
+ targets = gtk_target_table_new_from_list (target_list, &n_targets);
+
gtk_drag_dest_set (
GTK_WIDGET (composer), GTK_DEST_DEFAULT_ALL,
- drop_types, G_N_ELEMENTS (drop_types),
- GDK_ACTION_COPY | GDK_ACTION_ASK | GDK_ACTION_MOVE);
+ targets, n_targets, drag_actions);
g_signal_connect (
html, "drag-data-received",
G_CALLBACK (msg_composer_drag_data_received), NULL);
-#endif
+
+ gtk_target_table_free (targets, n_targets);
/* Configure Headers */
@@ -2336,7 +2310,6 @@ msg_composer_init (EMsgComposer *composer)
/* Attachments */
- view = e_msg_composer_get_attachment_view (composer);
store = e_attachment_view_get_store (view);
g_signal_connect_swapped (
diff --git a/configure.in b/configure.in
index 05024a1422..0b0c11b50f 100644
--- a/configure.in
+++ b/configure.in
@@ -1785,12 +1785,12 @@ plugins_standard_always="bbdb subject-thread save-calendar copy-tool mail-to-tas
plugins_standard="$plugins_standard_always"
all_plugins_standard="$plugins_standard"
-plugins_experimental_always="folder-unsubscribe mail-to-meeting save-attachments external-editor hula-account-setup"
+plugins_experimental_always="folder-unsubscribe mail-to-meeting external-editor hula-account-setup"
plugins_experimental="$plugins_experimental_always $IPOD_SYNC $TNEF_ATTACHMENTS $PYTHON_PLUGIN"
all_plugins_experimental="$plugins_experimental_always ipod-sync tnef-attachments"
dnl Temporary KILL-BONOBO hack
-enable_plugins="attachment-reminder addressbook-file audio-inline bbdb bogo-junk-plugin caldav calendar-file calendar-http copy-tool default-source external-editor google-account-setup hula-account-setup imap-features mail-notification mail-to-meeting mark-all-read plugin-manager profiler sa-junk-plugin save-attachments save-calendar subject-thread tnef-attachments vcard-inline webdav-account-setup"
+enable_plugins="attachment-reminder addressbook-file audio-inline bbdb bogo-junk-plugin caldav calendar-file calendar-http copy-tool default-source external-editor google-account-setup hula-account-setup imap-features mail-notification mail-to-meeting mark-all-read plugin-manager profiler sa-junk-plugin save-calendar subject-thread tnef-attachments vcard-inline webdav-account-setup"
dnl PLUGINS NOT BUILDING YET
dnl ------------------------
diff --git a/e-util/e-util.c b/e-util/e-util.c
index 02c76c3d32..071f5e58b8 100644
--- a/e-util/e-util.c
+++ b/e-util/e-util.c
@@ -186,33 +186,6 @@ exit:
}
/**
- * e_file_open_tmp:
- * @name_used: location to store the actual named used, or %NULL
- * @error: return location for a #GError, or %NULL
- *
- * Convenience function wraps g_file_open_tmp() but chooses a suitable
- * filename template using both the package name and the user name.
- *
- * Returns: A file handle (as from open()) to the file opened for reading
- * and writing. The file is opened in binary mode on platforms
- * where there is a difference. The file handle should be closed
- * with close(). In case of errors, -1 is returned and @error
- * will be set.
- **/
-gint
-e_file_open_tmp (gchar **name_used,
- GError **error)
-{
- static gchar *template = NULL;
-
- if (G_UNLIKELY (template == NULL))
- template = g_strdup_printf (
- PACKAGE "-%s-XXXXXX", g_get_user_name ());
-
- return g_file_open_tmp (template, name_used, error);
-}
-
-/**
* e_lookup_action:
* @ui_manager: a #GtkUIManager
* @action_name: the name of an action
diff --git a/e-util/e-util.h b/e-util/e-util.h
index 168b497da7..84ec411516 100644
--- a/e-util/e-util.h
+++ b/e-util/e-util.h
@@ -47,8 +47,6 @@ void e_show_uri (GtkWindow *parent,
const gchar *uri);
void e_display_help (GtkWindow *parent,
const gchar *link_id);
-gint e_file_open_tmp (gchar **name_used,
- GError **error);
GtkAction * e_lookup_action (GtkUIManager *ui_manager,
const gchar *action_name);
GtkActionGroup *e_lookup_action_group (GtkUIManager *ui_manager,
diff --git a/mail/e-attachment-handler-mail.c b/mail/e-attachment-handler-mail.c
index 32cd884fe2..b7be3b6b38 100644
--- a/mail/e-attachment-handler-mail.c
+++ b/mail/e-attachment-handler-mail.c
@@ -23,6 +23,7 @@
#include <config.h>
#include <glib/gi18n.h>
+#include <camel/camel-stream-mem.h>
#include "mail/em-composer-utils.h"
@@ -47,17 +48,21 @@ static const gchar *ui =
" </popup>"
"</ui>";
+/* Note: Do not use the info field. */
+static GtkTargetEntry target_table[] = {
+ { "message/rfc822", 0, 0 },
+ { "x-uid-list", 0, 0 }
+};
+
static void
-action_mail_forward_cb (GtkAction *action,
- EAttachmentHandler *handler)
+attachment_handler_mail_forward (GtkAction *action,
+ EAttachmentView *view)
{
- EAttachmentView *view;
EAttachment *attachment;
CamelMimePart *mime_part;
CamelDataWrapper *wrapper;
GList *selected;
- view = e_attachment_handler_get_view (handler);
selected = e_attachment_view_get_selected_attachments (view);
g_return_if_fail (g_list_length (selected) == 1);
@@ -72,16 +77,14 @@ action_mail_forward_cb (GtkAction *action,
}
static void
-action_mail_reply_all_cb (GtkAction *action,
- EAttachmentHandler *handler)
+attachment_handler_mail_reply_all (GtkAction *action,
+ EAttachmentView *view)
{
- EAttachmentView *view;
EAttachment *attachment;
CamelMimePart *mime_part;
CamelDataWrapper *wrapper;
GList *selected;
- view = e_attachment_handler_get_view (handler);
selected = e_attachment_view_get_selected_attachments (view);
g_return_if_fail (g_list_length (selected) == 1);
@@ -98,16 +101,14 @@ action_mail_reply_all_cb (GtkAction *action,
}
static void
-action_mail_reply_sender_cb (GtkAction *action,
- EAttachmentHandler *handler)
+attachment_handler_mail_reply_sender (GtkAction *action,
+ EAttachmentView *view)
{
- EAttachmentView *view;
EAttachment *attachment;
CamelMimePart *mime_part;
CamelDataWrapper *wrapper;
GList *selected;
- view = e_attachment_handler_get_view (handler);
selected = e_attachment_view_get_selected_attachments (view);
g_return_if_fail (g_list_length (selected) == 1);
@@ -130,26 +131,109 @@ static GtkActionEntry standard_entries[] = {
N_("_Forward"),
NULL,
NULL, /* XXX Add a tooltip! */
- G_CALLBACK (action_mail_forward_cb) },
+ G_CALLBACK (attachment_handler_mail_forward) },
{ "mail-reply-all",
"mail-reply-all",
N_("Reply to _All"),
NULL,
NULL, /* XXX Add a tooltip! */
- G_CALLBACK (action_mail_reply_all_cb) },
+ G_CALLBACK (attachment_handler_mail_reply_all) },
{ "mail-reply-sender",
"mail-reply-sender",
N_("_Reply to Sender"),
NULL,
NULL, /* XXX Add a tooltip! */
- G_CALLBACK (action_mail_reply_sender_cb) }
+ G_CALLBACK (attachment_handler_mail_reply_sender) }
};
static void
-attachment_handler_mail_update_actions_cb (EAttachmentView *view,
- EAttachmentHandler *handler)
+attachment_handler_mail_message_rfc822 (EAttachmentView *view,
+ GdkDragContext *drag_context,
+ gint x,
+ gint y,
+ GtkSelectionData *selection_data,
+ guint info,
+ guint time)
+{
+ static GdkAtom atom = GDK_NONE;
+ EAttachmentStore *store;
+ EAttachment *attachment;
+ CamelMimeMessage *message;
+ CamelDataWrapper *wrapper;
+ CamelStream *stream;
+ const gchar *data;
+ gboolean success = FALSE;
+ gpointer parent;
+ gint length;
+
+ if (G_UNLIKELY (atom == GDK_NONE))
+ atom = gdk_atom_intern_static_string ("message/rfc822");
+
+ if (gtk_selection_data_get_target (selection_data) != atom)
+ return;
+
+ g_signal_stop_emission_by_name (view, "drag-data-received");
+
+ data = (const gchar *) gtk_selection_data_get_data (selection_data);
+ length = gtk_selection_data_get_length (selection_data);
+
+ stream = camel_stream_mem_new ();
+ camel_stream_write (stream, data, length);
+ camel_stream_reset (stream);
+
+ message = camel_mime_message_new ();
+ wrapper = CAMEL_DATA_WRAPPER (message);
+
+ if (camel_data_wrapper_construct_from_stream (wrapper, stream) == -1)
+ goto exit;
+
+ store = e_attachment_view_get_store (view);
+
+ parent = gtk_widget_get_toplevel (GTK_WIDGET (view));
+ parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL;
+
+ attachment = e_attachment_new_for_message (message);
+ e_attachment_store_add_attachment (store, attachment);
+ e_attachment_load_async (
+ attachment, (GAsyncReadyCallback)
+ e_attachment_load_handle_error, parent);
+ g_object_unref (attachment);
+
+ success = TRUE;
+
+exit:
+ camel_object_unref (message);
+ camel_object_unref (stream);
+
+ gtk_drag_finish (drag_context, success, FALSE, time);
+}
+
+static void
+attachment_handler_mail_x_uid_list (EAttachmentView *view,
+ GdkDragContext *drag_context,
+ gint x,
+ gint y,
+ GtkSelectionData *selection_data,
+ guint info,
+ guint time)
+{
+ static GdkAtom atom = GDK_NONE;
+
+ if (G_UNLIKELY (atom == GDK_NONE))
+ atom = gdk_atom_intern_static_string ("x-uid-list");
+
+ if (gtk_selection_data_get_target (selection_data) != atom)
+ return;
+
+ return; /* REMOVE ME */
+
+ g_signal_stop_emission_by_name (view, "drag-data-received");
+}
+
+static void
+attachment_handler_mail_update_actions (EAttachmentView *view)
{
EAttachment *attachment;
CamelMimePart *mime_part;
@@ -184,7 +268,6 @@ exit:
static void
attachment_handler_mail_constructed (GObject *object)
{
- EAttachmentHandlerMailPrivate *priv;
EAttachmentHandler *handler;
EAttachmentView *view;
GtkActionGroup *action_group;
@@ -193,7 +276,6 @@ attachment_handler_mail_constructed (GObject *object)
GError *error = NULL;
handler = E_ATTACHMENT_HANDLER (object);
- priv = E_ATTACHMENT_HANDLER_MAIL_GET_PRIVATE (object);
/* Chain up to parent's constructed() method. */
G_OBJECT_CLASS (parent_class)->constructed (object);
@@ -205,7 +287,7 @@ attachment_handler_mail_constructed (GObject *object)
gtk_action_group_set_translation_domain (action_group, domain);
gtk_action_group_add_actions (
action_group, standard_entries,
- G_N_ELEMENTS (standard_entries), object);
+ G_N_ELEMENTS (standard_entries), view);
gtk_ui_manager_insert_action_group (ui_manager, action_group, 0);
g_object_unref (action_group);
@@ -218,20 +300,51 @@ attachment_handler_mail_constructed (GObject *object)
g_signal_connect (
view, "update-actions",
- G_CALLBACK (attachment_handler_mail_update_actions_cb),
- object);
+ G_CALLBACK (attachment_handler_mail_update_actions),
+ NULL);
+
+ g_signal_connect (
+ view, "drag-data-received",
+ G_CALLBACK (attachment_handler_mail_message_rfc822),
+ NULL);
+
+ g_signal_connect (
+ view, "drag-data-received",
+ G_CALLBACK (attachment_handler_mail_x_uid_list),
+ NULL);
+}
+
+static GdkDragAction
+attachment_handler_mail_get_drag_actions (EAttachmentHandler *handler)
+{
+ return GDK_ACTION_COPY;
+}
+
+static const GtkTargetEntry *
+attachment_handler_mail_get_target_table (EAttachmentHandler *handler,
+ guint *n_targets)
+{
+ if (n_targets != NULL)
+ *n_targets = G_N_ELEMENTS (target_table);
+
+ return target_table;
}
static void
attachment_handler_mail_class_init (EAttachmentHandlerMailClass *class)
{
GObjectClass *object_class;
+ EAttachmentHandlerClass *handler_class;
parent_class = g_type_class_peek_parent (class);
g_type_class_add_private (class, sizeof (EAttachmentHandlerMailPrivate));
object_class = G_OBJECT_CLASS (class);
object_class->constructed = attachment_handler_mail_constructed;
+
+ handler_class = E_ATTACHMENT_HANDLER_CLASS (class);
+ handler_class->get_drag_actions = attachment_handler_mail_get_drag_actions;
+ handler_class->get_target_table = attachment_handler_mail_get_target_table;
}
static void
@@ -261,8 +374,7 @@ e_attachment_handler_mail_get_type (void)
type = g_type_register_static (
E_TYPE_ATTACHMENT_HANDLER,
- "EAttachmentHandlerMail",
- &type_info, 0);
+ "EAttachmentHandlerMail", &type_info, 0);
}
return type;
diff --git a/mail/em-popup.c b/mail/em-popup.c
index c9dde270a0..e57b1de7f8 100644
--- a/mail/em-popup.c
+++ b/mail/em-popup.c
@@ -55,8 +55,6 @@
#include <e-util/e-util.h>
#include "e-attachment.h"
-static void emp_standard_menu_factory(EPopup *emp, void *data);
-
static GObjectClass *emp_parent;
static void
@@ -116,10 +114,6 @@ emp_class_init(GObjectClass *klass)
{
klass->finalize = emp_finalise;
((EPopupClass *)klass)->target_free = emp_target_free;
-
-#if 0 /* KILL-BONOBO */
- e_popup_class_add_factory((EPopupClass *)klass, NULL, emp_standard_menu_factory, NULL);
-#endif
}
GType
@@ -363,568 +357,6 @@ done:
return t;
}
-#if 0 /* KILL-BONOBO */
-/**
- * em_popup_target_new_attachments:
- * @emp:
- * @attachments: A list of EMsgComposerAttachment objects, reffed for
- * the list. Will be unreff'd once finished with.
- *
- * Owns the list @attachments and their items after they're passed in.
- *
- * Return value:
- **/
-EMPopupTargetAttachments *
-em_popup_target_new_attachments(EMPopup *emp, GSList *attachments)
-{
- EMPopupTargetAttachments *t = e_popup_target_new(&emp->popup, EM_POPUP_TARGET_ATTACHMENTS, sizeof(*t));
- guint32 mask = ~0;
- int len = g_slist_length(attachments);
-
- t->attachments = attachments;
- if (len > 0)
- mask &= ~ EM_POPUP_ATTACHMENTS_MANY;
- if (len == 1 && ((EAttachment *)attachments->data)->is_available_local) {
- EAttachment *attachment;
- CamelMimePart *mime_part;
- CamelContentType *mime_type;
- CamelDataWrapper *data_wrapper;
-
- attachment = attachments->data;
- mime_part = e_attachment_get_mime_part (attachment);
- mime_type = CAMEL_DATA_WRAPPER (mime_part)->mime_type;
- data_wrapper = camel_medium_get_content_object (
- CAMEL_MEDIUM (mime_part));
-
- if (camel_content_type_is (mime_type, "image", "*"))
- mask &= ~ EM_POPUP_ATTACHMENTS_IMAGE;
- if (CAMEL_IS_MIME_MESSAGE (data_wrapper))
- mask &= ~EM_POPUP_ATTACHMENTS_MESSAGE;
-
- mask &= ~ EM_POPUP_ATTACHMENTS_ONE;
- }
- if (len > 1)
- mask &= ~ EM_POPUP_ATTACHMENTS_MULTIPLE;
- t->target.mask = mask;
-
- return t;
-}
-#endif
-
-/* ********************************************************************** */
-
-#if 0 /* KILL-BONOBO */
-static void
-emp_part_popup_saveas(EPopup *ep, EPopupItem *item, void *data)
-{
- EPopupTarget *t = ep->target;
- CamelMimePart *part = NULL;
- GtkWidget *widget;
- gpointer parent;
-
- /* If it is of type EM_POPUP_TARGET_ATTACHMENTS, we can assume the length is one. */
- if (t->type == EM_POPUP_TARGET_ATTACHMENTS) {
- EAttachment *attachment;
-
- attachment = E_ATTACHMENT (((EMPopupTargetAttachments *) t)->attachments->data);
- part = e_attachment_get_mime_part (attachment);
- } else
- part = ((EMPopupTargetPart *) t)->part;
-
- widget = ep->target->widget;
- parent = gtk_widget_get_toplevel (widget);
- parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL;
-
- em_utils_save_part (parent, _("Save As..."), part);
-}
-#endif
-
-#if 0 /* KILL-BONOBO */
-static void
-emp_part_popup_set_background(EPopup *ep, EPopupItem *item, void *data)
-{
- EPopupTarget *t = ep->target;
- GConfClient *gconf;
- char *str, *filename, *path, *extension;
- unsigned int i=1;
- CamelMimePart *part = NULL;
-
- if (t->type == EM_POPUP_TARGET_ATTACHMENTS) {
- EAttachment *attachment;
-
- attachment = E_ATTACHMENT (((EMPopupTargetAttachments *) t)->attachments->data);
- part = e_attachment_get_mime_part (attachment);
- } else
- part = ((EMPopupTargetPart *) t)->part;
-
- if (!part)
- return;
-
- filename = g_strdup(camel_mime_part_get_filename(part));
-
- /* if filename is blank, create a default filename based on MIME type */
- if (!filename || !filename[0]) {
- CamelContentType *ct;
-
- ct = camel_mime_part_get_content_type(part);
- g_free (filename);
- filename = g_strdup_printf (_("untitled_image.%s"), ct->subtype);
- }
-
- e_filename_make_safe(filename);
-
- path = g_build_filename(g_get_home_dir(), ".gnome2", "wallpapers", filename, NULL);
-
- extension = strrchr(filename, '.');
- if (extension)
- *extension++ = 0;
-
- /* if file exists, stick a (number) on the end */
- while (g_file_test(path, G_FILE_TEST_EXISTS)) {
- char *name;
- name = g_strdup_printf(extension?"%s (%d).%s":"%s (%d)", filename, i++, extension);
- g_free(path);
- path = g_build_filename(g_get_home_dir(), ".gnome2", "wallpapers", name, NULL);
- g_free(name);
- }
-
- g_free(filename);
-
- if (em_utils_save_part_to_file(ep->target->widget, path, part)) {
- gconf = gconf_client_get_default();
-
- /* if the filename hasn't changed, blank the filename before
- * setting it so that gconf detects a change and updates it */
- if ((str = gconf_client_get_string(gconf, "/desktop/gnome/background/picture_filename", NULL)) != NULL
- && strcmp (str, path) == 0) {
- gconf_client_set_string(gconf, "/desktop/gnome/background/picture_filename", "", NULL);
- }
-
- g_free (str);
- gconf_client_set_string(gconf, "/desktop/gnome/background/picture_filename", path, NULL);
-
- /* if GNOME currently doesn't display a picture, set to "wallpaper"
- * display mode, otherwise leave it alone */
- if ((str = gconf_client_get_string(gconf, "/desktop/gnome/background/picture_options", NULL)) == NULL
- || strcmp(str, "none") == 0) {
- gconf_client_set_string(gconf, "/desktop/gnome/background/picture_options", "wallpaper", NULL);
- }
-
- gconf_client_suggest_sync(gconf, NULL);
-
- g_free(str);
- g_object_unref(gconf);
- }
-
- g_free(path);
-}
-#endif
-
-static void
-emp_part_popup_reply_sender(EPopup *ep, EPopupItem *item, void *data)
-{
- EPopupTarget *t = ep->target;
- CamelMimeMessage *message;
- CamelMimePart *part;
-
- if (t->type == EM_POPUP_TARGET_ATTACHMENTS) {
- EAttachment *attachment;
-
- attachment = E_ATTACHMENT (((EMPopupTargetAttachments *) t)->attachments->data);
- part = e_attachment_get_mime_part (attachment);
- } else
- part = ((EMPopupTargetPart *) t)->part;
-
- message = (CamelMimeMessage *)camel_medium_get_content_object((CamelMedium *)part);
- em_utils_reply_to_message(NULL, NULL, message, REPLY_MODE_SENDER, NULL);
-}
-
-static void
-emp_part_popup_reply_list (EPopup *ep, EPopupItem *item, void *data)
-{
- EPopupTarget *t = ep->target;
- CamelMimeMessage *message;
- CamelMimePart *part;
-
- if (t->type == EM_POPUP_TARGET_ATTACHMENTS) {
- EAttachment *attachment;
-
- attachment = E_ATTACHMENT (((EMPopupTargetAttachments *) t)->attachments->data);
- part = e_attachment_get_mime_part (attachment);
- } else
- part = ((EMPopupTargetPart *) t)->part;
-
- message = (CamelMimeMessage *)camel_medium_get_content_object((CamelMedium *)part);
- em_utils_reply_to_message(NULL, NULL, message, REPLY_MODE_LIST, NULL);
-}
-
-static void
-emp_part_popup_reply_all (EPopup *ep, EPopupItem *item, void *data)
-{
- EPopupTarget *t = ep->target;
- CamelMimeMessage *message;
- CamelMimePart *part;
-
- if (t->type == EM_POPUP_TARGET_ATTACHMENTS) {
- EAttachment *attachment;
-
- attachment = E_ATTACHMENT (((EMPopupTargetAttachments *) t)->attachments->data);
- part = e_attachment_get_mime_part (attachment);
- } else
- part = ((EMPopupTargetPart *) t)->part;
-
- message = (CamelMimeMessage *)camel_medium_get_content_object((CamelMedium *)part);
- em_utils_reply_to_message(NULL, NULL, message, REPLY_MODE_ALL, NULL);
-}
-
-static void
-emp_part_popup_forward (EPopup *ep, EPopupItem *item, void *data)
-{
- EPopupTarget *t = ep->target;
- CamelMimeMessage *message;
- CamelMimePart *part;
-
- if (t->type == EM_POPUP_TARGET_ATTACHMENTS) {
- EAttachment *attachment;
-
- attachment = E_ATTACHMENT (((EMPopupTargetAttachments *) t)->attachments->data);
- part = e_attachment_get_mime_part (attachment);
- } else
- part = ((EMPopupTargetPart *) t)->part;
-
- /* TODO: have a emfv specific override so we can get the parent folder uri */
- message = (CamelMimeMessage *)camel_medium_get_content_object((CamelMedium *) part);
- em_utils_forward_message(message, NULL);
-}
-
-#if 0 /* KILL-BONOBO */
-static EMPopupItem emp_standard_object_popups[] = {
- { E_POPUP_ITEM, "00.part.00", N_("_Save As..."), emp_part_popup_saveas, NULL, "document-save-as", 0 },
- { E_POPUP_ITEM, "00.part.10", N_("Set as _Background"), emp_part_popup_set_background, NULL, NULL, EM_POPUP_PART_IMAGE },
- { E_POPUP_BAR, "10.part", NULL, NULL, NULL, NULL, EM_POPUP_PART_MESSAGE },
- { E_POPUP_ITEM, "10.part.00", N_("_Reply to sender"), emp_part_popup_reply_sender, NULL, "mail-reply-sender" , EM_POPUP_PART_MESSAGE },
- { E_POPUP_ITEM, "10.part.01", N_("Reply to _List"), emp_part_popup_reply_list, NULL, NULL, EM_POPUP_PART_MESSAGE},
- { E_POPUP_ITEM, "10.part.03", N_("Reply to _All"), emp_part_popup_reply_all, NULL, "mail-reply-all", EM_POPUP_PART_MESSAGE},
- { E_POPUP_BAR, "20.part", NULL, NULL, NULL, NULL, EM_POPUP_PART_MESSAGE },
- { E_POPUP_ITEM, "20.part.00", N_("_Forward"), emp_part_popup_forward, NULL, "mail-forward", EM_POPUP_PART_MESSAGE },
-};
-
-static EMPopupItem emp_attachment_object_popups[] = {
- { E_POPUP_ITEM, "00.attach.00", N_("_Save As..."), emp_part_popup_saveas, NULL, "document-save-as", 0 },
- { E_POPUP_ITEM, "00.attach.10", N_("Set as _Background"), emp_part_popup_set_background, NULL, NULL, EM_POPUP_ATTACHMENTS_IMAGE },
- { E_POPUP_BAR, "05.attach", NULL, NULL, NULL, NULL, EM_POPUP_ATTACHMENTS_MESSAGE },
- { E_POPUP_ITEM, "05.attach.00", N_("_Reply to sender"), emp_part_popup_reply_sender, NULL, "mail-reply-sender" , EM_POPUP_ATTACHMENTS_MESSAGE },
- { E_POPUP_ITEM, "05.attach.01", N_("Reply to _List"), emp_part_popup_reply_list, NULL, NULL, EM_POPUP_ATTACHMENTS_MESSAGE},
- { E_POPUP_ITEM, "05.attach.03", N_("Reply to _All"), emp_part_popup_reply_all, NULL, "mail-reply-all", EM_POPUP_ATTACHMENTS_MESSAGE},
- { E_POPUP_BAR, "05.attach.10", NULL, NULL, NULL, NULL, EM_POPUP_ATTACHMENTS_MESSAGE },
- { E_POPUP_ITEM, "05.attach.15", N_("_Forward"), emp_part_popup_forward, NULL, "mail-forward", EM_POPUP_ATTACHMENTS_MESSAGE },
-};
-
-static const EPopupItem emp_standard_part_apps_bar = { E_POPUP_BAR, "99.object" };
-#endif
-
-/* ********************************************************************** */
-
-static void
-emp_uri_popup_link_open(EPopup *ep, EPopupItem *item, void *data)
-{
- EMPopupTargetURI *t = (EMPopupTargetURI *)ep->target;
- gchar *unescaped_uri = em_utils_url_unescape_amp (t->uri);
-
- /* FIXME Pass a parent window. */
- e_show_uri (NULL, unescaped_uri);
- g_free (unescaped_uri);
-}
-
-static void
-emp_uri_popup_address_send(EPopup *ep, EPopupItem *item, void *data)
-{
- EMPopupTargetURI *t = (EMPopupTargetURI *)ep->target;
-
- /* TODO: have an emfv specific override to get the from uri */
- em_utils_compose_new_message_with_mailto(t->uri, NULL);
-}
-
-static void
-emp_uri_popup_address_add(EPopup *ep, EPopupItem *item, void *data)
-{
- EMPopupTargetURI *t = (EMPopupTargetURI *)ep->target;
- CamelURL *url;
-
- url = camel_url_new(t->uri, NULL);
- if (url == NULL) {
- g_warning("cannot parse url '%s'", t->uri);
- return;
- }
-
- if (url->path && url->path[0])
- em_utils_add_address(ep->target->widget, url->path);
-
- camel_url_free(url);
-}
-
-static EPopupItem emp_standard_uri_popups[] = {
- { E_POPUP_ITEM, "00.uri.00", N_("_Open Link in Browser"), emp_uri_popup_link_open, NULL, NULL, EM_POPUP_URI_HTTP },
- { E_POPUP_ITEM, "00.uri.10", N_("_Send New Message To..."), emp_uri_popup_address_send, NULL, "mail-message-new", EM_POPUP_URI_MAILTO },
- { E_POPUP_ITEM, "00.uri.20", N_("_Add to Address Book"), emp_uri_popup_address_add, NULL, "contact-new", EM_POPUP_URI_MAILTO },
-};
-
-/* ********************************************************************** */
-
-#define LEN(x) (sizeof(x)/sizeof(x[0]))
-
-static void
-emp_apps_open_in(EPopup *ep, EPopupItem *item, void *data)
-{
- char *path;
- EPopupTarget *target = ep->target;
- CamelMimePart *part;
-
- if (target->type == EM_POPUP_TARGET_ATTACHMENTS) {
- EAttachment *attachment;
-
- attachment = E_ATTACHMENT (((EMPopupTargetAttachments *) target)->attachments->data);
- part = e_attachment_get_mime_part (attachment);
- } else
- part = ((EMPopupTargetPart *) target)->part;
-
- path = em_utils_temp_save_part(target->widget, part, TRUE);
- if (path) {
- 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);
-
- uris = g_list_append (uris, file);
- g_app_info_launch (app, uris, NULL, &error);
- g_object_unref (file);
- } else {
- char *uri;
-
- 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);
- }
-}
-
-static void
-emp_apps_popup_free(EPopup *ep, GSList *free_list, void *data)
-{
- while (free_list) {
- 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);
- g_slist_free_1(free_list);
-
- free_list = n;
- }
-}
-
-static void
-emp_standard_items_free(EPopup *ep, GSList *items, void *data)
-{
- g_slist_free(items);
-}
-
-static void
-emp_add_vcard (EPopup *ep, EPopupItem *item, void *data)
-{
- EPopupTarget *target = ep->target;
- CamelMimePart *part;
- CamelDataWrapper *content;
- CamelStreamMem *mem;
-
- if (target->type == EM_POPUP_TARGET_ATTACHMENTS) {
- EAttachment *attachment;
-
- attachment = E_ATTACHMENT (((EMPopupTargetAttachments *) target)->attachments->data);
- part = e_attachment_get_mime_part (attachment);
- } else
- part = ((EMPopupTargetPart *) target)->part;
-
- if (!part)
- return;
-
- content = camel_medium_get_content_object (CAMEL_MEDIUM (part));
- mem = CAMEL_STREAM_MEM (camel_stream_mem_new ());
-
- if (camel_data_wrapper_decode_to_stream (content, CAMEL_STREAM (mem)) == -1 ||
- !mem->buffer->data)
- g_warning ("Read part's content failed!");
- else {
- GString *vcard = g_string_new_len ((const gchar *) mem->buffer->data, mem->buffer->len);
-
- em_utils_add_vcard (target->widget, vcard->str);
-
- g_string_free (vcard, TRUE);
- }
-
- camel_object_unref (mem);
-}
-
-#if 0 /* KILL-BONOBO */
-static void
-emp_standard_menu_factory(EPopup *emp, void *data)
-{
- int i, len;
- EPopupItem *items;
- GSList *menus = NULL;
- GList *apps = NULL;
- char *mime_type = NULL;
- const char *filename = NULL;
-
- switch (emp->target->type) {
-#if 0
- case EM_POPUP_TARGET_SELECT:
- return;
- items = emp_standard_select_popups;
- len = LEN(emp_standard_select_popups);
- break;
-#endif
- case EM_POPUP_TARGET_URI: {
- /*EMPopupTargetURI *t = (EMPopupTargetURI *)target;*/
-
- items = emp_standard_uri_popups;
- len = LEN(emp_standard_uri_popups);
- break; }
- case EM_POPUP_TARGET_PART: {
- EMPopupTargetPart *t = (EMPopupTargetPart *)emp->target;
- mime_type = camel_data_wrapper_get_mime_type((CamelDataWrapper *)t->part);
- filename = camel_mime_part_get_filename(t->part);
-
- items = emp_standard_object_popups;
- len = LEN(emp_standard_object_popups);
- break; }
- case EM_POPUP_TARGET_ATTACHMENTS: {
- EMPopupTargetAttachments *t = (EMPopupTargetAttachments *)emp->target;
- GSList *list = t->attachments;
- EAttachment *attachment;
- CamelMimePart *mime_part;
-
- if (g_slist_length(list) != 1 || !((EAttachment *)list->data)->is_available_local) {
- items = NULL;
- len = 0;
- break;
- }
-
- /* Only one attachment selected */
- attachment = list->data;
- mime_part = e_attachment_get_mime_part (attachment);
- mime_type = camel_data_wrapper_get_mime_type (CAMEL_DATA_WRAPPER (mime_part));
- filename = camel_mime_part_get_filename (mime_part);
-
- items = emp_attachment_object_popups;
- len = LEN(emp_attachment_object_popups);
- break; }
- default:
- items = NULL;
- len = 0;
- }
-
- if (mime_type) {
- gchar *cp;
-
- /* GIO expects lowercase MIME types. */
- for (cp = mime_type; *cp != '\0'; cp++)
- *cp = g_ascii_tolower (*cp);
-
- cp = g_content_type_from_mime_type (mime_type);
- apps = g_app_info_get_all_for_type (cp ? cp : mime_type);
- g_free (cp);
-
- if (apps == NULL && strcmp (mime_type, "application/octet-stream") == 0) {
- if (filename != NULL) {
- gchar *name_type;
-
- name_type = e_util_guess_mime_type (filename, FALSE);
- cp = g_content_type_from_mime_type (name_type);
- apps = g_app_info_get_all_for_type (cp ? cp : name_type);
- g_free (cp);
- g_free (name_type);
- }
- }
-
- if (apps) {
- GString *label = g_string_new("");
- GSList *open_menus = NULL;
- GList *l;
-
- menus = g_slist_prepend(menus, (void *)&emp_standard_part_apps_bar);
-
- for (l = apps, i = 0; l; l = l->next, i++) {
- GAppInfo *app = l->data;
- EPopupItem *item;
-
- 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..."), g_app_info_get_name (app));
- item->activate = emp_apps_open_in;
- item->user_data = app;
-
- open_menus = g_slist_prepend(open_menus, item);
- }
-
- if (open_menus)
- e_popup_add_items(emp, open_menus, NULL, emp_apps_popup_free, NULL);
-
- g_string_free(label, TRUE);
- g_list_free(apps);
- }
-
- if (g_ascii_strcasecmp (mime_type, "text/x-vcard") == 0||
- g_ascii_strcasecmp (mime_type, "text/vcard") == 0) {
- EPopupItem *item;
-
- item = g_malloc0 (sizeof (*item));
- item->type = E_POPUP_ITEM;
- item->path = "00.00.vcf.00"; /* make it first item */
- item->label = _("_Add to Address Book");
- item->activate = emp_add_vcard;
- item->user_data = NULL;
- item->image = "contact-new";
-
- e_popup_add_items (emp, g_slist_append (NULL, item), NULL, NULL, NULL);
- }
-
- g_free (mime_type);
- }
-
- for (i=0;i<len;i++) {
- if ((items[i].visible & emp->target->mask) == 0)
- menus = g_slist_prepend(menus, &items[i]);
- }
-
- if (menus)
- e_popup_add_items(emp, menus, NULL, emp_standard_items_free, NULL);
-}
-#endif
-
/* ********************************************************************** */
/* Popup menu plugin handler */
diff --git a/plugins/save-attachments/ChangeLog b/plugins/save-attachments/ChangeLog
deleted file mode 100644
index 9980fdf13d..0000000000
--- a/plugins/save-attachments/ChangeLog
+++ /dev/null
@@ -1,102 +0,0 @@
-2009-01-28 Tor Lillqvist <tml@novell.com>
-
- * Makefile.am: Use -no-undefined and link with more libs on
- Windows.
-
-2008-09-19 Sankar P <psankar@novell.com>
-
-License Changes
-
- * save-attachments.c:
-
-2007-12-20 Matthew Barnes <mbarnes@redhat.com>
-
- ** Fixes part of bug #362638
-
- * save-attachments.c:
- Use the new MailMsg API for messages.
-
-2007-04-02 Sankar P <psankar@novell.com>
-
- * Committed on behalf of Gilles Dartiguelongue <dartigug@esiee.fr>
-
- * org-gnome-save-attachments.eplug.xml:
- Cleanup.
- Fixes part of #301149
-
-2007-03-29 Matthew Barnes <mbarnes@redhat.com>
-
- * save-attachments.c:
- Evolution requires GLib 2.10 now; remove dead backward-compatibility
- code for GLib < 2.8 (#418971).
-
-2007-01-27 Nickolay V. Shmyrev <nshmyrev@yandex.ru>
-
- * save-attachments.c: (save_got_message):
- mark strings as translatable. See bug #399381 for details.
-
-2006-07-07 Hiroyuki Ikezoe <poincare@ikezoe.net>
-
- ** Fixes bug #341369
- * save-attachments.c: fixing a memory leak.
-
-2006-02-28 Shi Pu <shi.pu@sun.com>
-
- ** Fixes #323853
-
- * save-attachments.c: (save_response), (entry_changed),
- (save_got_message):
- replace GnomeFileEntry by GtkFileChooserButton.
-
-2005-12-17 Tor Lillqvist <tml@novell.com>
-
- * save-attachments.c (entry_changed): Use GLib API to manipulate
- pathname.
-
-2005-05-16 Not Zed <NotZed@Ximian.com>
-
- * save-attachments.c: moved e-error to e-util
-
-2005-05-13 Rodney Dawes <dobey@novell.com>
-
- * org-gnome-save-attachments.xml: Update for new menu layout
-
-2005-05-12 Not Zed <NotZed@Ximian.com>
-
- * Makefile.am: setup built_sources/cleanfiles.
-
-2005-05-06 Not Zed <NotZed@Ximian.com>
-
- * Makefile.am:
- * org-gnome-save-attachments.eplug.xml: s/.in/.xml/ & i18n.
-
-2005-02-24 Björn Torkelsson <torkel@acc.umu.se>
-
- * org-gnome-save-attachments.eplug.in: Removed plugin from the
- name.
- Fixed description and added author
-
-2005-02-07 Not Zed <NotZed@Ximian.com>
-
- * save-attachments.c (save_part): fix the access() call test.
-
-2005-01-04 Philip Van Hoof <pvanhoof@gnome.org>
-
- * save-attachments.c: Use standard error messages
-
-2004-12-27 Philip Van Hoof <pvanhoof@gnome.org>
-
- * save-attachments.c: Warning when overwriting file
-
-2004-11-01 JP Rosevear <jpr@novell.com>
-
- * Makefile.am: dist xml menu file
-
-2004-11-01 JP Rosevear <jpr@novell.com>
-
- * Makefile.am: dist .eplug.in file
-
-2004-10-20 Not Zed <NotZed@Ximian.com>
-
- * Imported save-attachments example plugin.
-
diff --git a/plugins/save-attachments/Makefile.am b/plugins/save-attachments/Makefile.am
deleted file mode 100644
index 05c724a4e4..0000000000
--- a/plugins/save-attachments/Makefile.am
+++ /dev/null
@@ -1,31 +0,0 @@
-if OS_WIN32
-NO_UNDEFINED_REQUIRED_LIBS = \
- $(top_builddir)/mail/libevolution-mail.la \
- $(EVOLUTION_MAIL_LIBS) \
- $(GNOME_PLATFORM_LIBS) \
- $(top_builddir)/e-util/libeutil.la
-endif
-
-INCLUDES = \
- -I$(top_srcdir) \
- $(EVOLUTION_MAIL_CFLAGS)
-
-@EVO_PLUGIN_RULE@
-
-plugin_DATA = org-gnome-save-attachments.eplug org-gnome-save-attachments.xml
-plugin_LTLIBRARIES = liborg-gnome-save-attachments.la
-
-liborg_gnome_save_attachments_la_SOURCES = save-attachments.c
-liborg_gnome_save_attachments_la_LDFLAGS = -module \
- -avoid-version $(NO_UNDEFINED)
-
-liborg_gnome_save_attachments_la_LIBADD = \
- $(NO_UNDEFINED_REQUIRED_LIBS)
-
-
-EXTRA_DIST = \
- org-gnome-save-attachments.eplug.xml \
- org-gnome-save-attachments.xml
-
-BUILT_SOURCES = org-gnome-save-attachments.eplug
-CLEANFILES = $(BUILT_SOURCES)
diff --git a/plugins/save-attachments/org-gnome-save-attachments.eplug.xml b/plugins/save-attachments/org-gnome-save-attachments.eplug.xml
deleted file mode 100644
index d51b341db4..0000000000
--- a/plugins/save-attachments/org-gnome-save-attachments.eplug.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0"?>
-<e-plugin-list>
- <!-- the path to the shared library -->
- <e-plugin
- id="org.gnome.plugin.attachments.save"
- type="shlib"
- location="@PLUGINDIR@/liborg-gnome-save-attachments@SOEXT@"
- _name="Save attachments">
-
- <author name="Not Zed" email="NotZed@Ximian.com"/>
- <_description>A plugin for saving all attachments or parts of a message at once.</_description>
-
- <hook class="org.gnome.evolution.mail.bonobomenu:1.0">
- <menu id="org.gnome.evolution.mail.browser" target="select">
- <!-- the path to the bonobo menu description -->
- <ui file="@PLUGINDIR@/org-gnome-save-attachments.xml"/>
- <item
- type="item"
- verb="EPSASaveAttachments"
- path="/commands/EPSASaveAttachments"
- enable="one"
- activate="org_gnome_save_attachments_save"/>
- </menu>
- </hook>
- </e-plugin>
-</e-plugin-list>
diff --git a/plugins/save-attachments/org-gnome-save-attachments.xml b/plugins/save-attachments/org-gnome-save-attachments.xml
deleted file mode 100644
index 75f4aef7fb..0000000000
--- a/plugins/save-attachments/org-gnome-save-attachments.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<Root>
- <commands>
- <cmd name="EPSASaveAttachments" _label="Save Attachments..."
- _tip="Save all attachments"
- pixtype="stock" pixname="Save"/>
- </commands>
-
- <menu>
-<!--
- <placeholder name="MessagePlaceholder">
- <submenu name="Message">
- <placeholder name="MailMessageActions">
- <separator f="" name="emaillist5"/>
- <menuitem name="EPSASaveAttachments" verb=""/>
- </placeholder>
- </submenu>
- </placeholder>
--->
- </menu>
-</Root>
diff --git a/plugins/save-attachments/save-attachments.c b/plugins/save-attachments/save-attachments.c
deleted file mode 100644
index c48711c55a..0000000000
--- a/plugins/save-attachments/save-attachments.c
+++ /dev/null
@@ -1,392 +0,0 @@
-/*
- * 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 <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Michael Zucchi <notzed@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-/* This is prototype code only, this may, or may not, use undocumented
- * unstable or private internal function calls. */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <string.h>
-#include <stdio.h>
-
-#include <gtk/gtk.h>
-#include <glib/gi18n.h>
-#include <glib/gstdio.h>
-
-#include <camel/camel-folder.h>
-#include <camel/camel-exception.h>
-#include <camel/camel-mime-message.h>
-#include <camel/camel-multipart.h>
-#include <camel/camel-utf8.h>
-
-#include "e-util/e-error.h"
-
-#include "mail/em-menu.h"
-#include "mail/em-utils.h"
-
-/* these are sort of mail-internal */
-#include "mail/mail-mt.h"
-#include "mail/mail-ops.h"
-
-void org_gnome_save_attachments_save(EPlugin *ep, EMMenuTargetSelect *target);
-
-struct _save_data {
- CamelFolder *folder;
- char *uid;
- CamelMimeMessage *msg;
-
- char *path;
- char *base;
-
- GtkWidget *entry;
- GtkWidget *tree;
- GtkTreeStore *model;
-};
-
-static void
-free_data(struct _save_data *data)
-{
- if (data->msg)
- camel_object_unref(data->msg);
- g_free(data->base);
- g_free(data->path);
- g_free(data->uid);
- camel_object_unref(data->folder);
- if (data->model)
- g_object_unref(data->model);
- g_free(data);
-}
-
-static char *
-clean_name(const char *s)
-{
- GString *out = g_string_new("");
- int c;
- char *r;
-
- while ( (c = camel_utf8_getc((const unsigned char **)&s)) ) {
- if (!g_unichar_isprint(c) || ( c < 0x7f && strchr(" /'\"`&();|<>$%{}!", c )))
- c = '_';
- g_string_append_u(out, c);
- }
-
- r = g_strdup(out->str);
- g_string_free(out, TRUE);
-
- return r;
-}
-
-static void
-fill_model_rec(CamelMimeMessage *msg, CamelMimePart *part, GtkTreeStore *model, GtkTreeIter *parent, GString *name)
-{
- CamelDataWrapper *containee;
- int parts, i;
- char *type;
- GtkTreeIter iter;
- int len = name->len;
- CamelContentType *mime;
-
- containee = camel_medium_get_content_object((CamelMedium *)part);
- if (containee == NULL)
- return;
-
- mime = ((CamelDataWrapper *)containee)->mime_type;
- type = camel_content_type_simple(mime);
-
- if (CAMEL_IS_MULTIPART(containee)) {
- gtk_tree_store_append(model, &iter, parent);
- g_string_append_printf(name, ".multipart");
- gtk_tree_store_set(model, &iter, 0, FALSE, 1, type, 2, name->str, 3, name->str, 4, part, -1);
-
- parts = camel_multipart_get_number((CamelMultipart *)containee);
- for (i = 0; i < parts; i++) {
- CamelMimePart *mpart = camel_multipart_get_part((CamelMultipart *)containee, i);
-
- g_string_truncate(name, len);
- g_string_append_printf(name, ".%d", i);
- fill_model_rec(msg, mpart, model, &iter, name);
- }
- } else if (CAMEL_IS_MIME_MESSAGE(containee)) {
- gtk_tree_store_append(model, &iter, parent);
- g_string_append_printf(name, ".msg");
- gtk_tree_store_set(model, &iter, 0, FALSE, 1, type, 2, name->str, 3, name->str, 4, part, -1);
- fill_model_rec(msg, (CamelMimePart *)containee, model, &iter, name);
- } else {
- char *filename = NULL;
- const char *ext = NULL, *tmp;
- int save = FALSE;
-
- gtk_tree_store_append(model, &iter, parent);
- tmp = camel_mime_part_get_filename(part);
- if (tmp) {
- filename = clean_name(tmp);
- ext = strrchr(filename, '.');
- }
- tmp = camel_mime_part_get_disposition(part);
- if (tmp && !strcmp(tmp, "attachment"))
- save = TRUE;
-
- if (camel_content_type_is(mime, "text", "*")) {
- if (ext == NULL) {
- if ((ext = mime->subtype) == NULL || !strcmp(ext, "plain"))
- ext = "text";
- }
- } else if (camel_content_type_is(mime, "image", "*")) {
- if (ext == NULL) {
- if ((ext = mime->subtype) == NULL)
- ext = "image";
- }
- save = TRUE;
- }
-
- g_string_append_printf(name, ".%s", ext);
- gtk_tree_store_set(model, &iter, 0, save, 1, type, 2, filename?filename:name->str, 3, filename?NULL:name->str, 4, part, -1);
- g_free(filename);
- }
- g_free(type);
-
- g_string_truncate(name, len);
-}
-
-static void
-fill_model(CamelMimeMessage *msg, GtkTreeStore *model)
-{
- GString *name = g_string_new("");
- GtkTreeIter iter;
-
- gtk_tree_store_append(model, &iter, NULL);
- gtk_tree_store_set(model, &iter, 0, FALSE, 1, "message/rfc822", 2, ".msg", 3, ".msg", 4, msg, -1);
- fill_model_rec(msg, (CamelMimePart *)msg, model, &iter, name);
- g_string_free(name, TRUE);
-}
-
-static gboolean
-save_part(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, void *d)
-{
- struct _save_data *data = d;
- char *filename, *ext, *save;
- CamelMimePart *part;
- gboolean doit;
-
- /* TODO: check for existing file */
-
- gtk_tree_model_get(model, iter, 0, &doit, -1);
- if (!doit)
- return FALSE;
-
- gtk_tree_model_get(model, iter, 2, &filename, 3, &ext, 4, &part, -1);
- if (ext == NULL)
- save = g_build_filename(data->path, filename, NULL);
- else
- save = g_strdup_printf("%s%s", data->base, ext);
-
- /* FIXME: if part == data->msg then we need to save this
- * differently, not using the envelope MimePart */
-
- /*
- * The underlying em_utils_save_part_to_file ain't using gnome-vfs. Therefor
- * the POSIX access-call should suffice for checking the file existence.
- */
-
- if (g_access(save, F_OK) == 0)
- doit = e_error_run(NULL, E_ERROR_ASK_FILE_EXISTS_OVERWRITE, save, NULL) == GTK_RESPONSE_OK;
-
- if (doit)
- em_utils_save_part_to_file(NULL, save, part);
-
- g_free(ext);
- g_free(filename);
-
- return FALSE;
-}
-
-static void
-save_response(GtkWidget *d, int id, struct _save_data *data)
-{
- if (id == GTK_RESPONSE_OK) {
- char *tmp;
-
- data->base = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (data->entry));
- data->path = g_strdup(data->base);
- tmp = strrchr(data->path, '/');
- if (tmp)
- *tmp = 0;
- gtk_tree_model_foreach((GtkTreeModel *)data->model, save_part, data);
- }
-
- gtk_widget_destroy(d);
- free_data(data);
-}
-
-static gboolean
-entry_changed_update(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, void *d)
-{
- const char *name = d;
- char *filename, *ext;
-
- gtk_tree_model_get(model, iter, 3, &ext, -1);
- if (ext) {
- filename = g_strdup_printf("%s%s", name, ext);
- gtk_tree_store_set((GtkTreeStore *)model, iter, 2, filename, -1);
- g_free(filename);
- g_free(ext);
- }
-
- return FALSE;
-}
-
-static void
-entry_changed(GtkWidget *entry, struct _save_data *data)
-{
- char *path;
- char *basename = NULL;
- const char *file;
-
- path = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (data->entry));
- if (path == NULL
- || G_IS_DIR_SEPARATOR (path[strlen(path)-1])
- || (basename = g_path_get_basename(path)) == NULL
- || (basename[0] == '.' && basename[1] == '\0')
- || (g_file_test(path, G_FILE_TEST_IS_DIR)))
- file = "attachment";
- else
- file = basename;
-
- gtk_tree_model_foreach((GtkTreeModel *)data->model, entry_changed_update, (void *)file);
- g_free(path);
- g_free(basename);
-}
-
-static void
-toggle_changed(GtkWidget *entry, const char *spath, struct _save_data *data)
-{
- GtkTreePath *path;
- GtkTreeIter iter;
-
- path = gtk_tree_path_new_from_string(spath);
- if (gtk_tree_model_get_iter((GtkTreeModel *)data->model, &iter, path)) {
- gboolean on;
-
- gtk_tree_model_get((GtkTreeModel *)data->model, &iter, 0, &on, -1);
- gtk_tree_store_set(data->model, &iter, 0, !on, -1);
- }
-
- gtk_tree_path_free (path);
-}
-
-static void
-save_got_message(CamelFolder *folder, const char *uid, CamelMimeMessage *msg, void *d)
-{
- struct _save_data *data = d;
- GtkDialog *dialog;
- GtkWidget *w, *tree;
- GtkTreeStore *model;
- GtkCellRenderer *renderer;
-
- /* not found, the mailer will show an error box for this */
- if (msg == NULL) {
- free_data(data);
- return;
- }
-
- data->msg = msg;
- camel_object_ref(msg);
-
- dialog = (GtkDialog *)gtk_dialog_new_with_buttons(_("Save attachments"),
- NULL, /* target->parent? */
- 0,
- GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
- GTK_STOCK_SAVE, GTK_RESPONSE_OK,
- NULL);
- w = gtk_file_chooser_button_new (_("Select save base name"), GTK_FILE_CHOOSER_ACTION_OPEN);
- data->entry = w;
- g_object_set(w, "filechooser_action", GTK_FILE_CHOOSER_ACTION_SAVE, NULL);
- gtk_widget_show(w);
- gtk_box_pack_start((GtkBox *)dialog->vbox, w, FALSE, TRUE, 6);
-
- g_signal_connect(GTK_FILE_CHOOSER_BUTTON (w), "selection-changed", G_CALLBACK(entry_changed), data);
-
- model = gtk_tree_store_new(5, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER);
- data->model = model;
- fill_model(msg, model);
-
- tree = gtk_tree_view_new_with_model((GtkTreeModel *)model);
- data->tree = tree;
- gtk_widget_show(tree);
- gtk_tree_view_expand_all((GtkTreeView *)tree);
-
- renderer = gtk_cell_renderer_text_new();
- gtk_tree_view_insert_column_with_attributes((GtkTreeView *)tree, -1,
- _("MIME Type"), renderer, "text", 1, NULL);
- gtk_tree_view_set_expander_column((GtkTreeView *)tree, gtk_tree_view_get_column((GtkTreeView *)tree, 0));
-
- renderer = gtk_cell_renderer_toggle_new();
- g_object_set(renderer, "activatable", TRUE, NULL);
- g_signal_connect(renderer, "toggled", G_CALLBACK(toggle_changed), data);
-
- gtk_tree_view_insert_column_with_attributes((GtkTreeView *)tree, -1,
- _("Save"), renderer, "active", 0, NULL);
- renderer = gtk_cell_renderer_text_new();
- gtk_tree_view_insert_column_with_attributes((GtkTreeView *)tree, -1,
- _("Name"), renderer, "text", 2, NULL);
-
- w = g_object_new(gtk_frame_get_type(),
- "shadow_type", GTK_SHADOW_NONE,
- "label_widget", g_object_new(gtk_label_get_type(),
- "label", "<span weight=\"bold\">Attachments</span>",
- "use_markup", TRUE,
- "xalign", 0.0, NULL),
- "child", g_object_new(gtk_alignment_get_type(),
- "left_padding", 12,
- "top_padding", 6,
- "child", g_object_new(gtk_scrolled_window_get_type(),
- "hscrollbar_policy", GTK_POLICY_AUTOMATIC,
- "vscrollbar_policy", GTK_POLICY_AUTOMATIC,
- "shadow_type", GTK_SHADOW_IN,
- "child", tree,
- NULL),
- NULL),
- NULL);
- gtk_widget_show_all(w);
-
- gtk_box_pack_start((GtkBox *)dialog->vbox, w, TRUE, TRUE, 0);
- g_signal_connect(dialog, "response", G_CALLBACK(save_response), data);
- gtk_window_set_default_size((GtkWindow *)dialog, 500, 500);
- gtk_widget_show((GtkWidget *)dialog);
-}
-
-void
-org_gnome_save_attachments_save(EPlugin *ep, EMMenuTargetSelect *target)
-{
- struct _save_data *data;
-
- if (target->uids->len != 1)
- return;
-
- data = g_malloc0(sizeof(*data));
- data->folder = target->folder;
- camel_object_ref(data->folder);
- data->uid = g_strdup(target->uids->pdata[0]);
-
- mail_get_message(data->folder, data->uid, save_got_message, data, mail_msg_unordered_push);
-}
diff --git a/widgets/misc/Makefile.am b/widgets/misc/Makefile.am
index ad2f445eea..8ba66287f8 100644
--- a/widgets/misc/Makefile.am
+++ b/widgets/misc/Makefile.am
@@ -70,7 +70,6 @@ widgetsinclude_HEADERS = \
e-image-chooser.h \
e-map.h \
e-menu-tool-button.h \
- e-mime-part-utils.h \
e-online-button.h \
e-popup-action.h \
e-popup-menu.h \
@@ -134,7 +133,6 @@ libemiscwidgets_la_SOURCES = \
e-image-chooser.c \
e-map.c \
e-menu-tool-button.c \
- e-mime-part-utils.c \
e-online-button.c \
e-popup-action.c \
e-popup-menu.c \
diff --git a/widgets/misc/e-attachment-handler.c b/widgets/misc/e-attachment-handler.c
index dce139f9c3..03af1eec9b 100644
--- a/widgets/misc/e-attachment-handler.c
+++ b/widgets/misc/e-attachment-handler.c
@@ -155,3 +155,37 @@ e_attachment_handler_get_view (EAttachmentHandler *handler)
return E_ATTACHMENT_VIEW (handler->priv->view);
}
+
+GdkDragAction
+e_attachment_handler_get_drag_actions (EAttachmentHandler *handler)
+{
+ EAttachmentHandlerClass *class;
+
+ g_return_val_if_fail (E_IS_ATTACHMENT_HANDLER (handler), 0);
+
+ class = E_ATTACHMENT_HANDLER_GET_CLASS (handler);
+
+ if (class->get_drag_actions != NULL)
+ return class->get_drag_actions (handler);
+
+ return 0;
+}
+
+const GtkTargetEntry *
+e_attachment_handler_get_target_table (EAttachmentHandler *handler,
+ guint *n_targets)
+{
+ EAttachmentHandlerClass *class;
+
+ g_return_val_if_fail (E_IS_ATTACHMENT_HANDLER (handler), NULL);
+
+ class = E_ATTACHMENT_HANDLER_GET_CLASS (handler);
+
+ if (class->get_target_table != NULL)
+ return class->get_target_table (handler, n_targets);
+
+ if (n_targets != NULL)
+ *n_targets = 0;
+
+ return NULL;
+}
diff --git a/widgets/misc/e-attachment-handler.h b/widgets/misc/e-attachment-handler.h
index 8de5743ba6..05df3e8bbe 100644
--- a/widgets/misc/e-attachment-handler.h
+++ b/widgets/misc/e-attachment-handler.h
@@ -56,11 +56,22 @@ struct _EAttachmentHandler {
struct _EAttachmentHandlerClass {
GObjectClass parent_class;
+
+ GdkDragAction (*get_drag_actions) (EAttachmentHandler *handler);
+ const GtkTargetEntry *
+ (*get_target_table) (EAttachmentHandler *handler,
+ guint *n_targets);
};
GType e_attachment_handler_get_type (void);
EAttachmentView *
e_attachment_handler_get_view (EAttachmentHandler *handler);
+GdkDragAction e_attachment_handler_get_drag_actions
+ (EAttachmentHandler *handler);
+const GtkTargetEntry *
+ e_attachment_handler_get_target_table
+ (EAttachmentHandler *handler,
+ guint *n_targets);
G_END_DECLS
diff --git a/widgets/misc/e-attachment-paned.c b/widgets/misc/e-attachment-paned.c
index 42890236e9..f9f7bb1cca 100644
--- a/widgets/misc/e-attachment-paned.c
+++ b/widgets/misc/e-attachment-paned.c
@@ -729,3 +729,20 @@ e_attachment_paned_set_expanded (EAttachmentPaned *paned,
g_object_notify (G_OBJECT (paned), "expanded");
}
+
+void
+e_attachment_paned_drag_data_received (EAttachmentPaned *paned,
+ GdkDragContext *context,
+ gint x,
+ gint y,
+ GtkSelectionData *selection,
+ guint info,
+ guint time)
+{
+ g_return_if_fail (E_IS_ATTACHMENT_PANED (paned));
+
+ /* XXX Dirty hack for forwarding drop events. */
+ g_signal_emit_by_name (
+ paned->priv->icon_view, "drag-data-received",
+ context, x, y, selection, info, time);
+}
diff --git a/widgets/misc/e-attachment-paned.h b/widgets/misc/e-attachment-paned.h
index c15d642771..076ab6033e 100644
--- a/widgets/misc/e-attachment-paned.h
+++ b/widgets/misc/e-attachment-paned.h
@@ -70,6 +70,14 @@ void e_attachment_paned_set_active_view
gboolean e_attachment_paned_get_expanded (EAttachmentPaned *paned);
void e_attachment_paned_set_expanded (EAttachmentPaned *paned,
gboolean expanded);
+void e_attachment_paned_drag_data_received
+ (EAttachmentPaned *paned,
+ GdkDragContext *context,
+ gint x,
+ gint y,
+ GtkSelectionData *selection,
+ guint info,
+ guint time);
G_END_DECLS
diff --git a/widgets/misc/e-attachment-store.c b/widgets/misc/e-attachment-store.c
index e565d68cae..589f670f34 100644
--- a/widgets/misc/e-attachment-store.c
+++ b/widgets/misc/e-attachment-store.c
@@ -21,10 +21,12 @@
#include "e-attachment-store.h"
+#include <errno.h>
+#include <config.h>
#include <glib/gi18n.h>
#include "e-util/e-util.h"
-#include "e-util/gconf-bridge.h"
+#include "e-util/e-mktemp.h"
#define E_ATTACHMENT_STORE_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE \
@@ -32,8 +34,6 @@
struct _EAttachmentStorePrivate {
GHashTable *attachment_index;
- gchar *background_filename;
- gchar *background_options;
gchar *current_folder;
guint ignore_row_changed : 1;
@@ -41,8 +41,6 @@ struct _EAttachmentStorePrivate {
enum {
PROP_0,
- PROP_BACKGROUND_FILENAME,
- PROP_BACKGROUND_OPTIONS,
PROP_CURRENT_FOLDER,
PROP_NUM_ATTACHMENTS,
PROP_NUM_LOADING,
@@ -51,44 +49,6 @@ enum {
static gpointer parent_class;
-static const gchar *
-attachment_store_get_background_filename (EAttachmentStore *store)
-{
- return store->priv->background_filename;
-}
-
-static void
-attachment_store_set_background_filename (EAttachmentStore *store,
- const gchar *background_filename)
-{
- if (background_filename == NULL)
- background_filename = "";
-
- g_free (store->priv->background_filename);
- store->priv->background_filename = g_strdup (background_filename);
-
- g_object_notify (G_OBJECT (store), "background-filename");
-}
-
-static const gchar *
-attachment_store_get_background_options (EAttachmentStore *store)
-{
- return store->priv->background_options;
-}
-
-static void
-attachment_store_set_background_options (EAttachmentStore *store,
- const gchar *background_options)
-{
- if (background_options == NULL)
- background_options = "";
-
- g_free (store->priv->background_options);
- store->priv->background_options = g_strdup (background_options);
-
- g_object_notify (G_OBJECT (store), "background-options");
-}
-
static void
attachment_store_set_property (GObject *object,
guint property_id,
@@ -96,18 +56,6 @@ attachment_store_set_property (GObject *object,
GParamSpec *pspec)
{
switch (property_id) {
- case PROP_BACKGROUND_FILENAME:
- attachment_store_set_background_filename (
- E_ATTACHMENT_STORE (object),
- g_value_get_string (value));
- return;
-
- case PROP_BACKGROUND_OPTIONS:
- attachment_store_set_background_options (
- E_ATTACHMENT_STORE (object),
- g_value_get_string (value));
- return;
-
case PROP_CURRENT_FOLDER:
e_attachment_store_set_current_folder (
E_ATTACHMENT_STORE (object),
@@ -125,20 +73,6 @@ attachment_store_get_property (GObject *object,
GParamSpec *pspec)
{
switch (property_id) {
- case PROP_BACKGROUND_FILENAME:
- g_value_set_string (
- value,
- attachment_store_get_background_filename (
- E_ATTACHMENT_STORE (object)));
- return;
-
- case PROP_BACKGROUND_OPTIONS:
- g_value_set_string (
- value,
- attachment_store_get_background_options (
- E_ATTACHMENT_STORE (object)));
- return;
-
case PROP_CURRENT_FOLDER:
g_value_set_string (
value,
@@ -193,8 +127,6 @@ attachment_store_finalize (GObject *object)
g_hash_table_destroy (priv->attachment_index);
- g_free (priv->background_filename);
- g_free (priv->background_options);
g_free (priv->current_folder);
/* Chain up to parent's finalize() method. */
@@ -202,26 +134,6 @@ attachment_store_finalize (GObject *object)
}
static void
-attachment_store_constructed (GObject *object)
-{
- EAttachmentStorePrivate *priv;
- GConfBridge *bridge;
- const gchar *prop;
- const gchar *key;
-
- priv = E_ATTACHMENT_STORE_GET_PRIVATE (object);
- bridge = gconf_bridge_get ();
-
- prop = "background-filename";
- key = "/desktop/gnome/background/picture_filename";
- gconf_bridge_bind_property (bridge, key, object, prop);
-
- prop = "background-options";
- key = "/desktop/gnome/background/picture_options";
- gconf_bridge_bind_property (bridge, key, object, prop);
-}
-
-static void
attachment_store_class_init (EAttachmentStoreClass *class)
{
GObjectClass *object_class;
@@ -234,29 +146,6 @@ attachment_store_class_init (EAttachmentStoreClass *class)
object_class->get_property = attachment_store_get_property;
object_class->dispose = attachment_store_dispose;
object_class->finalize = attachment_store_finalize;
- object_class->constructed = attachment_store_constructed;
-
- g_object_class_install_property (
- object_class,
- PROP_BACKGROUND_FILENAME,
- g_param_spec_string (
- "background-filename",
- "Background Filename",
- NULL,
- NULL,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT));
-
- g_object_class_install_property (
- object_class,
- PROP_BACKGROUND_OPTIONS,
- g_param_spec_string (
- "background-options",
- "Background Options",
- NULL,
- NULL,
- G_PARAM_READWRITE |
- G_PARAM_CONSTRUCT));
g_object_class_install_property (
object_class,
@@ -737,101 +626,124 @@ e_attachment_store_run_save_dialog (EAttachmentStore *store,
return destination;
}
-/******************* e_attachment_store_save_list_async() ********************/
+/******************** e_attachment_store_get_uris_async() ********************/
-typedef struct _SaveContext SaveContext;
+typedef struct _UriContext UriContext;
-struct _SaveContext {
+struct _UriContext {
GSimpleAsyncResult *simple;
GList *attachment_list;
GError *error;
+ gchar **uris;
+ gint index;
};
-static SaveContext *
-attachment_store_save_context_new (EAttachmentStore *store,
- GList *attachment_list,
- GAsyncReadyCallback callback,
- gpointer user_data)
+static UriContext *
+attachment_store_uri_context_new (EAttachmentStore *store,
+ GList *attachment_list,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
- SaveContext *save_context;
+ UriContext *uri_context;
GSimpleAsyncResult *simple;
+ guint length;
+ gchar **uris;
simple = g_simple_async_result_new (
G_OBJECT (store), callback, user_data,
- e_attachment_store_save_list_async);
+ e_attachment_store_get_uris_async);
+
+ /* Add one for NULL terminator. */
+ length = g_list_length (attachment_list) + 1;
+ uris = g_malloc0 (sizeof (gchar *) * length);
- save_context = g_slice_new0 (SaveContext);
- save_context->simple = simple;
- save_context->attachment_list = g_list_copy (attachment_list);
+ uri_context = g_slice_new0 (UriContext);
+ uri_context->simple = simple;
+ uri_context->attachment_list = g_list_copy (attachment_list);
+ uri_context->uris = uris;
g_list_foreach (
- save_context->attachment_list,
+ uri_context->attachment_list,
(GFunc) g_object_ref, NULL);
- return save_context;
+ return uri_context;
}
static void
-attachment_store_save_context_free (SaveContext *save_context)
+attachment_store_uri_context_free (UriContext *uri_context)
{
/* Do not free the GSimpleAsyncResult. */
/* The attachment list should be empty now. */
- g_warn_if_fail (save_context->attachment_list != NULL);
+ g_warn_if_fail (uri_context->attachment_list == NULL);
/* So should the error. */
- g_warn_if_fail (save_context->error != NULL);
+ g_warn_if_fail (uri_context->error == NULL);
- g_slice_free (SaveContext, save_context);
+ g_strfreev (uri_context->uris);
+
+ g_slice_free (UriContext, uri_context);
}
static void
-attachment_store_save_list_finished_cb (EAttachment *attachment,
- GAsyncResult *result,
- SaveContext *save_context)
+attachment_store_get_uris_save_cb (EAttachment *attachment,
+ GAsyncResult *result,
+ UriContext *uri_context)
{
- GFile *file;
GSimpleAsyncResult *simple;
+ GFile *file;
+ gchar **uris;
+ gchar *uri;
GError *error = NULL;
file = e_attachment_save_finish (attachment, result, &error);
- if (file != NULL)
- g_object_unref (file);
/* Remove the attachment from the list. */
- save_context->attachment_list = g_list_remove (
- save_context->attachment_list, attachment);
+ uri_context->attachment_list = g_list_remove (
+ uri_context->attachment_list, attachment);
g_object_unref (attachment);
- /* If this is the first error, cancel the other jobs. */
- if (error != NULL && save_context->error == NULL) {
- g_propagate_error (&save_context->error, error);
- g_list_foreach (
- save_context->attachment_list,
- (GFunc) e_attachment_cancel, NULL);
+ if (file != NULL) {
+ uri = g_file_get_uri (file);
+ uri_context->uris[uri_context->index++] = uri;
+ g_object_unref (file);
- /* Otherwise, we can only report back one error. So if this is
- * something other than cancellation, dump it to the terminal. */
- } else if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
- g_warning ("%s", error->message);
+ } else if (error != NULL) {
+ /* If this is the first error, cancel the other jobs. */
+ if (uri_context->error == NULL) {
+ g_propagate_error (&uri_context->error, error);
+ g_list_foreach (
+ uri_context->attachment_list,
+ (GFunc) e_attachment_cancel, NULL);
+
+ /* Otherwise, we can only report back one error. So if
+ * this is something other than cancellation, dump it to
+ * the terminal. */
+ } else if (!g_error_matches (
+ error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
+ g_warning ("%s", error->message);
- if (error != NULL)
g_error_free (error);
+ }
/* If there's still jobs running, let them finish. */
- if (save_context->attachment_list != NULL)
+ if (uri_context->attachment_list != NULL)
return;
/* Steal the result. */
- simple = save_context->simple;
- save_context->simple = NULL;
+ simple = uri_context->simple;
+ uri_context->simple = NULL;
- /* Steal the error, too. */
- error = save_context->error;
- save_context->error = NULL;
+ /* And the URI list. */
+ uris = uri_context->uris;
+ uri_context->uris = NULL;
+
+ /* And the error. */
+ error = uri_context->error;
+ uri_context->error = NULL;
if (error == NULL)
- g_simple_async_result_set_op_res_gboolean (simple, TRUE);
+ g_simple_async_result_set_op_res_gpointer (simple, uris, NULL);
else {
g_simple_async_result_set_from_error (simple, error);
g_error_free (error);
@@ -839,63 +751,109 @@ attachment_store_save_list_finished_cb (EAttachment *attachment,
g_simple_async_result_complete (simple);
- attachment_store_save_context_free (save_context);
+ attachment_store_uri_context_free (uri_context);
}
void
-e_attachment_store_save_list_async (EAttachmentStore *store,
- GList *attachment_list,
- GFile *destination,
- GAsyncReadyCallback callback,
- gpointer user_data)
+e_attachment_store_get_uris_async (EAttachmentStore *store,
+ GList *attachment_list,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
- SaveContext *save_context;
+ GFile *temp_directory;
+ UriContext *uri_context;
+ GList *iter, *trash = NULL;
+ gchar *template;
+ gchar *path;
g_return_if_fail (E_IS_ATTACHMENT_STORE (store));
- g_return_if_fail (G_IS_FILE (destination));
g_return_if_fail (callback != NULL);
- /* Passing an empty list is silly, but we'll handle it. */
- if (attachment_list == NULL) {
+ uri_context = attachment_store_uri_context_new (
+ store, attachment_list, callback, user_data);
+
+ /* Grab the copied attachment list. */
+ attachment_list = uri_context->attachment_list;
+
+ /* First scan the list for attachments with a GFile. */
+ for (iter = attachment_list; iter != NULL; iter = iter->next) {
+ EAttachment *attachment = iter->data;
+ GFile *file;
+ gchar *uri;
+
+ file = e_attachment_get_file (attachment);
+ if (file == NULL)
+ continue;
+
+ uri = g_file_get_uri (file);
+ uri_context->uris[uri_context->index++] = uri;
+
+ /* Mark the list node for deletion. */
+ trash = g_list_prepend (trash, iter);
+ g_object_unref (attachment);
+ }
+
+ /* Expunge the list. */
+ for (iter = trash; iter != NULL; iter = iter->next) {
+ GList *link = iter->data;
+ attachment_list = g_list_delete_link (attachment_list, link);
+ }
+ g_list_free (trash);
+
+ uri_context->attachment_list = attachment_list;
+
+ /* Any remaining attachments in the list should have MIME parts
+ * only, so we need to save them all to a temporary directory.
+ * We use a directory so the files can retain their basenames. */
+ template = g_strdup_printf (PACKAGE "-%s-XXXXXX", g_get_user_name ());
+ path = e_mkdtemp (template);
+ g_free (template);
+
+ if (path == NULL) {
GSimpleAsyncResult *simple;
- simple = g_simple_async_result_new (
- G_OBJECT (store), callback, user_data,
- e_attachment_store_save_list_async);
- g_simple_async_result_set_op_res_gboolean (simple, TRUE);
+ /* Steal the result. */
+ simple = uri_context->simple;
+ uri_context->simple = NULL;
+
+ g_simple_async_result_set_error (
+ simple, G_FILE_ERROR,
+ g_file_error_from_errno (errno),
+ "%s", g_strerror (errno));
+
g_simple_async_result_complete_in_idle (simple);
+ attachment_store_uri_context_free (uri_context);
return;
}
- save_context = attachment_store_save_context_new (
- store, attachment_list, callback, user_data);
+ temp_directory = g_file_new_for_path (path);
- while (attachment_list != NULL) {
+ for (iter = attachment_list; iter != NULL; iter = iter->next)
e_attachment_save_async (
- E_ATTACHMENT (attachment_list->data),
- destination, (GAsyncReadyCallback)
- attachment_store_save_list_finished_cb,
- save_context);
- attachment_list = g_list_next (attachment_list);
- }
+ E_ATTACHMENT (iter->data),
+ temp_directory, (GAsyncReadyCallback)
+ attachment_store_get_uris_save_cb,
+ uri_context);
+
+ g_object_unref (temp_directory);
}
-gboolean
-e_attachment_store_save_list_finish (EAttachmentStore *store,
- GAsyncResult *result,
- GError **error)
+gchar **
+e_attachment_store_get_uris_finish (EAttachmentStore *store,
+ GAsyncResult *result,
+ GError **error)
{
GSimpleAsyncResult *simple;
- gboolean success;
+ gchar **uris;
g_return_val_if_fail (
g_simple_async_result_is_valid (result, G_OBJECT (store),
- e_attachment_store_save_list_async), FALSE);
+ e_attachment_store_get_uris_async), FALSE);
simple = G_SIMPLE_ASYNC_RESULT (result);
- success = g_simple_async_result_get_op_res_gboolean (simple);
+ uris = g_simple_async_result_get_op_res_gpointer (simple);
g_simple_async_result_propagate_error (simple, error);
g_object_unref (simple);
- return success;
+ return uris;
}
diff --git a/widgets/misc/e-attachment-store.h b/widgets/misc/e-attachment-store.h
index c672cb3c34..a6dd702b97 100644
--- a/widgets/misc/e-attachment-store.h
+++ b/widgets/misc/e-attachment-store.h
@@ -107,13 +107,12 @@ GFile * e_attachment_store_run_save_dialog
GtkWindow *parent);
/* Asynchronous Operations */
-void e_attachment_store_save_list_async
+void e_attachment_store_get_uris_async
(EAttachmentStore *store,
GList *attachment_list,
- GFile *destination,
GAsyncReadyCallback callback,
gpointer user_data);
-gboolean e_attachment_store_save_list_finish
+gchar ** e_attachment_store_get_uris_finish
(EAttachmentStore *store,
GAsyncResult *result,
GError **error);
diff --git a/widgets/misc/e-attachment-view.c b/widgets/misc/e-attachment-view.c
index b2dc62b934..d6dff653cc 100644
--- a/widgets/misc/e-attachment-view.c
+++ b/widgets/misc/e-attachment-view.c
@@ -36,38 +36,11 @@ enum {
LAST_SIGNAL
};
-enum {
- DND_TYPE_MESSAGE_RFC822,
- DND_TYPE_X_UID_LIST,
- DND_TYPE_TEXT_URI_LIST,
- DND_TYPE_NETSCAPE_URL,
- DND_TYPE_TEXT_VCARD,
- DND_TYPE_TEXT_CALENDAR
-};
-
-static GtkTargetEntry drop_types[] = {
- { "message/rfc822", 0, DND_TYPE_MESSAGE_RFC822 },
- { "x-uid-list", 0, DND_TYPE_X_UID_LIST },
- { "text/uri-list", 0, DND_TYPE_TEXT_URI_LIST },
- { "_NETSCAPE_URL", 0, DND_TYPE_NETSCAPE_URL },
- { "text/x-vcard", 0, DND_TYPE_TEXT_VCARD },
- { "text/calendar", 0, DND_TYPE_TEXT_CALENDAR }
-};
-
-/* The atoms need initialized at runtime. */
-static struct {
- const gchar *target;
- GdkAtom atom;
- GdkDragAction actions;
-} drag_info[] = {
- { "message/rfc822", NULL, GDK_ACTION_COPY },
- { "x-uid-list", NULL, GDK_ACTION_COPY |
- GDK_ACTION_MOVE |
- GDK_ACTION_ASK },
- { "text/uri-list", NULL, GDK_ACTION_COPY },
- { "_NETSCAPE_URL", NULL, GDK_ACTION_COPY },
- { "text/x-vcard", NULL, GDK_ACTION_COPY },
- { "text/calendar", NULL, GDK_ACTION_COPY }
+/* Note: Do not use the info field. */
+static GtkTargetEntry target_table[] = {
+ { "_NETSCAPE_URL", 0, 0 },
+ { "text/x-vcard", 0, 0 },
+ { "text/calendar", 0, 0 }
};
static const gchar *ui =
@@ -84,12 +57,6 @@ static const gchar *ui =
" <separator/>"
" <placeholder name='open-actions'/>"
" </popup>"
-" <popup name='dnd'>"
-" <menuitem action='drag-copy'/>"
-" <menuitem action='drag-move'/>"
-" <separator/>"
-" <menuitem action='drag-cancel'/>"
-" </popup>"
"</ui>";
static gulong signals[LAST_SIGNAL];
@@ -126,30 +93,6 @@ action_cancel_cb (GtkAction *action,
}
static void
-action_drag_cancel_cb (GtkAction *action,
- EAttachmentView *view)
-{
- EAttachmentViewPrivate *priv;
-
- priv = e_attachment_view_get_private (view);
- gtk_drag_finish (priv->drag_context, FALSE, FALSE, priv->time);
-}
-
-static void
-action_drag_copy_cb (GtkAction *action,
- EAttachmentView *view)
-{
- e_attachment_view_drag_action (view, GDK_ACTION_COPY);
-}
-
-static void
-action_drag_move_cb (GtkAction *action,
- EAttachmentView *view)
-{
- e_attachment_view_drag_action (view, GDK_ACTION_MOVE);
-}
-
-static void
action_open_in_cb (GtkAction *action,
EAttachmentView *view)
{
@@ -312,27 +255,6 @@ static GtkActionEntry standard_entries[] = {
NULL, /* XXX Add a tooltip! */
G_CALLBACK (action_cancel_cb) },
- { "drag-cancel",
- NULL,
- N_("Cancel _Drag"),
- NULL,
- NULL, /* XXX Add a tooltip! */
- G_CALLBACK (action_drag_cancel_cb) },
-
- { "drag-copy",
- NULL,
- N_("_Copy"),
- NULL,
- NULL, /* XXX Add a tooltip! */
- G_CALLBACK (action_drag_copy_cb) },
-
- { "drag-move",
- NULL,
- N_("_Move"),
- NULL,
- NULL, /* XXX Add a tooltip! */
- G_CALLBACK (action_drag_move_cb) },
-
{ "save-all",
GTK_STOCK_SAVE_AS,
N_("S_ave All"),
@@ -382,159 +304,153 @@ static GtkActionEntry editable_entries[] = {
};
static void
-drop_message_rfc822 (EAttachmentView *view,
- GtkSelectionData *selection_data,
- EAttachmentStore *store,
- GdkDragAction action)
+attachment_view_netscape_url (EAttachmentView *view,
+ GdkDragContext *drag_context,
+ gint x,
+ gint y,
+ GtkSelectionData *selection_data,
+ guint info,
+ guint time)
{
- EAttachmentViewPrivate *priv;
+ static GdkAtom atom = GDK_NONE;
+ EAttachmentStore *store;
EAttachment *attachment;
- CamelMimeMessage *message;
- CamelDataWrapper *wrapper;
- CamelStream *stream;
const gchar *data;
- gboolean success = FALSE;
- gboolean delete = FALSE;
gpointer parent;
+ gchar *copied_data;
+ gchar **strv;
gint length;
- priv = e_attachment_view_get_private (view);
+ if (G_UNLIKELY (atom == GDK_NONE))
+ atom = gdk_atom_intern_static_string ("_NETSCAPE_URL");
+
+ if (gtk_selection_data_get_target (selection_data) != atom)
+ return;
+
+ g_signal_stop_emission_by_name (view, "drag-data-received");
+
+ /* _NETSCAPE_URL is represented as "URI\nTITLE" */
data = (const gchar *) gtk_selection_data_get_data (selection_data);
length = gtk_selection_data_get_length (selection_data);
- stream = camel_stream_mem_new ();
- camel_stream_write (stream, data, length);
- camel_stream_reset (stream);
-
- message = camel_mime_message_new ();
- wrapper = CAMEL_DATA_WRAPPER (message);
+ copied_data = g_strndup (data, length);
+ strv = g_strsplit (copied_data, "\n", 2);
+ g_free (copied_data);
- if (camel_data_wrapper_construct_from_stream (wrapper, stream) == -1)
- goto exit;
+ store = e_attachment_view_get_store (view);
parent = gtk_widget_get_toplevel (GTK_WIDGET (view));
parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL;
- attachment = e_attachment_new_for_message (message);
+ attachment = e_attachment_new_for_uri (strv[0]);
e_attachment_store_add_attachment (store, attachment);
e_attachment_load_async (
attachment, (GAsyncReadyCallback)
e_attachment_load_handle_error, parent);
g_object_unref (attachment);
- success = TRUE;
- delete = (action == GDK_ACTION_MOVE);
-
-exit:
- camel_object_unref (message);
- camel_object_unref (stream);
+ g_strfreev (strv);
- gtk_drag_finish (priv->drag_context, success, delete, priv->time);
+ gtk_drag_finish (drag_context, TRUE, FALSE, time);
}
static void
-drop_netscape_url (EAttachmentView *view,
- GtkSelectionData *selection_data,
- EAttachmentStore *store,
- GdkDragAction action)
+attachment_view_text_calendar (EAttachmentView *view,
+ GdkDragContext *drag_context,
+ gint x,
+ gint y,
+ GtkSelectionData *selection_data,
+ guint info,
+ guint time)
{
- EAttachmentViewPrivate *priv;
+ static GdkAtom atom = GDK_NONE;
+ EAttachmentStore *store;
EAttachment *attachment;
+ CamelMimePart *mime_part;
+ GdkAtom data_type;
const gchar *data;
gpointer parent;
- gchar *copied_data;
- gchar **strv;
+ gchar *content_type;
gint length;
- /* _NETSCAPE_URL is represented as "URI\nTITLE" */
+ if (G_UNLIKELY (atom = GDK_NONE))
+ atom = gdk_atom_intern_static_string ("text/calendar");
- priv = e_attachment_view_get_private (view);
+ if (gtk_selection_data_get_target (selection_data) != atom)
+ return;
+
+ g_signal_stop_emission_by_name (view, "drag-data-received");
data = (const gchar *) gtk_selection_data_get_data (selection_data);
length = gtk_selection_data_get_length (selection_data);
+ data_type = gtk_selection_data_get_data_type (selection_data);
- copied_data = g_strndup (data, length);
- strv = g_strsplit (copied_data, "\n", 2);
- g_free (copied_data);
+ mime_part = camel_mime_part_new ();
+
+ content_type = gdk_atom_name (data_type);
+ camel_mime_part_set_content (mime_part, data, length, content_type);
+ camel_mime_part_set_disposition (mime_part, "inline");
+ g_free (content_type);
+
+ store = e_attachment_view_get_store (view);
parent = gtk_widget_get_toplevel (GTK_WIDGET (view));
parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL;
- attachment = e_attachment_new_for_uri (strv[0]);
+ attachment = e_attachment_new ();
+ e_attachment_set_mime_part (attachment, mime_part);
e_attachment_store_add_attachment (store, attachment);
e_attachment_load_async (
attachment, (GAsyncReadyCallback)
e_attachment_load_handle_error, parent);
g_object_unref (attachment);
- g_strfreev (strv);
-
- gtk_drag_finish (priv->drag_context, TRUE, FALSE, priv->time);
-}
-
-static void
-drop_text_uri_list (EAttachmentView *view,
- GtkSelectionData *selection_data,
- EAttachmentStore *store,
- GdkDragAction action)
-{
- EAttachmentViewPrivate *priv;
- gpointer parent;
- gchar **uris;
- gint ii;
-
- priv = e_attachment_view_get_private (view);
-
- uris = gtk_selection_data_get_uris (selection_data);
-
- parent = gtk_widget_get_toplevel (GTK_WIDGET (view));
- parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL;
-
- for (ii = 0; uris[ii] != NULL; ii++) {
- EAttachment *attachment;
-
- attachment = e_attachment_new_for_uri (uris[ii]);
- e_attachment_store_add_attachment (store, attachment);
- e_attachment_load_async (
- attachment, (GAsyncReadyCallback)
- e_attachment_load_handle_error, parent);
- g_object_unref (attachment);
- }
-
- g_strfreev (uris);
+ camel_object_unref (mime_part);
- gtk_drag_finish (priv->drag_context, TRUE, FALSE, priv->time);
+ gtk_drag_finish (drag_context, TRUE, FALSE, time);
}
static void
-drop_text_generic (EAttachmentView *view,
- GtkSelectionData *selection_data,
- EAttachmentStore *store,
- GdkDragAction action)
+attachment_view_text_x_vcard (EAttachmentView *view,
+ GdkDragContext *drag_context,
+ gint x,
+ gint y,
+ GtkSelectionData *selection_data,
+ guint info,
+ guint time)
{
- EAttachmentViewPrivate *priv;
+ static GdkAtom atom = GDK_NONE;
+ EAttachmentStore *store;
EAttachment *attachment;
CamelMimePart *mime_part;
- GdkAtom atom;
+ GdkAtom data_type;
const gchar *data;
gpointer parent;
gchar *content_type;
gint length;
- priv = e_attachment_view_get_private (view);
+ if (G_UNLIKELY (atom = GDK_NONE))
+ atom = gdk_atom_intern_static_string ("text/x-vcard");
+
+ if (gtk_selection_data_get_target (selection_data) != atom)
+ return;
+
+ g_signal_stop_emission_by_name (view, "drag-data-received");
data = (const gchar *) gtk_selection_data_get_data (selection_data);
length = gtk_selection_data_get_length (selection_data);
- atom = gtk_selection_data_get_data_type (selection_data);
+ data_type = gtk_selection_data_get_data_type (selection_data);
mime_part = camel_mime_part_new ();
- content_type = gdk_atom_name (atom);
+ content_type = gdk_atom_name (data_type);
camel_mime_part_set_content (mime_part, data, length, content_type);
camel_mime_part_set_disposition (mime_part, "inline");
g_free (content_type);
+ store = e_attachment_view_get_store (view);
+
parent = gtk_widget_get_toplevel (GTK_WIDGET (view));
parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL;
@@ -548,22 +464,49 @@ drop_text_generic (EAttachmentView *view,
camel_object_unref (mime_part);
- gtk_drag_finish (priv->drag_context, TRUE, FALSE, priv->time);
+ gtk_drag_finish (drag_context, TRUE, FALSE, time);
}
static void
-drop_x_uid_list (EAttachmentView *view,
- GtkSelectionData *selection_data,
- EAttachmentStore *store,
- GdkDragAction action)
+attachment_view_uris (EAttachmentView *view,
+ GdkDragContext *drag_context,
+ gint x,
+ gint y,
+ GtkSelectionData *selection_data,
+ guint info,
+ guint time)
{
- EAttachmentViewPrivate *priv;
+ EAttachmentStore *store;
+ gpointer parent;
+ gchar **uris;
+ gint ii;
- /* FIXME Ugh, this looks painful. Requires mailer stuff. */
+ uris = gtk_selection_data_get_uris (selection_data);
- priv = e_attachment_view_get_private (view);
+ if (uris == NULL)
+ return;
+
+ g_signal_stop_emission_by_name (view, "drag-data-received");
+
+ store = e_attachment_view_get_store (view);
+
+ parent = gtk_widget_get_toplevel (GTK_WIDGET (view));
+ parent = GTK_WIDGET_TOPLEVEL (parent) ? parent : NULL;
+
+ for (ii = 0; uris[ii] != NULL; ii++) {
+ EAttachment *attachment;
+
+ attachment = e_attachment_new_for_uri (uris[ii]);
+ e_attachment_store_add_attachment (store, attachment);
+ e_attachment_load_async (
+ attachment, (GAsyncReadyCallback)
+ e_attachment_load_handle_error, parent);
+ g_object_unref (attachment);
+ }
- gtk_drag_finish (priv->drag_context, FALSE, FALSE, priv->time);
+ g_strfreev (uris);
+
+ gtk_drag_finish (drag_context, TRUE, FALSE, time);
}
static void
@@ -669,10 +612,48 @@ attachment_view_update_actions (EAttachmentView *view)
}
static void
-attachment_view_class_init (EAttachmentViewIface *iface)
+attachment_view_init_handlers (EAttachmentView *view)
{
- gint ii;
+ EAttachmentViewPrivate *priv;
+ GtkTargetList *target_list;
+ GType *children;
+ guint ii;
+
+ priv = e_attachment_view_get_private (view);
+
+ target_list = gtk_target_list_new (
+ target_table, G_N_ELEMENTS (target_table));
+
+ gtk_target_list_add_uri_targets (target_list, 0);
+
+ priv->handlers = g_ptr_array_new ();
+ priv->target_list = target_list;
+ priv->drag_actions = GDK_ACTION_COPY;
+
+ children = g_type_children (E_TYPE_ATTACHMENT_HANDLER, NULL);
+
+ for (ii = 0; children[ii] != G_TYPE_INVALID; ii++) {
+ EAttachmentHandler *handler;
+ const GtkTargetEntry *targets;
+ guint n_targets;
+
+ handler = g_object_new (children[ii], "view", view, NULL);
+ targets = e_attachment_handler_get_target_table (
+ handler, &n_targets);
+ gtk_target_list_add_table (target_list, targets, n_targets);
+ priv->drag_actions |=
+ e_attachment_handler_get_drag_actions (handler);
+
+ g_ptr_array_add (priv->handlers, handler);
+ }
+
+ g_free (children);
+}
+
+static void
+attachment_view_class_init (EAttachmentViewIface *iface)
+{
iface->update_actions = attachment_view_update_actions;
g_object_interface_install_property (
@@ -693,11 +674,6 @@ attachment_view_class_init (EAttachmentViewIface *iface)
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
-
- for (ii = 0; ii < G_N_ELEMENTS (drag_info); ii++) {
- const gchar *target = drag_info[ii].target;
- drag_info[ii].atom = gdk_atom_intern (target, FALSE);
- }
}
GType
@@ -738,15 +714,10 @@ e_attachment_view_init (EAttachmentView *view)
GtkUIManager *ui_manager;
GtkActionGroup *action_group;
const gchar *domain = GETTEXT_PACKAGE;
- GType *children;
- guint ii;
GError *error = NULL;
priv = e_attachment_view_get_private (view);
- e_attachment_view_drag_source_set (view);
- e_attachment_view_drag_dest_set (view);
-
ui_manager = gtk_ui_manager_new ();
priv->merge_id = gtk_ui_manager_new_merge_id (ui_manager);
priv->ui_manager = ui_manager;
@@ -783,14 +754,28 @@ e_attachment_view_init (EAttachmentView *view)
G_OBJECT (view), "editable",
G_OBJECT (priv->editable_actions), "visible");
- /* Instantiate attachment handlers. */
- children = g_type_children (E_TYPE_ATTACHMENT_HANDLER, NULL);
- for (ii = 0; children[ii] != G_TYPE_INVALID; ii++) {
- EAttachmentHandler *handler;
- handler = g_object_new (children[ii], "view", view, NULL);
- priv->handlers = g_list_prepend (priv->handlers, handler);
- }
- g_free (children);
+ attachment_view_init_handlers (view);
+
+ e_attachment_view_drag_source_set (view);
+ e_attachment_view_drag_dest_set (view);
+
+ /* Connect built-in drag and drop handlers. */
+
+ g_signal_connect (
+ view, "drag-data-received",
+ G_CALLBACK (attachment_view_netscape_url), NULL);
+
+ g_signal_connect (
+ view, "drag-data-received",
+ G_CALLBACK (attachment_view_text_calendar), NULL);
+
+ g_signal_connect (
+ view, "drag-data-received",
+ G_CALLBACK (attachment_view_text_x_vcard), NULL);
+
+ g_signal_connect (
+ view, "drag-data-received",
+ G_CALLBACK (attachment_view_uris), NULL);
}
void
@@ -800,9 +785,13 @@ e_attachment_view_dispose (EAttachmentView *view)
priv = e_attachment_view_get_private (view);
- g_list_foreach (priv->handlers, (GFunc) g_object_unref, NULL);
- g_list_free (priv->handlers);
- priv->handlers = NULL;
+ g_ptr_array_foreach (priv->handlers, (GFunc) g_object_unref, NULL);
+ g_ptr_array_set_size (priv->handlers, 0);
+
+ if (priv->target_list != NULL) {
+ gtk_target_list_unref (priv->target_list);
+ priv->target_list = NULL;
+ }
if (priv->ui_manager != NULL) {
g_object_unref (priv->ui_manager);
@@ -823,11 +812,6 @@ e_attachment_view_dispose (EAttachmentView *view)
g_object_unref (priv->openwith_actions);
priv->openwith_actions = NULL;
}
-
- if (priv->drag_context != NULL) {
- g_object_unref (priv->drag_context);
- priv->drag_context = NULL;
- }
}
void
@@ -837,8 +821,7 @@ e_attachment_view_finalize (EAttachmentView *view)
priv = e_attachment_view_get_private (view);
- if (priv->selection_data != NULL)
- gtk_selection_data_free (priv->selection_data);
+ g_ptr_array_free (priv->handlers, TRUE);
}
EAttachmentViewPrivate *
@@ -893,6 +876,30 @@ e_attachment_view_set_editable (EAttachmentView *view,
g_object_notify (G_OBJECT (view), "editable");
}
+GtkTargetList *
+e_attachment_view_get_target_list (EAttachmentView *view)
+{
+ EAttachmentViewPrivate *priv;
+
+ g_return_val_if_fail (E_IS_ATTACHMENT_VIEW (view), NULL);
+
+ priv = e_attachment_view_get_private (view);
+
+ return priv->target_list;
+}
+
+GdkDragAction
+e_attachment_view_get_drag_actions (EAttachmentView *view)
+{
+ EAttachmentViewPrivate *priv;
+
+ g_return_val_if_fail (E_IS_ATTACHMENT_VIEW (view), 0);
+
+ priv = e_attachment_view_get_private (view);
+
+ return priv->drag_actions;
+}
+
GList *
e_attachment_view_get_selected_attachments (EAttachmentView *view)
{
@@ -1257,6 +1264,24 @@ e_attachment_view_drag_end (EAttachmentView *view,
g_return_if_fail (GDK_IS_DRAG_CONTEXT (context));
}
+static void
+attachment_view_got_uris_cb (EAttachmentStore *store,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ struct {
+ gchar **uris;
+ gboolean done;
+ } *status = user_data;
+
+ /* XXX Since this is a best-effort function,
+ * should we care about errors? */
+ status->uris = e_attachment_store_get_uris_finish (
+ store, result, NULL);
+
+ status->done = TRUE;
+}
+
void
e_attachment_view_drag_data_get (EAttachmentView *view,
GdkDragContext *context,
@@ -1264,56 +1289,65 @@ e_attachment_view_drag_data_get (EAttachmentView *view,
guint info,
guint time)
{
- GList *selected, *iter;
- gchar **uris;
- gint ii = 0;
+ EAttachmentStore *store;
+ GList *selected;
+
+ struct {
+ gchar **uris;
+ gboolean done;
+ } status;
g_return_if_fail (E_IS_ATTACHMENT_VIEW (view));
g_return_if_fail (GDK_IS_DRAG_CONTEXT (context));
g_return_if_fail (selection != NULL);
+ status.uris = NULL;
+ status.done = FALSE;
+
+ store = e_attachment_view_get_store (view);
+
selected = e_attachment_view_get_selected_attachments (view);
if (selected == NULL)
return;
- uris = g_malloc0 (sizeof (gchar *) * (g_list_length (selected) + 1));
+ e_attachment_store_get_uris_async (
+ store, selected, (GAsyncReadyCallback)
+ attachment_view_got_uris_cb, &status);
- for (iter = selected; iter != NULL; iter = iter->next) {
- EAttachment *attachment = iter->data;
- GFile *file;
-
- /* FIXME Need to handle attachments with no GFile. */
- file = e_attachment_get_file (attachment);
- if (file == NULL)
- continue;
+ g_list_foreach (selected, (GFunc) g_object_unref, NULL);
+ g_list_free (selected);
- uris[ii++] = g_file_get_uri (file);
- }
+ /* We can't return until we have results, so crank
+ * the main loop until the callback gets triggered. */
+ while (!status.done)
+ if (gtk_main_iteration ())
+ break;
- gtk_selection_data_set_uris (selection, uris);
+ if (status.uris != NULL)
+ gtk_selection_data_set_uris (selection, status.uris);
- g_strfreev (uris);
+ g_strfreev (status.uris);
}
void
e_attachment_view_drag_dest_set (EAttachmentView *view)
{
+ EAttachmentViewPrivate *priv;
GtkTargetEntry *targets;
- GtkTargetList *list;
gint n_targets;
g_return_if_fail (E_IS_ATTACHMENT_VIEW (view));
- list = gtk_target_list_new (NULL, 0);
- /* FIXME Add targets here... */
- targets = gtk_target_table_new_from_list (list, &n_targets);
+ priv = e_attachment_view_get_private (view);
+
+ targets = gtk_target_table_new_from_list (
+ priv->target_list, &n_targets);
gtk_drag_dest_set (
GTK_WIDGET (view), GTK_DEST_DEFAULT_ALL,
- targets, n_targets, GDK_ACTION_COPY);
+ targets, n_targets, priv->drag_actions);
gtk_target_table_free (targets, n_targets);
- gtk_target_list_unref (list);
}
void
@@ -1324,61 +1358,6 @@ e_attachment_view_drag_dest_unset (EAttachmentView *view)
gtk_drag_dest_unset (GTK_WIDGET (view));
}
-void
-e_attachment_view_drag_action (EAttachmentView *view,
- GdkDragAction action)
-{
- EAttachmentViewPrivate *priv;
- GtkSelectionData *selection_data;
- EAttachmentStore *store;
- GdkAtom atom;
- gchar *name;
-
- g_return_if_fail (E_IS_ATTACHMENT_VIEW (view));
-
- priv = e_attachment_view_get_private (view);
-
- selection_data = priv->selection_data;
- store = e_attachment_view_get_store (view);
- atom = gtk_selection_data_get_data_type (selection_data);
-
- switch (priv->info) {
- case DND_TYPE_MESSAGE_RFC822:
- drop_message_rfc822 (
- view, selection_data, store, action);
- return;
-
- case DND_TYPE_NETSCAPE_URL:
- drop_netscape_url (
- view, selection_data, store, action);
- return;
-
- case DND_TYPE_TEXT_URI_LIST:
- drop_text_uri_list (
- view, selection_data, store, action);
- return;
-
- case DND_TYPE_TEXT_VCARD:
- case DND_TYPE_TEXT_CALENDAR:
- drop_text_generic (
- view, selection_data, store, action);
- return;
-
- case DND_TYPE_X_UID_LIST:
- drop_x_uid_list (
- view, selection_data, store, action);
- return;
-
- default:
- name = gdk_atom_name (atom);
- g_warning ("Unknown drag type: %s", name);
- g_free (name);
- break;
- }
-
- gtk_drag_finish (priv->drag_context, FALSE, FALSE, priv->time);
-}
-
gboolean
e_attachment_view_drag_motion (EAttachmentView *view,
GdkDragContext *context,
@@ -1386,27 +1365,20 @@ e_attachment_view_drag_motion (EAttachmentView *view,
gint y,
guint time)
{
- GList *iter;
- GdkDragAction actions = 0;
+ EAttachmentViewPrivate *priv;
+ GdkDragAction actions;
GdkDragAction chosen_action;
g_return_val_if_fail (E_IS_ATTACHMENT_VIEW (view), FALSE);
g_return_val_if_fail (GDK_IS_DRAG_CONTEXT (context), FALSE);
+ priv = e_attachment_view_get_private (view);
+
/* Disallow drops if we're not editable. */
if (!e_attachment_view_get_editable (view))
return FALSE;
- for (iter = context->targets; iter != NULL; iter = iter->next) {
- GdkAtom atom = iter->data;
- gint ii;
-
- for (ii = 0; ii < G_N_ELEMENTS (drag_info); ii++)
- if (atom == drag_info[ii].atom)
- actions |= drag_info[ii].actions;
- }
-
- actions &= context->actions;
+ actions = priv->drag_actions & context->actions;
chosen_action = context->suggested_action;
if (chosen_action == GDK_ACTION_ASK) {
@@ -1441,53 +1413,31 @@ e_attachment_view_drag_drop (EAttachmentView *view,
void
e_attachment_view_drag_data_received (EAttachmentView *view,
- GdkDragContext *context,
+ GdkDragContext *drag_context,
gint x,
gint y,
- GtkSelectionData *selection,
+ GtkSelectionData *selection_data,
guint info,
guint time)
{
- EAttachmentViewPrivate *priv;
- GtkUIManager *ui_manager;
- GdkDragAction action;
+ GdkAtom atom;
+ gchar *name;
g_return_if_fail (E_IS_ATTACHMENT_VIEW (view));
- g_return_if_fail (GDK_IS_DRAG_CONTEXT (context));
- g_return_if_fail (selection != NULL);
-
- priv = e_attachment_view_get_private (view);
- ui_manager = e_attachment_view_get_ui_manager (view);
+ g_return_if_fail (GDK_IS_DRAG_CONTEXT (drag_context));
- action = context->action;
+ /* Drop handlers are supposed to stop further emission of the
+ * "drag-data-received" signal if they can handle the data. If
+ * we get this far it means none of the handlers were successful,
+ * so report the drop as failed. */
- if (gtk_selection_data_get_data (selection) == NULL)
- return;
-
- if (gtk_selection_data_get_length (selection) == -1)
- return;
-
- if (priv->drag_context != NULL)
- g_object_unref (priv->drag_context);
-
- if (priv->selection_data != NULL)
- gtk_selection_data_free (priv->selection_data);
+ atom = gtk_selection_data_get_target (selection_data);
- priv->drag_context = g_object_ref (context);
- priv->selection_data = gtk_selection_data_copy (selection);
- priv->info = info;
- priv->time = time;
+ name = gdk_atom_name (atom);
+ g_warning ("Unknown selection target: %s", name);
+ g_free (name);
- if (action == GDK_ACTION_ASK) {
- GtkWidget *menu;
-
- menu = gtk_ui_manager_get_widget (ui_manager, "/dnd");
- g_return_if_fail (GTK_IS_MENU (menu));
-
- gtk_menu_popup (
- GTK_MENU (menu), NULL, NULL, NULL, NULL, 0, time);
- } else
- e_attachment_view_drag_action (view, action);
+ gtk_drag_finish (drag_context, FALSE, FALSE, time);
}
GtkAction *
diff --git a/widgets/misc/e-attachment-view.h b/widgets/misc/e-attachment-view.h
index 16a7ac1967..8b625d0d8a 100644
--- a/widgets/misc/e-attachment-view.h
+++ b/widgets/misc/e-attachment-view.h
@@ -93,7 +93,11 @@ struct _EAttachmentViewIface {
struct _EAttachmentViewPrivate {
/* Attachment Handlers */
- GList *handlers;
+ GPtrArray *handlers;
+
+ /* Drag Destination */
+ GtkTargetList *target_list;
+ GdkDragAction drag_actions;
/* Popup Menu Management */
GtkUIManager *ui_manager;
@@ -102,12 +106,6 @@ struct _EAttachmentViewPrivate {
GtkActionGroup *openwith_actions;
guint merge_id;
- /* Drag and Drop State */
- GdkDragContext *drag_context;
- GtkSelectionData *selection_data;
- guint info;
- guint time;
-
guint editable : 1;
};
@@ -124,6 +122,10 @@ EAttachmentStore *
gboolean e_attachment_view_get_editable (EAttachmentView *view);
void e_attachment_view_set_editable (EAttachmentView *view,
gboolean editable);
+GtkTargetList * e_attachment_view_get_target_list
+ (EAttachmentView *view);
+GdkDragAction e_attachment_view_get_drag_actions
+ (EAttachmentView *view);
GList * e_attachment_view_get_selected_attachments
(EAttachmentView *view);
void e_attachment_view_open_path (EAttachmentView *view,
@@ -182,8 +184,6 @@ void e_attachment_view_drag_data_get (EAttachmentView *view,
void e_attachment_view_drag_dest_set (EAttachmentView *view);
void e_attachment_view_drag_dest_unset
(EAttachmentView *view);
-void e_attachment_view_drag_action (EAttachmentView *view,
- GdkDragAction action);
gboolean e_attachment_view_drag_motion (EAttachmentView *view,
GdkDragContext *context,
gint x,
diff --git a/widgets/misc/e-attachment.c b/widgets/misc/e-attachment.c
index fb84261fa2..bd9795c908 100644
--- a/widgets/misc/e-attachment.c
+++ b/widgets/misc/e-attachment.c
@@ -22,6 +22,7 @@
#include "e-attachment.h"
#include <errno.h>
+#include <config.h>
#include <glib/gi18n.h>
#include <camel/camel-iconv.h>
#include <camel/camel-data-wrapper.h>
@@ -32,6 +33,7 @@
#include <camel/camel-stream-vfs.h>
#include "e-util/e-util.h"
+#include "e-util/e-mktemp.h"
#include "e-attachment-store.h"
#define E_ATTACHMENT_GET_PRIVATE(obj) \
@@ -1914,18 +1916,30 @@ static void
attachment_open_save_temporary (OpenContext *open_context)
{
GFile *file;
+ gchar *template;
gchar *path;
- gint fd;
GError *error = NULL;
- fd = e_file_open_tmp (&path, &error);
+ errno = 0;
+ /* XXX This could trigger a blocking temp directory cleanup. */
+ template = g_strdup_printf (PACKAGE "-%s-XXXXXX", g_get_user_name ());
+ path = e_mktemp (template);
+ g_free (template);
+
+ /* XXX Let's hope errno got set properly. */
+ if (path == NULL)
+ g_set_error (
+ &error, G_FILE_ERROR,
+ g_file_error_from_errno (errno),
+ "%s", g_strerror (errno));
+
+ /* We already know if there's an error, but this does the cleanup. */
if (attachment_open_check_for_error (open_context, error))
return;
file = g_file_new_for_path (path);
- close (fd);
g_free (path);
e_attachment_save_async (
@@ -2519,8 +2533,11 @@ e_attachment_save_handle_error (EAttachment *attachment,
g_return_if_fail (GTK_IS_WINDOW (parent));
file = e_attachment_save_finish (attachment, result, &error);
- if (file != NULL)
+
+ if (file != NULL) {
g_object_unref (file);
+ return;
+ }
/* Ignore cancellations. */
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED))
diff --git a/widgets/misc/e-mime-part-utils.c b/widgets/misc/e-mime-part-utils.c
deleted file mode 100644
index 3238ca93f5..0000000000
--- a/widgets/misc/e-mime-part-utils.c
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * 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 <http://www.gnu.org/licenses/>
- *
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#include "e-mime-part-utils.h"
-
-#include <errno.h>
-#include <gio/gio.h>
-#include <glib/gi18n.h>
-#include <camel/camel-stream-vfs.h>
-
-#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);
-}
diff --git a/widgets/misc/e-mime-part-utils.h b/widgets/misc/e-mime-part-utils.h
deleted file mode 100644
index e923e07c8d..0000000000
--- a/widgets/misc/e-mime-part-utils.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * e-mime-part-utils.h
- *
- * 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 <http://www.gnu.org/licenses/>
- *
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef E_MIME_PART_UTILS_H
-#define E_MIME_PART_UTILS_H
-
-#include <gtk/gtk.h>
-#include <camel/camel-mime-part.h>
-#include <shell/e-shell-window.h>
-
-G_BEGIN_DECLS
-
-GList * e_mime_part_utils_get_apps (CamelMimePart *mime_part);
-gboolean e_mime_part_utils_save_to_file (CamelMimePart *mime_part,
- GFile *file,
- GError **error);
-
-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);
-
-G_END_DECLS
-
-#endif /* E_MIME_PART_UTILS_H */