diff options
-rw-r--r-- | camel/ChangeLog | 22 | ||||
-rw-r--r-- | camel/camel-folder.c | 143 | ||||
-rw-r--r-- | camel/camel-vee-folder.c | 46 | ||||
-rw-r--r-- | camel/camel-vee-folder.h | 8 |
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 */ |