aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--camel/ChangeLog22
-rw-r--r--camel/camel-folder.c143
-rw-r--r--camel/camel-vee-folder.c46
-rw-r--r--camel/camel-vee-folder.h8
4 files changed, 185 insertions, 34 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog
index 612fe4300b..c0b391e099 100644
--- a/camel/ChangeLog
+++ b/camel/ChangeLog
@@ -1,3 +1,25 @@
+2001-03-13 Jeffrey Stedfast <fejj@ximian.com>
+
+ * camel-folder.c (camel_folder_copy_message_to): Don't allow the
+ user to copy a message to or from the vtrash folder. Set an
+ exception if they try.
+ (camel_folder_move_message_to): This one is a bit more
+ complicated: 1) If the user tried to move a message from the
+ vtrash into the original folder, just undelete the message. 2) If
+ the user tries to move the message to the vtrash folder, then just
+ mark the message as deleted. 3) If the user tries to move the
+ message from the vTrash to a folder other than the original, use
+ the original folder as the source. As another optimization, I've
+ made it so that if the user tries to move a message to the same
+ folder, just no-op.
+ (move_message_to): Unset the deleted flag before moving (assuming
+ it's there).
+ (copy_message_to): Same.
+
+ * camel-vee-folder.c (camel_vee_folder_get_message_folder): New
+ convenience function to get the folder from which the message uid
+ is derived from.
+
2001-03-13 Dan Winship <danw@ximian.com>
* providers/imap/camel-imap-store.c (imap_connect): When trying
diff --git a/camel/camel-folder.c b/camel/camel-folder.c
index faff5f7556..b3d50e893d 100644
--- a/camel/camel-folder.c
+++ b/camel/camel-folder.c
@@ -28,12 +28,15 @@
#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"
#include "camel-private.h"
+#define d(x) x
+
static CamelObjectClass *parent_class = NULL;
/* Returns the class for a CamelFolder */
@@ -1062,23 +1065,46 @@ copy_message_to (CamelFolder *source, const char *uid, CamelFolder *dest, CamelE
/* Default implementation. */
/* we alredy have the lock, dont deadlock */
- msg = CF_CLASS(source)->get_message(source, uid, ex);
+ msg = CF_CLASS (source)->get_message (source, uid, ex);
if (!msg)
return;
+
if (source->has_summary_capability)
- info = CF_CLASS(source)->get_message_info (source, uid);
+ info = CF_CLASS (source)->get_message_info (source, uid);
else
- info = camel_message_info_new_from_header(((CamelMimePart *)msg)->headers);
+ 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 (info) {
if (source->has_summary_capability)
- CF_CLASS(source)->free_message_info(source, info);
+ CF_CLASS (source)->free_message_info (source, info);
else
- camel_message_info_free(info);
+ camel_message_info_free (info);
}
}
+/* 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)
+{
+ /* 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;
+
+ /* either this store doesn't implement vtrash or src
+ and dest are both vtrash folders */
+ return NULL;
+}
+
/**
* camel_folder_copy_message_to:
* @source: source folder
@@ -1089,8 +1115,6 @@ copy_message_to (CamelFolder *source, const char *uid, CamelFolder *dest, CamelE
* This copies 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().
- *
- * This function is still depcreated, it is not the same as move_message_to.
**/
void
camel_folder_copy_message_to (CamelFolder *source, const char *uid,
@@ -1099,14 +1123,25 @@ camel_folder_copy_message_to (CamelFolder *source, const char *uid,
g_return_if_fail (CAMEL_IS_FOLDER (source));
g_return_if_fail (CAMEL_IS_FOLDER (dest));
g_return_if_fail (uid != NULL);
-
+
CAMEL_FOLDER_LOCK(source, lock);
-
- if (source->parent_store == dest->parent_store)
- CF_CLASS (source)->copy_message_to (source, uid, dest, ex);
- else
+
+ 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);
-
+
CAMEL_FOLDER_UNLOCK(source, lock);
}
@@ -1117,25 +1152,33 @@ move_message_to (CamelFolder *source, const char *uid,
{
CamelMimeMessage *msg;
CamelMessageInfo *info = NULL;
-
+
/* Default implementation. */
- msg = CF_CLASS(source)->get_message (source, uid, ex);
+ msg = CF_CLASS (source)->get_message (source, uid, ex);
if (!msg)
return;
+
if (source->has_summary_capability)
- info = CF_CLASS(source)->get_message_info (source, uid);
+ info = CF_CLASS (source)->get_message_info (source, uid);
else
- info = camel_message_info_new_from_header(((CamelMimePart *)msg)->headers);
+ 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))
- CF_CLASS(source)->set_message_flags(source, uid, CAMEL_MESSAGE_DELETED, CAMEL_MESSAGE_DELETED);
+ if (!camel_exception_is_set (ex))
+ CF_CLASS (source)->set_message_flags (source, uid, CAMEL_MESSAGE_DELETED,
+ CAMEL_MESSAGE_DELETED);
+
if (info) {
if (source->has_summary_capability)
- CF_CLASS(source)->free_message_info(source, info);
+ CF_CLASS (source)->free_message_info (source, info);
else
- camel_message_info_free(info);
+ camel_message_info_free (info);
}
}
@@ -1158,14 +1201,52 @@ camel_folder_move_message_to (CamelFolder *source, const char *uid,
g_return_if_fail (CAMEL_IS_FOLDER (source));
g_return_if_fail (CAMEL_IS_FOLDER (dest));
g_return_if_fail (uid != NULL);
-
+
+ if (source == dest) {
+ /* source and destination folders are the same, nothing to do. */
+ return;
+ }
+
CAMEL_FOLDER_LOCK(source, lock);
-
- if (source->parent_store == dest->parent_store)
- CF_CLASS (source)->move_message_to (source, uid, dest, ex);
- else
+
+ 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);
-
+ }
+
CAMEL_FOLDER_UNLOCK(source, lock);
}
@@ -1176,7 +1257,7 @@ freeze (CamelFolder *folder)
folder->priv->frozen++;
- printf("freeze(%p) = %d\n", folder, folder->priv->frozen);
+ d(printf ("freeze(%p) = %d\n", folder, folder->priv->frozen));
CAMEL_FOLDER_UNLOCK(folder, change_lock);
}
@@ -1207,7 +1288,7 @@ thaw (CamelFolder * folder)
folder->priv->frozen--;
- printf("thaw(%p) = %d\n", folder, folder->priv->frozen);
+ d(printf ("thaw(%p) = %d\n", folder, folder->priv->frozen));
if (folder->priv->frozen == 0) {
/* If we have more or less messages, do a folder changed, otherwise just
@@ -1252,7 +1333,7 @@ folder_changed (CamelObject *obj, gpointer event_data)
CamelFolderChangeInfo *changed = event_data;
gboolean ret = TRUE;
- printf("folder_changed(%p, %p), frozen=%d\n", obj, event_data, folder->priv->frozen);
+ d(printf ("folder_changed(%p, %p), frozen=%d\n", obj, event_data, folder->priv->frozen));
if (folder->priv->frozen) {
CAMEL_FOLDER_LOCK(folder, change_lock);
@@ -1276,7 +1357,7 @@ message_changed (CamelObject *obj, /*const char *uid*/gpointer event_data)
CamelFolder *folder = CAMEL_FOLDER (obj);
gboolean ret = TRUE;
- printf("message_changed(%p, %p), frozen=%d\n", folder, event_data, folder->priv->frozen);
+ d(printf ("message_changed(%p, %p), frozen=%d\n", folder, event_data, folder->priv->frozen));
if (folder->priv->frozen) {
CAMEL_FOLDER_LOCK(folder, change_lock);
diff --git a/camel/camel-vee-folder.c b/camel/camel-vee-folder.c
index 5b1b704c22..cb6ef4bf91 100644
--- a/camel/camel-vee-folder.c
+++ b/camel/camel-vee-folder.c
@@ -703,6 +703,14 @@ message_changed(CamelFolder *f, const char *uid, CamelVeeFolder *vf)
g_free(vuid);
}
+
+/**
+ * camel_vee_folder_remove_folder:
+ * @vf: Virtual Folder object
+ * @sub: source CamelFolder to remove from @vf
+ *
+ * Removed the source folder, @sub, from the virtual folder, @vf.
+ **/
void
camel_vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *sub)
{
@@ -737,6 +745,14 @@ camel_vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *sub)
CAMEL_VEE_FOLDER_UNLOCK(vf, summary_lock);
}
+
+/**
+ * camel_vee_folder_add_folder:
+ * @vf: Virtual Folder object
+ * @sub: source CamelFolder to add to @vf
+ *
+ * Adds @sub as a source folder to @vf.
+ **/
void
camel_vee_folder_add_folder(CamelVeeFolder *vf, CamelFolder *sub)
{
@@ -774,6 +790,36 @@ camel_vee_folder_add_folder(CamelVeeFolder *vf, CamelFolder *sub)
CAMEL_VEE_FOLDER_UNLOCK(vf, summary_lock);
}
+
+/**
+ * camel_vee_folder_get_message_folder:
+ * @vf: Virtual Folder object
+ * @uid: message uid
+ *
+ * Returns the parent folder of @uid if it exists, otherwise NULL.
+ * Note: You must unref the folder when finished with it.
+ **/
+CamelFolder *
+camel_vee_folder_get_message_folder (CamelVeeFolder *vf, const gchar *uid)
+{
+ CamelVeeMessageInfo *mi;
+ CamelFolder *folder;
+
+ CAMEL_VEE_FOLDER_LOCK(vf, summary_lock);
+
+ mi = (CamelVeeMessageInfo *)camel_folder_summary_uid (CAMEL_FOLDER (vf)->summary, uid);
+ if (mi) {
+ camel_object_ref (CAMEL_OBJECT (mi->folder));
+ folder = mi->folder;
+ } else {
+ folder = NULL;
+ }
+
+ CAMEL_VEE_FOLDER_UNLOCK(vf, summary_lock);
+
+ return folder;
+}
+
static void
vee_sync (CamelFolder *folder, gboolean expunge, CamelException *ex)
{
diff --git a/camel/camel-vee-folder.h b/camel/camel-vee-folder.h
index 3447fd6ba4..0cb16c98dd 100644
--- a/camel/camel-vee-folder.h
+++ b/camel/camel-vee-folder.h
@@ -51,9 +51,11 @@ struct _CamelVeeFolderClass {
};
guint camel_vee_folder_get_type (void);
-CamelFolder *camel_vee_folder_new (CamelStore *parent_store, const char *name, guint32 flags, CamelException *ex);
+CamelFolder *camel_vee_folder_new (CamelStore *parent_store, const char *name,
+ guint32 flags, CamelException *ex);
-void camel_vee_folder_add_folder(CamelVeeFolder *vf, CamelFolder *sub);
-void camel_vee_folder_remove_folder(CamelVeeFolder *vf, CamelFolder *sub);
+void camel_vee_folder_add_folder (CamelVeeFolder *vf, CamelFolder *sub);
+void camel_vee_folder_remove_folder (CamelVeeFolder *vf, CamelFolder *sub);
+CamelFolder *camel_vee_folder_get_message_folder (CamelVeeFolder *vf, const char *uid);
#endif /* ! _CAMEL_VEE_FOLDER_H */