diff options
-rw-r--r-- | mail/ChangeLog | 13 | ||||
-rw-r--r-- | mail/component-factory.c | 31 | ||||
-rw-r--r-- | mail/folder-browser.c | 200 |
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 (); |