From efddd51d3b67fbf48a6c190fa7ddfb0244be5ddf Mon Sep 17 00:00:00 2001 From: Jeffrey Stedfast Date: Tue, 27 Mar 2001 01:41:21 +0000 Subject: Use camel_vtrash_folder_new() to create the vtrash folder now. 2001-03-26 Jeffrey Stedfast * camel-store.c (init_trash): Use camel_vtrash_folder_new() to create the vtrash folder now. * camel-vtrash-folder.[c,h]: New subclass of CamelVeeFolder for our vTrash folders. * camel-folder.c (camel_folder_copy_messages_to): Don't watch for vtrash folders anymore. (camel_folder_move_messages_to): Same. * camel-vee-folder.c (camel_vee_folder_class_init): Update. (vee_move_messages_to): Rewrite to use the new move API. * camel-filter-driver.c (do_copy): Updated to reflect copy_message_to changes. Create a temporary uid array and use that. (do_move): Same. (camel_filter_driver_filter_message): And again, here... * providers/imap/camel-imap-folder.c (imap_copy_messages_to): Update to the new API. (imap_move_messages_to): Same. (get_uid_set): New function to create a `set' string based on an array of UIDs for use with imap_copy_messages_to. * camel-folder.c (camel_folder_copy_messages_to): Replaces camel_folder_copy_message_to (camel_folder_move_message_to): Replaces camel_folder_move_message_to. svn path=/trunk/; revision=8960 --- camel/ChangeLog | 34 +++++++- camel/Makefile.am | 2 + camel/camel-filter-driver.c | 33 ++++++-- camel/camel-folder.c | 128 ++++++++++------------------ camel/camel-folder.h | 32 +++---- camel/camel-store.c | 11 +-- camel/camel-vee-folder.c | 33 +++++--- camel/camel-vtrash-folder.c | 138 +++++++++++++++++++++++++++++++ camel/camel-vtrash-folder.h | 51 ++++++++++++ camel/providers/imap/camel-imap-folder.c | 117 +++++++++++++++----------- 10 files changed, 396 insertions(+), 183 deletions(-) create mode 100644 camel/camel-vtrash-folder.c create mode 100644 camel/camel-vtrash-folder.h diff --git a/camel/ChangeLog b/camel/ChangeLog index 9422e5e746..b4413e885f 100644 --- a/camel/ChangeLog +++ b/camel/ChangeLog @@ -1,3 +1,35 @@ +2001-03-26 Jeffrey Stedfast + + * camel-store.c (init_trash): Use camel_vtrash_folder_new() to + create the vtrash folder now. + + * camel-vtrash-folder.[c,h]: New subclass of CamelVeeFolder for + our vTrash folders. + + * camel-folder.c (camel_folder_copy_messages_to): Don't watch for + vtrash folders anymore. + (camel_folder_move_messages_to): Same. + + * camel-vee-folder.c (camel_vee_folder_class_init): Update. + (vee_move_messages_to): Rewrite to use the new move API. + + * camel-filter-driver.c (do_copy): Updated to reflect + copy_message_to changes. Create a temporary uid array and use + that. + (do_move): Same. + (camel_filter_driver_filter_message): And again, here... + + * providers/imap/camel-imap-folder.c (imap_copy_messages_to): + Update to the new API. + (imap_move_messages_to): Same. + (get_uid_set): New function to create a `set' string based on an + array of UIDs for use with imap_copy_messages_to. + + * camel-folder.c (camel_folder_copy_messages_to): Replaces + camel_folder_copy_message_to + (camel_folder_move_message_to): Replaces + camel_folder_move_message_to. + 2001-03-27 Not Zed * camel-vee-store.c (vee_get_folder): Added folder_created event @@ -10,7 +42,7 @@ (vee_sync): Always rebuild folder on sync, even when not expunge. (folder_changed): If not autoupdating, make sure we remove any removed entries. - (vee_folder_build_folder): + (vee_folder_build_folder): (vee_folder_remove_folder): NOP if we're called on folder_unmatched. (vee_search_by_expression): Only search each folder once. Should diff --git a/camel/Makefile.am b/camel/Makefile.am index 694ab616dd..67f65f33e6 100644 --- a/camel/Makefile.am +++ b/camel/Makefile.am @@ -82,6 +82,7 @@ libcamel_la_SOURCES = \ camel-url.c \ camel-vee-folder.c \ camel-vee-store.c \ + camel-vtrash-folder.c \ camel-charset-map.c \ camel.c \ gstring-util.c \ @@ -152,6 +153,7 @@ libcamelinclude_HEADERS = \ camel-url.h \ camel-vee-folder.h \ camel-vee-store.h \ + camel-vtrash-folder.h \ camel.h \ gstring-util.h \ hash-table-utils.h \ diff --git a/camel/camel-filter-driver.c b/camel/camel-filter-driver.c index 261f727610..3fa703848b 100644 --- a/camel/camel-filter-driver.c +++ b/camel/camel-filter-driver.c @@ -371,9 +371,14 @@ do_copy (struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFilterDriv break; p->copied = TRUE; - if (p->uid && p->source && camel_folder_has_summary_capability (p->source)) - camel_folder_copy_message_to (p->source, p->uid, outbox, p->ex); - else + if (p->uid && p->source && camel_folder_has_summary_capability (p->source)) { + GPtrArray *uids; + + uids = g_ptr_array_new (); + g_ptr_array_add (uids, (char *) p->uid); + camel_folder_copy_messages_to (p->source, uids, outbox, p->ex); + g_ptr_array_free (uids, TRUE); + } else camel_folder_append_message (outbox, p->message, p->info, p->ex); service_url = camel_service_get_url (CAMEL_SERVICE (camel_folder_get_parent_store (outbox))); @@ -408,9 +413,14 @@ do_move (struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFilterDriv p->copied = TRUE; p->deleted = TRUE; /* a 'move' is a copy & delete */ - if (p->uid && p->source && camel_folder_has_summary_capability (p->source)) - camel_folder_copy_message_to (p->source, p->uid, outbox, p->ex); - else + if (p->uid && p->source && camel_folder_has_summary_capability (p->source)) { + GPtrArray *uids; + + uids = g_ptr_array_new (); + g_ptr_array_add (uids, (char *) p->uid); + camel_folder_copy_messages_to (p->source, uids, outbox, p->ex); + g_ptr_array_free (uids, TRUE); + } else camel_folder_append_message (outbox, p->message, p->info, p->ex); service_url = camel_service_get_url (CAMEL_SERVICE (camel_folder_get_parent_store (outbox))); @@ -871,9 +881,14 @@ camel_filter_driver_filter_message (CamelFilterDriver *driver, CamelMimeMessage /* copy it to the default inbox */ filtered = TRUE; camel_filter_driver_log (driver, FILTER_LOG_ACTION, "Copy to default folder"); - if (p->uid && p->source && camel_folder_has_summary_capability (p->source)) - camel_folder_copy_message_to (p->source, p->uid, p->defaultfolder, p->ex); - else + if (p->uid && p->source && camel_folder_has_summary_capability (p->source)) { + GPtrArray *uids; + + 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); + g_ptr_array_free (uids, TRUE); + } else camel_folder_append_message (p->defaultfolder, p->message, p->info, p->ex); } diff --git a/camel/camel-folder.c b/camel/camel-folder.c index b3a86c0f4f..2183edeedc 100644 --- a/camel/camel-folder.c +++ b/camel/camel-folder.c @@ -28,7 +28,6 @@ #include "camel-folder.h" #include "camel-exception.h" #include "camel-store.h" -#include "camel-vee-folder.h" #include "camel-mime-message.h" #include "string-utils.h" #include "e-util/e-memory.h" @@ -95,15 +94,15 @@ static GPtrArray *search_by_expression (CamelFolder *folder, static void search_free (CamelFolder * folder, GPtrArray * result); -static void copy_message_to (CamelFolder *source, - const char *uid, - CamelFolder *dest, - CamelException *ex); +static void copy_messages_to (CamelFolder *source, + GPtrArray *uids, + CamelFolder *dest, + CamelException *ex); -static void move_message_to (CamelFolder *source, - const char *uid, - CamelFolder *dest, - CamelException *ex); +static void move_messages_to (CamelFolder *source, + GPtrArray *uids, + CamelFolder *dest, + CamelException *ex); static void freeze (CamelFolder *folder); static void thaw (CamelFolder *folder); @@ -148,8 +147,8 @@ 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_message_to = copy_message_to; - camel_folder_class->move_message_to = move_message_to; + camel_folder_class->copy_messages_to = copy_messages_to; + camel_folder_class->move_messages_to = move_messages_to; camel_folder_class->freeze = freeze; camel_folder_class->thaw = thaw; @@ -1114,59 +1113,40 @@ copy_message_to (CamelFolder *source, const char *uid, CamelFolder *dest, CamelE } } -/* Note: this gets used by camel_folder_copy_message_to and camel_folder_move_message_to */ -static CamelFolder * -get_the_vtrash (CamelFolder *source, CamelFolder *dest) +static void +copy_messages_to (CamelFolder *source, GPtrArray *uids, CamelFolder *dest, CamelException *ex) { - /* Find the vtrash folder given the source and destination folders. - We don't want to return the 'vtrash'->parent_store->vtrash - because it won't exist */ - if (source->parent_store->vtrash) - return source->parent_store->vtrash; - else if (dest->parent_store->vtrash) - return dest->parent_store->vtrash; + int i; - /* either this store doesn't implement vtrash or src - and dest are both vtrash folders */ - return NULL; + for (i = 0; i < uids->len && !camel_exception_is_set (ex); i++) + copy_message_to (source, uids->pdata[i], dest, ex); } /** - * camel_folder_copy_message_to: + * camel_folder_copy_messages_to: * @source: source folder - * @uid: UID of message in @source + * @uids: message UIDs in @source * @dest: destination folder * @ex: a CamelException * - * This copies a message from one folder to another. If the @source and + * 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_message_to (CamelFolder *source, const char *uid, - CamelFolder *dest, CamelException *ex) +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 (uid != NULL); + g_return_if_fail (uids != NULL); CAMEL_FOLDER_LOCK(source, lock); - if (source->parent_store == dest->parent_store) { - CamelFolder *vtrash; - - vtrash = get_the_vtrash (source, dest); - - if (source == vtrash || dest == vtrash) { - /* don't allow the user to copy to or from the vtrash folder */ - camel_exception_setv (ex, CAMEL_EXCEPTION_SYSTEM, - _("You cannot copy a message to or from " - "this trash folder.")); - } else { - CF_CLASS (source)->copy_message_to (source, uid, dest, ex); - } - } else - copy_message_to (source, uid, dest, ex); + 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); } @@ -1208,10 +1188,19 @@ move_message_to (CamelFolder *source, const char *uid, } } +static void +move_messages_to (CamelFolder *source, GPtrArray *uids, CamelFolder *dest, CamelException *ex) +{ + int i; + + for (i = 0; i < uids->len && !camel_exception_is_set (ex); i++) + move_message_to (source, uids->pdata[i], dest, ex); +} + /** - * camel_folder_move_message_to: + * camel_folder_move_messages_to: * @source: source folder - * @uid: UID of message in @source + * @uids: message UIDs in @source * @dest: destination folder * @ex: a CamelException * @@ -1221,12 +1210,12 @@ move_message_to (CamelFolder *source, const char *uid, * camel_folder_delete_message(). **/ void -camel_folder_move_message_to (CamelFolder *source, const char *uid, +camel_folder_move_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 (uid != NULL); + g_return_if_fail (uids != NULL); if (source == dest) { /* source and destination folders are the same, nothing to do. */ @@ -1235,43 +1224,10 @@ camel_folder_move_message_to (CamelFolder *source, const char *uid, CAMEL_FOLDER_LOCK(source, lock); - if (source->parent_store == dest->parent_store) { - CamelFolder *vtrash; - - vtrash = get_the_vtrash (source, dest); - - if (source == vtrash || dest == vtrash) { - /* Note: We know that it isn't possible that both the source - AND dest folders are the vtrash because otherwise we would - have kicked out above. */ - CamelFolder *real; - - real = camel_vee_folder_get_message_folder (CAMEL_VEE_FOLDER (vtrash), uid); - - if (source == vtrash && dest == real) { - /* Just undelete the original message */ - CF_CLASS (dest)->set_message_flags (dest, uid, CAMEL_MESSAGE_DELETED, 0); - } else if (dest == vtrash) { - /* Just delete the original message */ - CF_CLASS (source)->set_message_flags (source, uid, CAMEL_MESSAGE_DELETED, - CAMEL_MESSAGE_DELETED); - } else if (real) { - /* This means that the user is trying to move the message - from the vTrash to a folder other than the original. */ - CF_CLASS (real)->move_message_to (real, uid, dest, ex); - } else { - g_assert_not_reached (); - } - - if (real) - camel_object_unref (CAMEL_OBJECT (real)); - } else { - /* don't have to worry about vtrash folders, yay */ - CF_CLASS (source)->move_message_to (source, uid, dest, ex); - } - } else { - move_message_to (source, uid, dest, ex); - } + 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); CAMEL_FOLDER_UNLOCK(source, lock); } diff --git a/camel/camel-folder.h b/camel/camel-folder.h index ab3483d1da..a4b50c2b2e 100644 --- a/camel/camel-folder.h +++ b/camel/camel-folder.h @@ -140,15 +140,15 @@ typedef struct { void (*ref_message_info) (CamelFolder *, CamelMessageInfo *); void (*free_message_info) (CamelFolder *, CamelMessageInfo *); - void (*copy_message_to) (CamelFolder *source, - const char *uid, - CamelFolder *destination, - CamelException *ex); + void (*copy_messages_to) (CamelFolder *source, + GPtrArray *uids, + CamelFolder *destination, + CamelException *ex); - void (*move_message_to) (CamelFolder *source, - const char *uid, - CamelFolder *destination, - CamelException *ex); + void (*move_messages_to) (CamelFolder *source, + GPtrArray *uids, + CamelFolder *destination, + CamelException *ex); void (*freeze) (CamelFolder *folder); void (*thaw) (CamelFolder *folder); @@ -255,15 +255,15 @@ 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_message_to (CamelFolder *source, - const char *uid, - CamelFolder *dest, - CamelException *ex); +void camel_folder_copy_messages_to (CamelFolder *source, + GPtrArray *uids, + CamelFolder *dest, + CamelException *ex); -void camel_folder_move_message_to (CamelFolder *source, - const char *uid, - CamelFolder *dest, - CamelException *ex); +void camel_folder_move_messages_to (CamelFolder *source, + GPtrArray *uids, + CamelFolder *dest, + CamelException *ex); /* stop/restart getting events */ void camel_folder_freeze (CamelFolder *folder); diff --git a/camel/camel-store.c b/camel/camel-store.c index 0d39c6ee29..5cae2b9d9e 100644 --- a/camel/camel-store.c +++ b/camel/camel-store.c @@ -31,8 +31,7 @@ #include "camel-store.h" #include "camel-folder.h" -#include "camel-vee-store.h" -#include "camel-vee-folder.h" +#include "camel-vtrash-folder.h" #include "camel-exception.h" #include "camel-private.h" @@ -377,13 +376,7 @@ trash_finalize (CamelObject *trash, gpointer event_data, gpointer user_data) static void init_trash (CamelStore *store) { - char *name; - - name = g_strdup_printf ("%s?(match-all (system-flag \"Deleted\"))", _("Trash")); - - store->vtrash = camel_vee_folder_new (store, name, CAMEL_STORE_FOLDER_CREATE|CAMEL_STORE_VEE_FOLDER_AUTO|CAMEL_STORE_FOLDER_PRIVATE); - - g_free (name); + store->vtrash = camel_vtrash_folder_new (store, _("Trash")); if (store->vtrash) { /* attach to the finalise event of the vtrash */ diff --git a/camel/camel-vee-folder.c b/camel/camel-vee-folder.c index cfcf3175c7..1a54f8e657 100644 --- a/camel/camel-vee-folder.c +++ b/camel/camel-vee-folder.c @@ -56,7 +56,7 @@ 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_message_to(CamelFolder *source, const char *uid, CamelFolder *dest, CamelException *ex); +static void vee_move_messages_to(CamelFolder *source, GPtrArray *uids, CamelFolder *dest, CamelException *ex); static GPtrArray *vee_search_by_expression(CamelFolder *folder, const char *expression, CamelException *ex); @@ -119,7 +119,7 @@ camel_vee_folder_class_init (CamelVeeFolderClass *klass) folder_class->expunge = vee_expunge; folder_class->get_message = vee_get_message; - folder_class->move_message_to = vee_move_message_to; + folder_class->move_messages_to = vee_move_messages_to; folder_class->search_by_expression = vee_search_by_expression; @@ -471,19 +471,28 @@ vee_set_message_user_flag(CamelFolder *folder, const char *uid, const char *name } static void -vee_move_message_to(CamelFolder *folder, const char *uid, CamelFolder *dest, CamelException *ex) +vee_move_messages_to (CamelFolder *folder, GPtrArray *uids, CamelFolder *dest, CamelException *ex) { CamelVeeMessageInfo *mi; - - mi = (CamelVeeMessageInfo *)camel_folder_summary_uid(folder->summary, uid); - if (mi) { - /* noop if it we're moving from the same vfolder (uh, which should't happen but who knows) */ - if (folder != mi->folder) { - camel_folder_move_message_to(mi->folder, camel_message_info_uid(mi) + 8, dest, ex); + 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_folder_summary_info_free(folder->summary, (CamelMessageInfo *)mi); - } else { - camel_exception_setv(ex, CAMEL_EXCEPTION_FOLDER_INVALID_UID, _("No such message: %s"), uid); } } diff --git a/camel/camel-vtrash-folder.c b/camel/camel-vtrash-folder.c new file mode 100644 index 0000000000..acaa9c5b34 --- /dev/null +++ b/camel/camel-vtrash-folder.c @@ -0,0 +1,138 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Authors: Jeffrey Stedfast + * + * Copyright 2001 Ximian, Inc. (www.ximian.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA. + * + */ + +#include + +#include "camel-exception.h" +#include "camel-vtrash-folder.h" +#include "camel-store.h" +#include "camel-vee-store.h" +#include "camel-mime-message.h" + +#include + +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 +camel_vtrash_folder_class_init (CamelVTrashFolderClass *klass) +{ + CamelFolderClass *folder_class = (CamelFolderClass *) klass; + + camel_vtrash_folder_parent = + 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; +} + +CamelType +camel_vtrash_folder_get_type (void) +{ + static CamelType type = CAMEL_INVALID_TYPE; + + if (type == CAMEL_INVALID_TYPE) { + type = camel_type_register (camel_vee_folder_get_type (), + "CamelVTrashFolder", + sizeof (CamelVTrashFolder), + sizeof (CamelVTrashFolderClass), + (CamelObjectClassInitFunc) camel_vtrash_folder_class_init, + NULL, + NULL, + NULL); + } + + return type; +} + +/** + * camel_vee_folder_new: + * @parent_store: the parent CamelVeeStore + * @name: the vfolder name + * @ex: a CamelException + * + * Create a new CamelVeeFolder object. + * + * Return value: A new CamelVeeFolder widget. + **/ +CamelFolder * +camel_vtrash_folder_new (CamelStore *parent_store, const char *name) +{ + CamelFolder *vtrash; + char *vtrash_name; + guint32 flags; + + vtrash = (CamelFolder *)camel_object_new (camel_vtrash_folder_get_type ()); + vtrash_name = g_strdup_printf ("%s?(match-all (system-flag \"Deleted\"))", name); + flags = CAMEL_STORE_FOLDER_PRIVATE | CAMEL_STORE_FOLDER_CREATE | CAMEL_STORE_VEE_FOLDER_AUTO; + + camel_vee_folder_construct (CAMEL_VEE_FOLDER (vtrash), parent_store, vtrash_name, flags); + + return vtrash; +} + +static void +vtrash_append_message (CamelFolder *folder, CamelMimeMessage *message, const CamelMessageInfo *info, CamelException *ex) +{ + /* 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.")); +} + +static void +vtrash_move_messages_to (CamelFolder *source, GPtrArray *uids, CamelFolder *dest, CamelException *ex) +{ + CamelFolder *original; + int i; + + for (i = 0; i < uids->len; i++) { + original = camel_vee_folder_get_message_folder (CAMEL_VEE_FOLDER (source), uids->pdata[i]); + + if (dest == original) { + /* Just undelete the original message */ + CAMEL_FOLDER_CLASS (dest)->set_message_flags (dest, uids->pdata[i], CAMEL_MESSAGE_DELETED, 0); + } else if (original) { + /* This means that the user is trying to move the message + from the vTrash to a folder other than the original. */ + GPtrArray *tuids; + + tuids = g_ptr_array_new (); + g_ptr_array_add (tuids, uids->pdata[i]); + CAMEL_FOLDER_CLASS (original)->move_messages_to (original, tuids, dest, ex); + g_ptr_array_free (tuids, TRUE); + } + + if (original) + camel_object_unref (CAMEL_OBJECT (original)); + } +} diff --git a/camel/camel-vtrash-folder.h b/camel/camel-vtrash-folder.h new file mode 100644 index 0000000000..7f5dd1b79e --- /dev/null +++ b/camel/camel-vtrash-folder.h @@ -0,0 +1,51 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Authors: Jeffrey Stedfast + * + * Copyright 2001 Ximian, Inc. (www.ximian.com) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA. + * + */ + + +#ifndef _CAMEL_VTRASH_FOLDER_H +#define _CAMEL_VTRASH_FOLDER_H + +#include +#include + +#define CAMEL_VTRASH_FOLDER(obj) CAMEL_CHECK_CAST (obj, camel_vtrash_folder_get_type (), CamelVTrashFolder) +#define CAMEL_VTRASH_FOLDER_CLASS(klass) CAMEL_CHECK_CLASS_CAST (klass, camel_vtrash_folder_get_type (), CamelVTrashFolderClass) +#define CAMEL_IS_VTRASH_FOLDER(obj) CAMEL_CHECK_TYPE (obj, camel_vtrash_folder_get_type ()) + +typedef struct _CamelVTrashFolder CamelVTrashFolder; +typedef struct _CamelVTrashFolderClass CamelVTrashFolderClass; + +struct _CamelVTrashFolder { + CamelVeeFolder parent; + +}; + +struct _CamelVTrashFolderClass { + CamelVeeFolderClass parent_class; + +}; + +CamelType camel_vtrash_folder_get_type (void); + +CamelFolder *camel_vtrash_folder_new (CamelStore *parent_store, const char *name); + +#endif /* ! _CAMEL_VTRASH_FOLDER_H */ diff --git a/camel/providers/imap/camel-imap-folder.c b/camel/providers/imap/camel-imap-folder.c index d458b1cfb5..2b9bfb7b78 100644 --- a/camel/providers/imap/camel-imap-folder.c +++ b/camel/providers/imap/camel-imap-folder.c @@ -79,10 +79,10 @@ static CamelMimeMessage *imap_get_message (CamelFolder *folder, const gchar *uid CamelException *ex); static void imap_append_message (CamelFolder *folder, CamelMimeMessage *message, const CamelMessageInfo *info, CamelException *ex); -static void imap_copy_message_to (CamelFolder *source, const char *uid, - CamelFolder *destination, CamelException *ex); -static void imap_move_message_to (CamelFolder *source, const char *uid, - CamelFolder *destination, CamelException *ex); +static void imap_copy_messages_to (CamelFolder *source, GPtrArray *uids, + CamelFolder *destination, CamelException *ex); +static void imap_move_messages_to (CamelFolder *source, GPtrArray *uids, + CamelFolder *destination, CamelException *ex); /* searching */ static GPtrArray *imap_search_by_expression (CamelFolder *folder, const char *expression, CamelException *ex); @@ -107,8 +107,8 @@ camel_imap_folder_class_init (CamelImapFolderClass *camel_imap_folder_class) camel_folder_class->get_message = imap_get_message; camel_folder_class->append_message = imap_append_message; - camel_folder_class->copy_message_to = imap_copy_message_to; - camel_folder_class->move_message_to = imap_move_message_to; + camel_folder_class->copy_messages_to = imap_copy_messages_to; + camel_folder_class->move_messages_to = imap_move_messages_to; camel_folder_class->search_by_expression = imap_search_by_expression; camel_folder_class->search_free = imap_search_free; @@ -685,72 +685,89 @@ imap_append_message (CamelFolder *folder, CamelMimeMessage *message, camel_imap_response_free (response); } +static char * +get_uid_set (GPtrArray *uids) +{ + /* Note: the only thing that might be good to do here is to + not use atoi() and use strtoul() or something */ + int i, last_uid, this_uid; + gboolean range = FALSE; + GString *gset; + char *set; + + gset = g_string_new (uids->pdata[0]); + last_uid = atoi (uids->pdata[0]); + for (i = 1; i < uids->len; i++) { + this_uid = atoi (uids->pdata[i]); + if (this_uid != last_uid + 1) { + if (range) { + g_string_sprintfa (gset, ":%d", last_uid); + range = FALSE; + } + + g_string_sprintfa (gset, ",%d", this_uid); + } else { + range = TRUE; + } + + last_uid = this_uid; + } + + if (range) + g_string_sprintfa (gset, ":%d", this_uid); + + set = gset->str; + g_string_free (gset, FALSE); + + return set; +} + static void -imap_copy_message_to (CamelFolder *source, const char *uid, - CamelFolder *destination, CamelException *ex) +imap_copy_messages_to (CamelFolder *source, GPtrArray *uids, + CamelFolder *destination, CamelException *ex) { CamelImapStore *store = CAMEL_IMAP_STORE (source->parent_store); CamelImapResponse *response; - CamelMessageInfo *mi; - + char *set; + if (!camel_imap_store_check_online (store, ex)) return; - - mi = camel_folder_summary_uid (source->summary, uid); - g_return_if_fail (mi != NULL); - + /* Sync message flags if needed. */ - if (mi->flags & CAMEL_MESSAGE_FOLDER_FLAGGED) { - char *flaglist; - - flaglist = imap_create_flag_list (mi->flags); - CAMEL_IMAP_STORE_LOCK (store, command_lock); - response = camel_imap_command (store, source, ex, - "UID STORE %s FLAGS.SILENT %s", - camel_message_info_uid (mi), - flaglist); - CAMEL_IMAP_STORE_UNLOCK (store, command_lock); - g_free (flaglist); - if (camel_exception_is_set (ex)) { - camel_folder_summary_info_free (source->summary, mi); - return; - } - camel_imap_response_free (response); - - mi->flags &= ~CAMEL_MESSAGE_FOLDER_FLAGGED; - ((CamelImapMessageInfo *)mi)->server_flags = - mi->flags & CAMEL_IMAP_SERVER_FLAGS; - } - camel_folder_summary_info_free (source->summary, mi); - + imap_sync (source, FALSE, ex); if (camel_exception_is_set (ex)) return; - - /* Now copy it */ + + /* Now copy the messages */ CAMEL_IMAP_STORE_LOCK(store, command_lock); + set = get_uid_set (uids); response = camel_imap_command (store, source, ex, "UID COPY %s %S", - uid, destination->full_name); + set, destination->full_name); + + camel_imap_response_free (response); + g_free (set); CAMEL_IMAP_STORE_UNLOCK(store, command_lock); - + if (camel_exception_is_set (ex)) return; - - camel_imap_response_free (response); - + /* Force the destination folder to notice its new messages. */ response = camel_imap_command (store, destination, NULL, "NOOP"); camel_imap_response_free (response); - } +} static void -imap_move_message_to (CamelFolder *source, const char *uid, - CamelFolder *destination, CamelException *ex) +imap_move_messages_to (CamelFolder *source, GPtrArray *uids, + CamelFolder *destination, CamelException *ex) { - imap_copy_message_to (source, uid, destination, ex); + int i; + + imap_copy_messages_to (source, uids, destination, ex); if (camel_exception_is_set (ex)) return; - - camel_folder_delete_message (source, uid); + + for (i = 0; i < uids->len; i++) + camel_folder_delete_message (source, uids->pdata[i]); } static GPtrArray * -- cgit