aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mail/ChangeLog13
-rw-r--r--mail/component-factory.c31
-rw-r--r--mail/folder-browser.c200
3 files changed, 193 insertions, 51 deletions
diff --git a/mail/ChangeLog b/mail/ChangeLog
index 54f486da5c..9d242b1508 100644
--- a/mail/ChangeLog
+++ b/mail/ChangeLog
@@ -1,5 +1,18 @@
2001-06-26 Jeffrey Stedfast <fejj@ximian.com>
+ * component-factory.c (message_rfc822_dnd): No longer returns a
+ gboolean and also takes a CamelException.
+ (destination_folder_handle_drop): Do better error checking.
+
+ * folder-browser.c (my_folder_browser_init): Connect to the
+ tree-drag-data-recieved signal.
+ (message_list_drag_data_recieved): New function that handles the
+ recieving end of the DnD event.
+ (x_evolution_message_parse): New convenience function to parse the
+ x-evolution-message type so that the cut/paste and DnD code can
+ share it.
+ (selection_received): Use x_evolution_message_parse().
+
* mail-config.c (config_read): Read in the default show_preview
value.
(mail_config_write_on_exit): Save the default show_preview value
diff --git a/mail/component-factory.c b/mail/component-factory.c
index 9c375786b7..6865f829b9 100644
--- a/mail/component-factory.c
+++ b/mail/component-factory.c
@@ -291,19 +291,15 @@ destination_folder_handle_motion (EvolutionShellComponentDndDestinationFolder *f
return TRUE;
}
-static gboolean
-message_rfc822_dnd (CamelFolder *dest, CamelStream *stream)
+static void
+message_rfc822_dnd (CamelFolder *dest, CamelStream *stream, CamelException *ex)
{
- gboolean retval = FALSE;
CamelMimeParser *mp;
- CamelException *ex;
mp = camel_mime_parser_new ();
camel_mime_parser_scan_from (mp, TRUE);
camel_mime_parser_init_with_stream (mp, stream);
- ex = camel_exception_new ();
-
while (camel_mime_parser_step (mp, 0, 0) == HSCAN_FROM) {
CamelMessageInfo *info;
CamelMimeMessage *msg;
@@ -312,25 +308,21 @@ message_rfc822_dnd (CamelFolder *dest, CamelStream *stream)
if (camel_mime_part_construct_from_parser (CAMEL_MIME_PART (msg), mp) == -1) {
camel_object_unref (CAMEL_OBJECT (msg));
break;
- } else {
- /* we got at least 1 message so we will return TRUE */
- retval = TRUE;
}
/* append the message to the folder... */
info = g_new0 (CamelMessageInfo, 1);
camel_folder_append_message (dest, msg, info, ex);
- camel_exception_clear (ex);
camel_object_unref (CAMEL_OBJECT (msg));
+ if (camel_exception_is_set (ex))
+ break;
+
/* skip over the FROM_END state */
camel_mime_parser_step (mp, 0, 0);
}
camel_object_unref (CAMEL_OBJECT (mp));
- camel_exception_free (ex);
-
- return retval;
}
static CORBA_boolean
@@ -345,6 +337,7 @@ destination_folder_handle_drop (EvolutionShellComponentDndDestinationFolder *fol
gboolean retval = FALSE;
CamelFolder *source;
CamelStream *stream;
+ CamelException ex;
GPtrArray *uids;
CamelURL *uri;
int type, fd;
@@ -358,6 +351,8 @@ destination_folder_handle_drop (EvolutionShellComponentDndDestinationFolder *fol
if (!strcmp (destination_context->dndType, accepted_dnd_types[type]))
break;
+ camel_exception_init (&ex);
+
switch (type) {
case ACCEPTED_DND_TYPE_TEXT_URI_LIST:
source = mail_tool_uri_to_folder (physical_uri, NULL);
@@ -384,11 +379,13 @@ destination_folder_handle_drop (EvolutionShellComponentDndDestinationFolder *fol
}
stream = camel_stream_fs_new_with_fd (fd);
- retval = message_rfc822_dnd (source, stream);
+ message_rfc822_dnd (source, stream, &ex);
camel_object_unref (CAMEL_OBJECT (stream));
camel_object_unref (CAMEL_OBJECT (source));
- if (action == GNOME_Evolution_ShellComponentDnd_ACTION_MOVE)
+ retval = !camel_exception_is_set (&ex);
+
+ if (action == GNOME_Evolution_ShellComponentDnd_ACTION_MOVE && retval)
unlink (url);
g_free (url);
@@ -403,7 +400,7 @@ destination_folder_handle_drop (EvolutionShellComponentDndDestinationFolder *fol
camel_stream_write (stream, data->bytes._buffer, data->bytes._length);
camel_stream_reset (stream);
- retval = message_rfc822_dnd (source, stream);
+ message_rfc822_dnd (source, stream, &ex);
camel_object_unref (CAMEL_OBJECT (stream));
camel_object_unref (CAMEL_OBJECT (source));
break;
@@ -450,6 +447,8 @@ destination_folder_handle_drop (EvolutionShellComponentDndDestinationFolder *fol
break;
}
+ camel_exception_clear (&ex);
+
return retval;
}
diff --git a/mail/folder-browser.c b/mail/folder-browser.c
index e5db32c649..d43a03e04c 100644
--- a/mail/folder-browser.c
+++ b/mail/folder-browser.c
@@ -384,39 +384,47 @@ message_list_drag_data_get (ETree *tree, int row, ETreePath path, int col,
}
static void
-selection_get (GtkWidget *widget, GtkSelectionData *selection_data,
- guint info, guint time_stamp, FolderBrowser *fb)
+message_rfc822_dnd (CamelFolder *dest, CamelStream *stream, CamelException *ex)
{
- if (clipboard_selection != NULL) {
- gtk_selection_data_set (selection_data,
- GDK_SELECTION_TYPE_STRING,
- 8,
- clipboard_selection->data,
- clipboard_selection->len);
- }
-}
-
-static void
-selection_clear_event (GtkWidget *widget, GdkEventSelection *event, FolderBrowser *fb)
-{
- if (clipboard_selection != NULL) {
- g_byte_array_free (clipboard_selection, TRUE);
- clipboard_selection = NULL;
+ CamelMimeParser *mp;
+
+ mp = camel_mime_parser_new ();
+ camel_mime_parser_scan_from (mp, TRUE);
+ camel_mime_parser_init_with_stream (mp, stream);
+
+ while (camel_mime_parser_step (mp, 0, 0) == HSCAN_FROM) {
+ CamelMessageInfo *info;
+ CamelMimeMessage *msg;
+
+ msg = camel_mime_message_new ();
+ if (camel_mime_part_construct_from_parser (CAMEL_MIME_PART (msg), mp) == -1) {
+ camel_object_unref (CAMEL_OBJECT (msg));
+ break;
+ }
+
+ /* append the message to the folder... */
+ info = g_new0 (CamelMessageInfo, 1);
+ camel_folder_append_message (dest, msg, info, ex);
+ camel_object_unref (CAMEL_OBJECT (msg));
+
+ if (camel_exception_is_set (ex))
+ break;
+
+ /* skip over the FROM_END state */
+ camel_mime_parser_step (mp, 0, 0);
}
+
+ camel_object_unref (CAMEL_OBJECT (mp));
}
-static void
-selection_received (GtkWidget *widget, GtkSelectionData *selection_data,
- guint time, FolderBrowser *fb)
+static CamelFolder *
+x_evolution_message_parse (char *in, unsigned int inlen, GPtrArray **uids)
{
- char *url, *name, *in, *inptr, *inend;
- CamelFolder *source;
- GPtrArray *uids;
-
/* format: "url folder_name uid1\0uid2\0uid3\0...\0uidn" */
+ char *inptr, *inend, *name, *url;
+ CamelFolder *folder;
- in = selection_data->data;
- inend = in + selection_data->length;
+ inend = in + inlen;
inptr = strchr (in, ' ');
url = g_strndup (in, inptr - in);
@@ -425,26 +433,142 @@ selection_received (GtkWidget *widget, GtkSelectionData *selection_data,
inptr = strchr (name, ' ');
name = g_strndup (name, inptr - name);
- source = mail_tool_get_folder_from_urlname (url, name, 0, NULL);
+ folder = mail_tool_get_folder_from_urlname (url, name, 0, NULL);
g_free (name);
g_free (url);
- if (!source)
- return;
+ if (!folder)
+ return NULL;
/* split the uids */
inptr++;
- uids = g_ptr_array_new ();
+ *uids = g_ptr_array_new ();
while (inptr < inend) {
char *start = inptr;
while (inptr < inend && *inptr)
inptr++;
- g_ptr_array_add (uids, g_strndup (start, inptr - start));
+ g_ptr_array_add (*uids, g_strndup (start, inptr - start));
inptr++;
}
+ return folder;
+}
+
+static void
+message_list_drag_data_recieved (ETree *tree, int row, ETreePath path, int col,
+ GdkDragContext *context, gint x, gint y,
+ GtkSelectionData *selection_data, guint info,
+ guint time, gpointer user_data)
+{
+ FolderBrowser *fb = FOLDER_BROWSER (user_data);
+ CamelFolder *folder = NULL;
+ GPtrArray *uids = NULL;
+ CamelStream *stream;
+ CamelException ex;
+ char *inend, *url;
+ CamelURL *uri;
+ int fd;
+
+ camel_exception_init (&ex);
+
+ switch (info) {
+ case DND_TARGET_TYPE_TEXT_URI_LIST:
+ url = g_strndup (selection_data->data, selection_data->length);
+ inend = strchr (url, '\n');
+ if (inend)
+ *inend = '\0';
+
+ /* get the path component */
+ g_strstrip (url);
+ uri = camel_url_new (url, NULL);
+ g_free (url);
+ url = uri->path;
+ uri->path = NULL;
+ camel_url_free (uri);
+
+ fd = open (url, O_RDONLY);
+ if (fd == -1) {
+ g_free (url);
+ return;
+ }
+
+ stream = camel_stream_fs_new_with_fd (fd);
+ message_rfc822_dnd (fb->folder, stream, &ex);
+ camel_object_unref (CAMEL_OBJECT (stream));
+
+ if (context->action == GDK_ACTION_MOVE && !camel_exception_is_set (&ex))
+ unlink (url);
+
+ g_free (url);
+ break;
+ case DND_TARGET_TYPE_MESSAGE_RFC822:
+ /* write the message(s) out to a CamelStream so we can use it */
+ stream = camel_stream_mem_new ();
+ camel_stream_write (stream, selection_data->data, selection_data->length);
+ camel_stream_reset (stream);
+
+ message_rfc822_dnd (fb->folder, stream, &ex);
+ camel_object_unref (CAMEL_OBJECT (stream));
+ break;
+ case DND_TARGET_TYPE_X_EVOLUTION_MESSAGE:
+ folder = x_evolution_message_parse (selection_data->data, selection_data->length, &uids);
+ if (folder == NULL)
+ return;
+
+ if (uids == NULL) {
+ camel_object_unref (CAMEL_OBJECT (folder));
+ return;
+ }
+
+ mail_do_transfer_messages (folder, uids, context->action == GDK_ACTION_MOVE, fb->uri);
+
+ camel_object_unref (CAMEL_OBJECT (folder));
+ break;
+ }
+
+ camel_exception_clear (&ex);
+}
+
+static void
+selection_get (GtkWidget *widget, GtkSelectionData *selection_data,
+ guint info, guint time_stamp, FolderBrowser *fb)
+{
+ if (clipboard_selection != NULL) {
+ gtk_selection_data_set (selection_data,
+ GDK_SELECTION_TYPE_STRING,
+ 8,
+ clipboard_selection->data,
+ clipboard_selection->len);
+ }
+}
+
+static void
+selection_clear_event (GtkWidget *widget, GdkEventSelection *event, FolderBrowser *fb)
+{
+ if (clipboard_selection != NULL) {
+ g_byte_array_free (clipboard_selection, TRUE);
+ clipboard_selection = NULL;
+ }
+}
+
+static void
+selection_received (GtkWidget *widget, GtkSelectionData *selection_data,
+ guint time, FolderBrowser *fb)
+{
+ CamelFolder *source = NULL;
+ GPtrArray *uids = NULL;
+
+ source = x_evolution_message_parse (selection_data->data, selection_data->length, &uids);
+ if (source == NULL)
+ return;
+
+ if (uids == NULL) {
+ camel_object_unref (CAMEL_OBJECT (source));
+ return;
+ }
+
mail_do_transfer_messages (source, uids, FALSE, fb->uri);
camel_object_unref (CAMEL_OBJECT (source));
@@ -1564,7 +1688,7 @@ static gboolean
do_message_selected(FolderBrowser *fb)
{
d(printf ("selecting uid %s (delayed)\n", fb->new_uid ? fb->new_uid : "NONE"));
-
+
/* keep polling if we are busy */
if (fb->reconfigure) {
if (fb->new_uid == NULL) {
@@ -1573,9 +1697,9 @@ do_message_selected(FolderBrowser *fb)
}
return TRUE;
}
-
+
fb->loading_id = 0;
-
+
/* if we are loading, then set a pending, but leave the loading, coudl cancel here (?) */
if (fb->loading_uid) {
g_free(fb->pending_uid);
@@ -1588,7 +1712,7 @@ do_message_selected(FolderBrowser *fb)
mail_display_set_message(fb->mail_display, NULL);
}
}
-
+
return FALSE;
}
@@ -1661,6 +1785,12 @@ my_folder_browser_init (GtkObject *object)
gtk_signal_connect (GTK_OBJECT (fb->message_list->tree), "tree_drag_data_get",
GTK_SIGNAL_FUNC (message_list_drag_data_get), fb);
+ e_tree_drag_dest_set (fb->message_list->tree, GTK_DEST_DEFAULT_ALL,
+ drag_types, num_drag_types, GDK_ACTION_MOVE | GDK_ACTION_COPY);
+
+ gtk_signal_connect (GTK_OBJECT (fb->message_list->tree), "tree_drag_data_recieved",
+ GTK_SIGNAL_FUNC (message_list_drag_data_recieved), fb);
+
/* cut, copy & paste */
if (!invisible) {
invisible = gtk_invisible_new ();