aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--camel/ChangeLog34
-rw-r--r--camel/Makefile.am2
-rw-r--r--camel/camel-filter-driver.c33
-rw-r--r--camel/camel-folder.c128
-rw-r--r--camel/camel-folder.h32
-rw-r--r--camel/camel-store.c11
-rw-r--r--camel/camel-vee-folder.c33
-rw-r--r--camel/camel-vtrash-folder.c138
-rw-r--r--camel/camel-vtrash-folder.h51
-rw-r--r--camel/providers/imap/camel-imap-folder.c117
10 files changed, 396 insertions, 183 deletions
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 <fejj@ximian.com>
+
+ * 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 <NotZed@Ximian.com>
* 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 <fejj@ximian.com>
+ *
+ * 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 <config.h>
+
+#include "camel-exception.h"
+#include "camel-vtrash-folder.h"
+#include "camel-store.h"
+#include "camel-vee-store.h"
+#include "camel-mime-message.h"
+
+#include <string.h>
+
+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 <fejj@ximian.com>
+ *
+ * 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 <camel/camel-folder.h>
+#include <camel/camel-vee-folder.h>
+
+#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 *