aboutsummaryrefslogtreecommitdiffstats
path: root/camel
diff options
context:
space:
mode:
authorJeffrey Stedfast <fejj@ximian.com>2001-03-14 02:59:32 +0800
committerJeffrey Stedfast <fejj@src.gnome.org>2001-03-14 02:59:32 +0800
commit56737afcb166d3b928f9a89d9ac9d76c079a575d (patch)
tree739b71e488feec5d3bbdc5c475222b2c0b7b3761 /camel
parentb4269e1f42c26ad7e02759d46e61542d1119adcc (diff)
downloadgsoc2013-evolution-56737afcb166d3b928f9a89d9ac9d76c079a575d.tar.gz
gsoc2013-evolution-56737afcb166d3b928f9a89d9ac9d76c079a575d.tar.zst
gsoc2013-evolution-56737afcb166d3b928f9a89d9ac9d76c079a575d.zip
Don't allow the user to copy a message to or from the vtrash folder. Set
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. svn path=/trunk/; revision=8677
Diffstat (limited to 'camel')
-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 */