From 6952dcb7c0821d705fad562ff5b96613b7c7b248 Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Fri, 10 May 2002 16:44:36 +0000 Subject: Replace copy_messages_to and move_messages_to with a single function that * camel-folder.c (camel_folder_transfer_messages_to): Replace copy_messages_to and move_messages_to with a single function that just takes a "delete_originals" flag. Also, use the vtrash implementation if *either* folder is a vtrash. (transfer_messages_to): Make this use camel_operation_progress (previously move_messages_to did but copy_messages_to didn't), and freeze/thaw the folder(s) if doing multiple messages. * camel-vtrash-folder.c (vtrash_transfer_messages_to): Update for move/copy merge. Move the "move messages into vtrash" code here from mail-ops.c. Now all of the vtrash move/copy special casing is in camel instead of half of it being here and half in mail/. (This should also make it so that "Move to Trash" will work in filter rules.) * camel-vee-folder.c (vee_transfer_messages_to): Make this just return an exception, since it will only be called when trying to move/copy messages from one vfolder to another. (vee_append_message): Add this too so we get a nicer error message than the default "unimplemented" one in camel-folder.c. * camel-digest-folder.c: Replace copy_messages_to and move_messages_to with transfer_messages_to. * camel-disco-folder.c: Likewise * camel-disco-diary.c (camel_disco_diary_log, camel_disco_diary_replay): replace MOVE/COPY with TRANSFER. * providers/imap/camel-imap-folder.c (imap_transfer_offline, imap_transfer_online, imap_transfer_resyncing): Update for changes. (This ends up being a bit more complicated than it was before for now, but later disconnected operation changes should resimplify it.) * camel-filter-driver.c (camel_filter_driver_filter_message, do_copy, do_move): Use transfer_messages_to instead of copy. svn path=/trunk/; revision=16744 --- camel/ChangeLog | 40 +++++++++ camel/camel-digest-folder.c | 22 ++--- camel/camel-disco-diary.c | 18 ++-- camel/camel-disco-diary.h | 3 +- camel/camel-disco-folder.c | 46 ++++------- camel/camel-disco-folder.h | 25 +++--- camel/camel-filter-driver.c | 6 +- camel/camel-folder.c | 137 +++++++++---------------------- camel/camel-folder.h | 22 ++--- camel/camel-vee-folder.c | 36 +++----- camel/camel-vtrash-folder.c | 60 ++++++++------ camel/providers/imap/camel-imap-folder.c | 82 +++++++++--------- 12 files changed, 224 insertions(+), 273 deletions(-) diff --git a/camel/ChangeLog b/camel/ChangeLog index 4b87d56e95..12c2efde89 100644 --- a/camel/ChangeLog +++ b/camel/ChangeLog @@ -1,3 +1,43 @@ +2002-05-10 Dan Winship + + * camel-folder.c (camel_folder_transfer_messages_to): Replace + copy_messages_to and move_messages_to with a single function that + just takes a "delete_originals" flag. Also, use the vtrash + implementation if *either* folder is a vtrash. + (transfer_messages_to): Make this use camel_operation_progress + (previously move_messages_to did but copy_messages_to didn't), and + freeze/thaw the folder(s) if doing multiple messages. + + * camel-vtrash-folder.c (vtrash_transfer_messages_to): Update for + move/copy merge. Move the "move messages into vtrash" code here + from mail-ops.c. Now all of the vtrash move/copy special casing is + in camel instead of half of it being here and half in mail/. (This + should also make it so that "Move to Trash" will work in filter + rules.) + + * camel-vee-folder.c (vee_transfer_messages_to): Make this just + return an exception, since it will only be called when trying to + move/copy messages from one vfolder to another. + (vee_append_message): Add this too so we get a nicer error message + than the default "unimplemented" one in camel-folder.c. + + * camel-digest-folder.c: Replace copy_messages_to and + move_messages_to with transfer_messages_to. + + * camel-disco-folder.c: Likewise + + * camel-disco-diary.c (camel_disco_diary_log, + camel_disco_diary_replay): replace MOVE/COPY with TRANSFER. + + * providers/imap/camel-imap-folder.c (imap_transfer_offline, + imap_transfer_online, imap_transfer_resyncing): Update for + changes. (This ends up being a bit more complicated than it was + before for now, but later disconnected operation changes should + resimplify it.) + + * camel-filter-driver.c (camel_filter_driver_filter_message, + do_copy, do_move): Use transfer_messages_to instead of copy. + 2002-05-09 Jeffrey Stedfast * camel-filter-search.c (shell_exec): New filter function to pipe diff --git a/camel/camel-digest-folder.c b/camel/camel-digest-folder.c index a1f058e42d..def9b3904c 100644 --- a/camel/camel-digest-folder.c +++ b/camel/camel-digest-folder.c @@ -58,10 +58,9 @@ static CamelMimeMessage *digest_get_message (CamelFolder *folder, const gchar *u CamelException *ex); static void digest_append_message (CamelFolder *folder, CamelMimeMessage *message, const CamelMessageInfo *info, CamelException *ex); -static void digest_copy_messages_to (CamelFolder *source, GPtrArray *uids, - CamelFolder *destination, CamelException *ex); -static void digest_move_messages_to (CamelFolder *source, GPtrArray *uids, - CamelFolder *destination, CamelException *ex); +static void digest_transfer_messages_to (CamelFolder *source, GPtrArray *uids, + CamelFolder *destination, gboolean delete_originals, + CamelException *ex); static void @@ -85,8 +84,7 @@ camel_digest_folder_class_init (CamelDigestFolderClass *camel_digest_folder_clas camel_folder_class->get_message = digest_get_message; camel_folder_class->append_message = digest_append_message; - camel_folder_class->copy_messages_to = digest_copy_messages_to; - camel_folder_class->move_messages_to = digest_move_messages_to; + camel_folder_class->transfer_messages_to = digest_transfer_messages_to; } static void @@ -305,15 +303,9 @@ digest_append_message (CamelFolder *folder, CamelMimeMessage *message, } static void -digest_copy_messages_to (CamelFolder *source, GPtrArray *uids, - CamelFolder *destination, CamelException *ex) -{ - /* no-op */ -} - -static void -digest_move_messages_to (CamelFolder *source, GPtrArray *uids, - CamelFolder *destination, CamelException *ex) +digest_transfer_messages_to (CamelFolder *source, GPtrArray *uids, + CamelFolder *destination, gboolean delete_originals, + CamelException *ex) { /* no-op */ } diff --git a/camel/camel-disco-diary.c b/camel/camel-disco-diary.c index a437f5aa09..198ec607c8 100644 --- a/camel/camel-disco-diary.c +++ b/camel/camel-disco-diary.c @@ -149,12 +149,12 @@ camel_disco_diary_log (CamelDiscoDiary *diary, CamelDiscoDiaryAction action, break; } - case CAMEL_DISCO_DIARY_FOLDER_MOVE: - case CAMEL_DISCO_DIARY_FOLDER_COPY: + case CAMEL_DISCO_DIARY_FOLDER_TRANSFER: { CamelFolder *source = va_arg (ap, CamelFolder *); CamelFolder *destination = va_arg (ap, CamelFolder *); GPtrArray *uids = va_arg (ap, GPtrArray *); + gboolean delete_originals = va_arg (ap, gboolean); status = camel_file_util_encode_string (diary->file, source->full_name); if (status == -1) @@ -163,6 +163,9 @@ camel_disco_diary_log (CamelDiscoDiary *diary, CamelDiscoDiaryAction action, if (status == -1) break; status = diary_encode_uids (diary, uids); + if (status == -1) + break; + status = camel_file_util_encode_uint32 (diary->file, delete_originals); break; } @@ -332,27 +335,26 @@ camel_disco_diary_replay (CamelDiscoDiary *diary, CamelException *ex) break; } - case CAMEL_DISCO_DIARY_FOLDER_COPY: - case CAMEL_DISCO_DIARY_FOLDER_MOVE: + case CAMEL_DISCO_DIARY_FOLDER_TRANSFER: { CamelFolder *source, *destination; GPtrArray *uids; + guint32 delete_originals; source = diary_decode_folder (diary); destination = diary_decode_folder (diary); uids = diary_decode_uids (diary); if (!uids) goto lose; + if (camel_file_util_decode_uint32 (diary->file, &delete_originals) == -1) + goto lose; if (!source || !destination) { free_uids (uids); continue; } - if (action == CAMEL_DISCO_DIARY_FOLDER_COPY) - camel_folder_copy_messages_to (source, uids, destination, ex); - else - camel_folder_move_messages_to (source, uids, destination, ex); + camel_folder_transfer_messages_to (source, uids, destination, delete_originals, ex); free_uids (uids); break; } diff --git a/camel/camel-disco-diary.h b/camel/camel-disco-diary.h index e2094adc8a..b177d8ef6f 100644 --- a/camel/camel-disco-diary.h +++ b/camel/camel-disco-diary.h @@ -43,8 +43,7 @@ typedef enum { CAMEL_DISCO_DIARY_FOLDER_EXPUNGE, CAMEL_DISCO_DIARY_FOLDER_APPEND, - CAMEL_DISCO_DIARY_FOLDER_MOVE, - CAMEL_DISCO_DIARY_FOLDER_COPY + CAMEL_DISCO_DIARY_FOLDER_TRANSFER, } CamelDiscoDiaryAction; typedef enum { diff --git a/camel/camel-disco-folder.c b/camel/camel-disco-folder.c index eb3d8633aa..d7c385c60b 100644 --- a/camel/camel-disco-folder.c +++ b/camel/camel-disco-folder.c @@ -40,10 +40,10 @@ static void disco_expunge (CamelFolder *folder, CamelException *ex); static void disco_append_message (CamelFolder *folder, CamelMimeMessage *message, const CamelMessageInfo *info, CamelException *ex); -static void disco_copy_messages_to (CamelFolder *source, GPtrArray *uids, - CamelFolder *destination, CamelException *ex); -static void disco_move_messages_to (CamelFolder *source, GPtrArray *uids, - CamelFolder *destination, CamelException *ex); +static void disco_transfer_messages_to (CamelFolder *source, GPtrArray *uids, + CamelFolder *destination, + gboolean delete_originals, + CamelException *ex); static void disco_cache_message (CamelDiscoFolder *disco_folder, const char *uid, CamelException *ex); @@ -68,8 +68,7 @@ camel_disco_folder_class_init (CamelDiscoFolderClass *camel_disco_folder_class) camel_folder_class->expunge = disco_expunge; camel_folder_class->append_message = disco_append_message; - camel_folder_class->copy_messages_to = disco_copy_messages_to; - camel_folder_class->move_messages_to = disco_move_messages_to; + camel_folder_class->transfer_messages_to = disco_transfer_messages_to; } CamelType @@ -190,43 +189,26 @@ disco_append_message (CamelFolder *folder, CamelMimeMessage *message, } static void -disco_copy_messages_to (CamelFolder *source, GPtrArray *uids, - CamelFolder *destination, CamelException *ex) +disco_transfer_messages_to (CamelFolder *source, GPtrArray *uids, + CamelFolder *destination, + gboolean delete_originals, CamelException *ex) { CamelDiscoStore *disco = CAMEL_DISCO_STORE (source->parent_store); switch (camel_disco_store_status (disco)) { case CAMEL_DISCO_STORE_ONLINE: - CDF_CLASS (source)->copy_online (source, uids, destination, ex); + CDF_CLASS (source)->transfer_online (source, uids, destination, + delete_originals, ex); break; case CAMEL_DISCO_STORE_OFFLINE: - CDF_CLASS (source)->copy_offline (source, uids, destination, ex); + CDF_CLASS (source)->transfer_offline (source, uids, destination, + delete_originals, ex); break; case CAMEL_DISCO_STORE_RESYNCING: - CDF_CLASS (source)->copy_resyncing (source, uids, destination, ex); - break; - } -} - -static void -disco_move_messages_to (CamelFolder *source, GPtrArray *uids, - CamelFolder *destination, CamelException *ex) -{ - CamelDiscoStore *disco = CAMEL_DISCO_STORE (source->parent_store); - - switch (camel_disco_store_status (disco)) { - case CAMEL_DISCO_STORE_ONLINE: - CDF_CLASS (source)->move_online (source, uids, destination, ex); - break; - - case CAMEL_DISCO_STORE_OFFLINE: - CDF_CLASS (source)->move_offline (source, uids, destination, ex); - break; - - case CAMEL_DISCO_STORE_RESYNCING: - CDF_CLASS (source)->move_resyncing (source, uids, destination, ex); + CDF_CLASS (source)->transfer_resyncing (source, uids, destination, + delete_originals, ex); break; } } diff --git a/camel/camel-disco-folder.h b/camel/camel-disco-folder.h index b35c913f5f..9f6e8e2366 100644 --- a/camel/camel-disco-folder.h +++ b/camel/camel-disco-folder.h @@ -70,19 +70,18 @@ typedef struct { const CamelMessageInfo *info, CamelException *ex); - void (*copy_online) (CamelFolder *source, GPtrArray *uids, - CamelFolder *destination, CamelException *ex); - void (*copy_offline) (CamelFolder *source, GPtrArray *uids, - CamelFolder *destination, CamelException *ex); - void (*copy_resyncing) (CamelFolder *source, GPtrArray *uids, - CamelFolder *destination, CamelException *ex); - - void (*move_online) (CamelFolder *source, GPtrArray *uids, - CamelFolder *destination, CamelException *ex); - void (*move_offline) (CamelFolder *source, GPtrArray *uids, - CamelFolder *destination, CamelException *ex); - void (*move_resyncing) (CamelFolder *source, GPtrArray *uids, - CamelFolder *destination, CamelException *ex); + void (*transfer_online) (CamelFolder *source, GPtrArray *uids, + CamelFolder *destination, + gboolean delete_originals, + CamelException *ex); + void (*transfer_offline) (CamelFolder *source, GPtrArray *uids, + CamelFolder *destination, + gboolean delete_originals, + CamelException *ex); + void (*transfer_resyncing) (CamelFolder *source, GPtrArray *uids, + CamelFolder *destination, + gboolean delete_originals, + CamelException *ex); void (*cache_message) (CamelDiscoFolder *disco_folder, const char *uid, CamelException *ex); diff --git a/camel/camel-filter-driver.c b/camel/camel-filter-driver.c index f4e78204ec..a2ba89c8ee 100644 --- a/camel/camel-filter-driver.c +++ b/camel/camel-filter-driver.c @@ -459,7 +459,7 @@ do_copy (struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFilterDriv uids = g_ptr_array_new (); g_ptr_array_add (uids, (char *) p->uid); - camel_folder_copy_messages_to (p->source, uids, outbox, p->ex); + camel_folder_transfer_messages_to (p->source, uids, outbox, FALSE, p->ex); g_ptr_array_free (uids, TRUE); } else { if (p->message == NULL) @@ -510,7 +510,7 @@ do_move (struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFilterDriv uids = g_ptr_array_new (); g_ptr_array_add (uids, (char *) p->uid); - camel_folder_copy_messages_to (p->source, uids, outbox, p->ex); + camel_folder_transfer_messages_to (p->source, uids, outbox, FALSE, p->ex); g_ptr_array_free (uids, TRUE); } else { if (p->message == NULL) @@ -1230,7 +1230,7 @@ camel_filter_driver_filter_message (CamelFilterDriver *driver, CamelMimeMessage uids = g_ptr_array_new (); g_ptr_array_add (uids, (char *) p->uid); - camel_folder_copy_messages_to (p->source, uids, p->defaultfolder, p->ex); + camel_folder_transfer_messages_to (p->source, uids, p->defaultfolder, FALSE, p->ex); g_ptr_array_free (uids, TRUE); } else { if (p->message == NULL) { diff --git a/camel/camel-folder.c b/camel/camel-folder.c index e4edebf257..554c43a7f1 100644 --- a/camel/camel-folder.c +++ b/camel/camel-folder.c @@ -38,6 +38,7 @@ #include "camel-session.h" #include "camel-filter-driver.h" #include "camel-private.h" +#include "camel-vtrash-folder.h" #define d(x) #define w(x) @@ -96,8 +97,7 @@ static GPtrArray *search_by_expression (CamelFolder *folder, const char *e static GPtrArray *search_by_uids (CamelFolder *folder, const char *exp, GPtrArray *uids, CamelException *ex); static void search_free (CamelFolder * folder, GPtrArray *result); -static void copy_messages_to (CamelFolder *source, GPtrArray *uids, CamelFolder *dest, CamelException *ex); -static void move_messages_to (CamelFolder *source, GPtrArray *uids, CamelFolder *dest, CamelException *ex); +static void transfer_messages_to (CamelFolder *source, GPtrArray *uids, CamelFolder *dest, gboolean delete_originals, CamelException *ex); static void delete (CamelFolder *folder); static void folder_rename (CamelFolder *folder, const char *new); @@ -147,8 +147,7 @@ camel_folder_class_init (CamelFolderClass *camel_folder_class) camel_folder_class->get_message_info = get_message_info; camel_folder_class->ref_message_info = ref_message_info; camel_folder_class->free_message_info = free_message_info; - camel_folder_class->copy_messages_to = copy_messages_to; - camel_folder_class->move_messages_to = move_messages_to; + camel_folder_class->transfer_messages_to = transfer_messages_to; camel_folder_class->delete = delete; camel_folder_class->rename = folder_rename; camel_folder_class->freeze = freeze; @@ -1138,7 +1137,7 @@ camel_folder_search_free (CamelFolder *folder, GPtrArray *result) static void -copy_message_to (CamelFolder *source, const char *uid, CamelFolder *dest, CamelException *ex) +transfer_message_to (CamelFolder *source, const char *uid, CamelFolder *dest, gboolean delete_original, CamelException *ex) { CamelMimeMessage *msg; CamelMessageInfo *info = NULL; @@ -1161,84 +1160,10 @@ copy_message_to (CamelFolder *source, const char *uid, CamelFolder *dest, CamelE camel_folder_append_message (dest, msg, info, ex); camel_object_unref (CAMEL_OBJECT (msg)); - if (info) { - if (source->folder_flags & CAMEL_FOLDER_HAS_SUMMARY_CAPABILITY) - CF_CLASS (source)->free_message_info (source, info); - else - camel_message_info_free (info); - } -} - -static void -copy_messages_to (CamelFolder *source, GPtrArray *uids, CamelFolder *dest, CamelException *ex) -{ - int i; - - for (i = 0; i < uids->len && !camel_exception_is_set (ex); i++) - copy_message_to (source, uids->pdata[i], dest, ex); -} - -/** - * camel_folder_copy_messages_to: - * @source: source folder - * @uids: message UIDs in @source - * @dest: destination folder - * @ex: a CamelException - * - * This copies messages from one folder to another. If the @source and - * @dest folders have the same parent_store, this may be more efficient - * than a camel_folder_append_message(). - **/ -void -camel_folder_copy_messages_to (CamelFolder *source, GPtrArray *uids, - CamelFolder *dest, CamelException *ex) -{ - g_return_if_fail (CAMEL_IS_FOLDER (source)); - g_return_if_fail (CAMEL_IS_FOLDER (dest)); - g_return_if_fail (uids != NULL); - - if (source == dest || uids->len == 0) { - /* source and destination folders are the same, or no work to do, do nothing. */ - return; - } - - CAMEL_FOLDER_LOCK(source, lock); - - if (source->parent_store == dest->parent_store) - CF_CLASS (source)->copy_messages_to (source, uids, dest, ex); - else - copy_messages_to (source, uids, dest, ex); - - CAMEL_FOLDER_UNLOCK(source, lock); -} - -static void -move_message_to (CamelFolder *source, const char *uid, CamelFolder *dest, CamelException *ex) -{ - CamelMimeMessage *msg; - CamelMessageInfo *info = NULL; - - /* Default implementation. */ - - msg = CF_CLASS (source)->get_message (source, uid, ex); - if (!msg) - return; - - if (source->folder_flags & CAMEL_FOLDER_HAS_SUMMARY_CAPABILITY) - info = CF_CLASS (source)->get_message_info (source, uid); - else - info = camel_message_info_new_from_header (((CamelMimePart *)msg)->headers); - - /* we don't want to retain the deleted flag */ - if (info && info->flags & CAMEL_MESSAGE_DELETED) - info->flags = info->flags & ~CAMEL_MESSAGE_DELETED; - - camel_folder_append_message (dest, msg, info, ex); - camel_object_unref (CAMEL_OBJECT (msg)); - if (!camel_exception_is_set (ex)) + if (delete_original && !camel_exception_is_set (ex)) camel_folder_set_message_flags (source, uid, CAMEL_MESSAGE_DELETED|CAMEL_MESSAGE_SEEN, ~0); - + if (info) { if (source->folder_flags & CAMEL_FOLDER_HAS_SUMMARY_CAPABILITY) CF_CLASS (source)->free_message_info (source, info); @@ -1248,62 +1173,78 @@ move_message_to (CamelFolder *source, const char *uid, CamelFolder *dest, CamelE } static void -move_messages_to (CamelFolder *source, GPtrArray *uids, CamelFolder *dest, CamelException *ex) +transfer_messages_to (CamelFolder *source, GPtrArray *uids, CamelFolder *dest, gboolean delete_originals, CamelException *ex) { - int i; CamelException local; + int i; camel_exception_init(&local); if (ex == NULL) ex = &local; - camel_operation_start(NULL, _("Moving messages")); + camel_operation_start(NULL, delete_originals ? _("Moving messages") : _("Copying messages")); + if (uids->len > 1) { + camel_folder_freeze(dest); + if (delete_originals) + camel_folder_freeze(source); + } for (i = 0; i < uids->len && !camel_exception_is_set (ex); i++) { - move_message_to (source, uids->pdata[i], dest, ex); + transfer_message_to (source, uids->pdata[i], dest, delete_originals, ex); camel_operation_progress(NULL, i * 100 / uids->len); } + if (uids->len > 1) { + camel_folder_thaw(dest); + if (delete_originals) + camel_folder_thaw(source); + } camel_operation_end(NULL); camel_exception_clear(&local); } /** - * camel_folder_move_messages_to: + * camel_folder_transfer_messages_to: * @source: source folder * @uids: message UIDs in @source * @dest: destination folder + * @delete_originals: whether or not to delete the original messages * @ex: a CamelException * - * This moves a message from one folder to another. If the @source and - * @dest folders have the same parent_store, this may be more efficient - * than a camel_folder_append_message() followed by - * camel_folder_delete_message(). + * This copies or moves messages from one folder to another. If the + * @source and @dest folders have the same parent_store, this may be + * more efficient than using camel_folder_append_message(). **/ void -camel_folder_move_messages_to (CamelFolder *source, GPtrArray *uids, - CamelFolder *dest, CamelException *ex) +camel_folder_transfer_messages_to (CamelFolder *source, GPtrArray *uids, + CamelFolder *dest, gboolean delete_originals, + CamelException *ex) { g_return_if_fail (CAMEL_IS_FOLDER (source)); g_return_if_fail (CAMEL_IS_FOLDER (dest)); g_return_if_fail (uids != NULL); if (source == dest || uids->len == 0) { - /* source and destination folders are the same, or no work to do, nothing to do. */ + /* source and destination folders are the same, or no work to do, do nothing. */ return; } CAMEL_FOLDER_LOCK(source, lock); - if (source->parent_store == dest->parent_store) - CF_CLASS (source)->move_messages_to (source, uids, dest, ex); - else - move_messages_to (source, uids, dest, ex); + if (source->parent_store == dest->parent_store) { + /* If either folder is a vtrash, we need to use the + * vtrash transfer method. + */ + if (CAMEL_IS_VTRASH_FOLDER (dest)) + CF_CLASS (dest)->transfer_messages_to (source, uids, dest, delete_originals, ex); + else + CF_CLASS (source)->transfer_messages_to (source, uids, dest, delete_originals, ex); + } else + transfer_messages_to (source, uids, dest, delete_originals, ex); CAMEL_FOLDER_UNLOCK(source, lock); } - static void delete (CamelFolder *folder) { diff --git a/camel/camel-folder.h b/camel/camel-folder.h index fb987922c6..f2f6e59347 100644 --- a/camel/camel-folder.h +++ b/camel/camel-folder.h @@ -144,15 +144,11 @@ typedef struct { void (*ref_message_info) (CamelFolder *, CamelMessageInfo *); void (*free_message_info) (CamelFolder *, CamelMessageInfo *); - void (*copy_messages_to) (CamelFolder *source, - GPtrArray *uids, - CamelFolder *destination, - CamelException *ex); - - void (*move_messages_to) (CamelFolder *source, - GPtrArray *uids, - CamelFolder *destination, - CamelException *ex); + void (*transfer_messages_to) (CamelFolder *source, + GPtrArray *uids, + CamelFolder *destination, + gboolean delete_originals, + CamelException *ex); void (*delete) (CamelFolder *folder); void (*rename) (CamelFolder *folder, const char *newname); @@ -262,14 +258,10 @@ CamelMessageInfo *camel_folder_get_message_info (CamelFolder *folder, const cha void camel_folder_free_message_info (CamelFolder *folder, CamelMessageInfo *info); void camel_folder_ref_message_info (CamelFolder *folder, CamelMessageInfo *info); -void camel_folder_copy_messages_to (CamelFolder *source, - GPtrArray *uids, - CamelFolder *dest, - CamelException *ex); - -void camel_folder_move_messages_to (CamelFolder *source, +void camel_folder_transfer_messages_to (CamelFolder *source, GPtrArray *uids, CamelFolder *dest, + gboolean delete_originals, CamelException *ex); void camel_folder_delete (CamelFolder *folder); diff --git a/camel/camel-vee-folder.c b/camel/camel-vee-folder.c index 7ccaae72ab..785d70b057 100644 --- a/camel/camel-vee-folder.c +++ b/camel/camel-vee-folder.c @@ -54,7 +54,8 @@ static void vee_sync (CamelFolder *folder, gboolean expunge, CamelException *ex) static void vee_expunge (CamelFolder *folder, CamelException *ex); static CamelMimeMessage *vee_get_message (CamelFolder *folder, const gchar *uid, CamelException *ex); -static void vee_move_messages_to(CamelFolder *source, GPtrArray *uids, CamelFolder *dest, CamelException *ex); +static void vee_append_message(CamelFolder *folder, CamelMimeMessage *message, const CamelMessageInfo *info, CamelException *ex); +static void vee_transfer_messages_to(CamelFolder *source, GPtrArray *uids, CamelFolder *dest, gboolean delete_originals, CamelException *ex); static GPtrArray *vee_search_by_expression(CamelFolder *folder, const char *expression, CamelException *ex); static GPtrArray *vee_search_by_uids(CamelFolder *folder, const char *expression, GPtrArray *uids, CamelException *ex); @@ -123,7 +124,8 @@ camel_vee_folder_class_init (CamelVeeFolderClass *klass) folder_class->expunge = vee_expunge; folder_class->get_message = vee_get_message; - folder_class->move_messages_to = vee_move_messages_to; + folder_class->append_message = vee_append_message; + folder_class->transfer_messages_to = vee_transfer_messages_to; folder_class->search_by_expression = vee_search_by_expression; folder_class->search_by_uids = vee_search_by_uids; @@ -730,29 +732,15 @@ vee_set_message_user_flag(CamelFolder *folder, const char *uid, const char *name } static void -vee_move_messages_to (CamelFolder *folder, GPtrArray *uids, CamelFolder *dest, CamelException *ex) +vee_append_message(CamelFolder *folder, CamelMimeMessage *message, const CamelMessageInfo *info, CamelException *ex) { - CamelVeeMessageInfo *mi; - int i; - - for (i = 0; i < uids->len && !camel_exception_is_set (ex); i++) { - mi = (CamelVeeMessageInfo *) camel_folder_summary_uid (folder->summary, uids->pdata[i]); - if (mi) { - /* noop if it we're moving from the same vfolder (uh, which should't happen but who knows) */ - if (folder != mi->folder) { - GPtrArray *uids; - - uids = g_ptr_array_new (); - g_ptr_array_add (uids, (char *) (camel_message_info_uid (mi) + 8)); - camel_folder_move_messages_to (mi->folder, uids, dest, ex); - g_ptr_array_free (uids, TRUE); - } - camel_folder_summary_info_free (folder->summary, (CamelMessageInfo *)mi); - } else { - camel_exception_setv (ex, CAMEL_EXCEPTION_FOLDER_INVALID_UID, - _("No such message: %s"), uids->pdata[i]); - } - } + camel_exception_set(ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot copy or move messages into a Virtual Folder")); +} + +static void +vee_transfer_messages_to (CamelFolder *folder, GPtrArray *uids, CamelFolder *dest, gboolean delete_originals, CamelException *ex) +{ + camel_exception_set(ex, CAMEL_EXCEPTION_SYSTEM, _("Cannot copy or move messages into a Virtual Folder")); } static void vee_rename(CamelFolder *folder, const char *new) diff --git a/camel/camel-vtrash-folder.c b/camel/camel-vtrash-folder.c index cb390eacda..5b09047abb 100644 --- a/camel/camel-vtrash-folder.c +++ b/camel/camel-vtrash-folder.c @@ -37,8 +37,7 @@ static CamelVeeFolderClass *camel_vtrash_folder_parent; static void vtrash_append_message (CamelFolder *folder, CamelMimeMessage *message, const CamelMessageInfo *info, CamelException *ex); -static void vtrash_copy_messages_to (CamelFolder *folder, GPtrArray *uids, CamelFolder *dest, CamelException *ex); -static void vtrash_move_messages_to (CamelFolder *folder, GPtrArray *uids, CamelFolder *dest, CamelException *ex); +static void vtrash_transfer_messages_to (CamelFolder *folder, GPtrArray *uids, CamelFolder *dest, gboolean delete_originals, CamelException *ex); static void camel_vtrash_folder_class_init (CamelVTrashFolderClass *klass) @@ -49,8 +48,7 @@ camel_vtrash_folder_class_init (CamelVTrashFolderClass *klass) CAMEL_VEE_FOLDER_CLASS (camel_type_get_global_classfuncs (camel_folder_get_type ())); folder_class->append_message = vtrash_append_message; - folder_class->copy_messages_to = vtrash_copy_messages_to; - folder_class->move_messages_to = vtrash_move_messages_to; + folder_class->transfer_messages_to = vtrash_transfer_messages_to; } static void @@ -109,26 +107,21 @@ vtrash_append_message (CamelFolder *folder, CamelMimeMessage *message, const Cam /* no-op */ } -static void -vtrash_copy_messages_to (CamelFolder *source, GPtrArray *uids, CamelFolder *dest, CamelException *ex) -{ - /* don't allow the user to copy to or from the vtrash folder */ - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("You cannot copy messages from this trash folder.")); -} - -struct _move_data { +struct _transfer_data { CamelFolder *folder; CamelFolder *dest; GPtrArray *uids; + gboolean delete; }; static void -move_messages(CamelFolder *folder, struct _move_data *md, CamelException *ex) +transfer_messages(CamelFolder *folder, struct _transfer_data *md, CamelException *ex) { int i; - camel_folder_move_messages_to(md->folder, md->uids, md->dest, ex); + if (!camel_exception_is_set (ex)) + camel_folder_transfer_messages_to(md->folder, md->uids, md->dest, md->delete, ex); + for (i=0;iuids->len;i++) g_free(md->uids->pdata[i]); g_ptr_array_free(md->uids, TRUE); @@ -137,18 +130,42 @@ move_messages(CamelFolder *folder, struct _move_data *md, CamelException *ex) } static void -vtrash_move_messages_to (CamelFolder *source, GPtrArray *uids, CamelFolder *dest, CamelException *ex) +vtrash_transfer_messages_to (CamelFolder *source, GPtrArray *uids, CamelFolder *dest, gboolean delete_originals, CamelException *ex) { CamelVeeMessageInfo *mi; int i; GHashTable *batch = NULL; const char *tuid; - struct _move_data *md; + struct _transfer_data *md; + + /* This is a special case of transfer_messages_to: Either the + * source or the destination is a vtrash folder (but not both + * since a store should never have more than one). + */ + + if (CAMEL_IS_VTRASH_FOLDER (dest)) { + /* Copy to trash is meaningless. */ + if (!delete_originals) + return; + + /* Move to trash is the same as deleting the message */ + for (i = 0; i < uids->len; i++) + camel_folder_delete_message (source, uids->pdata[i]); + return; + } + + g_return_if_fail (CAMEL_IS_VTRASH_FOLDER (source)); + + /* Moving/Copying from the trash to the original folder = undelete. + * Moving/Copying from the trash to a different folder = move/copy. + * + * Need to check this uid by uid, but we batch up the copies. + */ for (i = 0; i < uids->len; i++) { mi = (CamelVeeMessageInfo *)camel_folder_get_message_info (source, uids->pdata[i]); if (mi == NULL) { - g_warning ("Cannot find uid %s in source folder during move_to", (char *) uids->pdata[i]); + g_warning ("Cannot find uid %s in source folder during transfer", (char *) uids->pdata[i]); continue; } @@ -156,10 +173,6 @@ vtrash_move_messages_to (CamelFolder *source, GPtrArray *uids, CamelFolder *dest /* Just undelete the original message */ camel_folder_set_message_flags (source, uids->pdata[i], CAMEL_MESSAGE_DELETED, 0); } else { - /* This means that the user is trying to move the message - from the vTrash to a folder other than the original. - We batch them up as much as we can */ - if (batch == NULL) batch = g_hash_table_new(NULL, NULL); md = g_hash_table_lookup(batch, mi->folder); @@ -175,14 +188,13 @@ vtrash_move_messages_to (CamelFolder *source, GPtrArray *uids, CamelFolder *dest tuid = uids->pdata[i]; if (strlen(tuid)>8) tuid += 8; - printf("moving message uid '%s'\n", tuid); g_ptr_array_add(md->uids, g_strdup(tuid)); } camel_folder_free_message_info (source, (CamelMessageInfo *)mi); } if (batch) { - g_hash_table_foreach(batch, (GHFunc)move_messages, ex); + g_hash_table_foreach(batch, (GHFunc)transfer_messages, ex); g_hash_table_destroy(batch); } } diff --git a/camel/providers/imap/camel-imap-folder.c b/camel/providers/imap/camel-imap-folder.c index b654919e09..9baf2560aa 100644 --- a/camel/providers/imap/camel-imap-folder.c +++ b/camel/providers/imap/camel-imap-folder.c @@ -93,14 +93,18 @@ static void imap_append_offline (CamelFolder *folder, CamelMimeMessage *message, static void imap_append_resyncing (CamelFolder *folder, CamelMimeMessage *message, const CamelMessageInfo *info, CamelException *ex); -static void imap_copy_online (CamelFolder *source, GPtrArray *uids, - CamelFolder *destination, CamelException *ex); -static void imap_copy_offline (CamelFolder *source, GPtrArray *uids, - CamelFolder *destination, CamelException *ex); -static void imap_copy_resyncing (CamelFolder *source, GPtrArray *uids, - CamelFolder *destination, CamelException *ex); -static void imap_move_messages_to (CamelFolder *source, GPtrArray *uids, - CamelFolder *destination, CamelException *ex); +static void imap_transfer_online (CamelFolder *source, GPtrArray *uids, + CamelFolder *destination, + gboolean delete_originals, + CamelException *ex); +static void imap_transfer_offline (CamelFolder *source, GPtrArray *uids, + CamelFolder *destination, + gboolean delete_originals, + CamelException *ex); +static void imap_transfer_resyncing (CamelFolder *source, GPtrArray *uids, + CamelFolder *destination, + gboolean delete_originals, + CamelException *ex); /* searching */ static GPtrArray *imap_search_by_expression (CamelFolder *folder, const char *expression, CamelException *ex); @@ -121,7 +125,6 @@ camel_imap_folder_class_init (CamelImapFolderClass *camel_imap_folder_class) /* virtual method overload */ camel_folder_class->get_message = imap_get_message; - camel_folder_class->move_messages_to = imap_move_messages_to; camel_folder_class->rename = imap_rename; camel_folder_class->search_by_expression = imap_search_by_expression; camel_folder_class->search_by_uids = imap_search_by_uids; @@ -141,9 +144,9 @@ camel_imap_folder_class_init (CamelImapFolderClass *camel_imap_folder_class) camel_disco_folder_class->append_online = imap_append_online; camel_disco_folder_class->append_offline = imap_append_offline; camel_disco_folder_class->append_resyncing = imap_append_resyncing; - camel_disco_folder_class->copy_online = imap_copy_online; - camel_disco_folder_class->copy_offline = imap_copy_offline; - camel_disco_folder_class->copy_resyncing = imap_copy_resyncing; + camel_disco_folder_class->transfer_online = imap_transfer_online; + camel_disco_folder_class->transfer_offline = imap_transfer_offline; + camel_disco_folder_class->transfer_resyncing = imap_transfer_resyncing; camel_disco_folder_class->cache_message = imap_cache_message; } @@ -1123,8 +1126,9 @@ imap_append_resyncing (CamelFolder *folder, CamelMimeMessage *message, static void -imap_copy_offline (CamelFolder *source, GPtrArray *uids, - CamelFolder *destination, CamelException *ex) +imap_transfer_offline (CamelFolder *source, GPtrArray *uids, + CamelFolder *destination, gboolean delete_originals, + CamelException *ex) { CamelImapStore *store = CAMEL_IMAP_STORE (source->parent_store); CamelImapMessageCache *sc = CAMEL_IMAP_FOLDER (source)->cache; @@ -1164,6 +1168,9 @@ imap_copy_offline (CamelFolder *source, GPtrArray *uids, camel_folder_change_info_add_uid (changes, destuid); g_free (destuid); + + if (delete_originals) + camel_folder_delete_message (source, uid); } CAMEL_IMAP_FOLDER_UNLOCK (destination, cache_lock); @@ -1174,8 +1181,8 @@ imap_copy_offline (CamelFolder *source, GPtrArray *uids, camel_folder_change_info_free (changes); camel_disco_diary_log (CAMEL_DISCO_STORE (store)->diary, - CAMEL_DISCO_DIARY_FOLDER_COPY, - source, destination, uids); + CAMEL_DISCO_DIARY_FOLDER_TRANSFER, + source, destination, uids, delete_originals); } static void @@ -1257,11 +1264,12 @@ do_copy (CamelFolder *source, GPtrArray *uids, } static void -imap_copy_online (CamelFolder *source, GPtrArray *uids, - CamelFolder *destination, CamelException *ex) +imap_transfer_online (CamelFolder *source, GPtrArray *uids, + CamelFolder *destination, gboolean delete_originals, + CamelException *ex) { CamelImapStore *store = CAMEL_IMAP_STORE (source->parent_store); - int count; + int count, i; /* Sync message flags if needed. */ imap_sync_online (source, ex); @@ -1279,11 +1287,17 @@ imap_copy_online (CamelFolder *source, GPtrArray *uids, if (store->current_folder != destination || camel_folder_summary_count (destination->summary) == count) camel_folder_refresh_info (destination, ex); + + if (delete_originals) { + for (i = 0; i < uids->len; i++) + camel_folder_delete_message (source, uids->pdata[i]); + } } static void -imap_copy_resyncing (CamelFolder *source, GPtrArray *uids, - CamelFolder *destination, CamelException *ex) +imap_transfer_resyncing (CamelFolder *source, GPtrArray *uids, + CamelFolder *destination, gboolean delete_originals, + CamelException *ex) { CamelDiscoDiary *diary = CAMEL_DISCO_STORE (source->parent_store)->diary; GPtrArray *realuids; @@ -1313,6 +1327,9 @@ imap_copy_resyncing (CamelFolder *source, GPtrArray *uids, break; } g_ptr_array_add (realuids, (char *)uid); + + if (delete_originals) + camel_folder_delete_message (source, uid); } /* If we saw any real UIDs, do a COPY */ @@ -1327,17 +1344,20 @@ imap_copy_resyncing (CamelFolder *source, GPtrArray *uids, while (i < uids->len && !isdigit (*(unsigned char *)(uids->pdata[i])) && !camel_exception_is_set (ex)) { - message = camel_folder_get_message (source, uids->pdata[i], NULL); + uid = uids->pdata[i]; + message = camel_folder_get_message (source, uid, NULL); if (!message) { /* Message must have been expunged */ continue; } - info = camel_folder_get_message_info (source, uids->pdata[i]); + info = camel_folder_get_message_info (source, uid); g_return_if_fail (info != NULL); imap_append_online (destination, message, info, ex); camel_folder_free_message_info (source, info); camel_object_unref (CAMEL_OBJECT (message)); + if (delete_originals) + camel_folder_delete_message (source, uid); i++; } } @@ -1345,22 +1365,6 @@ imap_copy_resyncing (CamelFolder *source, GPtrArray *uids, g_ptr_array_free (realuids, FALSE); } -static void -imap_move_messages_to (CamelFolder *source, GPtrArray *uids, - CamelFolder *destination, CamelException *ex) -{ - int i; - - /* do it this way (as opposed to camel_folder_copy_messages_to) - * to avoid locking issues */ - CF_CLASS (source)->copy_messages_to (source, uids, destination, ex); - if (camel_exception_is_set (ex)) - return; - - for (i = 0; i < uids->len; i++) - camel_folder_delete_message (source, uids->pdata[i]); -} - static GPtrArray * imap_search_by_expression (CamelFolder *folder, const char *expression, CamelException *ex) { -- cgit v1.2.3