[evolution-kolab] KolabMailImapClient: refuse to delete non-empty folder



commit ac0939b42d8ddc21bdc2b2cd98373fc5c1e85ce4
Author: Christian Hilberg <hilberg kernelconcepts de>
Date:   Thu Sep 20 20:10:28 2012 +0200

    KolabMailImapClient: refuse to delete non-empty folder
    
    * do not delete folders which contain messages or
      subfolders
    * KolabMailImapClient is used in backend context,
      and we do not have a proper means of displaying
      nested PIM folder structures in Evo, so we better
      safe-guard against disastrous accidential delete
      operations
    * if a folder with too many PIM items must be deleted,
      it will be okay to require the user to switch to
      email view, unhide PIM folders and delete them there

 src/libekolab/kolab-mail-imap-client.c |   64 ++++++++++++++++++++++++++++++-
 1 files changed, 61 insertions(+), 3 deletions(-)
---
diff --git a/src/libekolab/kolab-mail-imap-client.c b/src/libekolab/kolab-mail-imap-client.c
index a145d18..ccdb2ff 100644
--- a/src/libekolab/kolab-mail-imap-client.c
+++ b/src/libekolab/kolab-mail-imap-client.c
@@ -1707,26 +1707,84 @@ kolab_mail_imap_client_delete_folder (KolabMailImapClient *self,
                                       GError **err)
 {
 	KolabMailImapClientPrivate *priv = NULL;
+	CamelFolderInfo *fi = NULL;
+	CamelFolder *folder = NULL;
 	GError *tmp_err = NULL;
-	gboolean ok = FALSE;
+	gboolean has_children = FALSE;
+	gboolean has_messages = FALSE;
+	gboolean ok = TRUE;
 
 	g_assert (KOLAB_IS_MAIL_IMAP_CLIENT (self));
 	g_assert (foldername != NULL);
-	(void)cancellable; /* FIXME */ /* cancellable may be NULL */
+	/* cancellable may be NULL */
 	g_return_val_if_fail (err == NULL || *err == NULL, FALSE);
 
 	priv = KOLAB_MAIL_IMAP_CLIENT_PRIVATE (self);
 
 	g_assert (priv->is_up == TRUE);
 
+	fi = camel_kolab_imapx_store_get_folder_info_online (priv->store,
+	                                                     foldername,
+	                                                     CAMEL_STORE_FOLDER_INFO_NO_VIRTUAL,
+	                                                     cancellable,
+	                                                     &tmp_err);
+	if (tmp_err != NULL)
+		goto exit;
+
+	/* CamelFolderInfo->total is unreliable unless we down-sync folder,
+	 * if we need that information, we need to get CamelFolder
+	 */
+	has_children = (fi->child != NULL);
+
+	if (has_children)
+		goto folder_skip;
+	
+	folder = camel_store_get_folder_sync (CAMEL_STORE (priv->store),
+	                                      foldername,
+	                                      0,
+	                                      cancellable,
+	                                      &tmp_err);
+	
+	if (tmp_err != NULL)
+		goto exit;
+
+	ok = camel_folder_refresh_info_sync (folder,
+	                                     cancellable,
+	                                     &tmp_err);
+	if (! ok)
+		goto exit;
+
+	has_messages = (camel_folder_get_message_count (folder) > 0);
+
+ folder_skip:
+	
+	/* won't delete a folder which has subfolders or messages in it */
+	if (has_children || has_messages) {
+		g_set_error (&tmp_err,
+		             KOLAB_CAMEL_ERROR,
+		             KOLAB_CAMEL_ERROR_GENERIC,
+		             _("Refusing to delete non-empty folder %s"),
+		             foldername);
+		goto exit;
+	}
+
 	/* delete folder on server */
 	ok = camel_store_delete_folder_sync (CAMEL_STORE (priv->store),
 	                                     foldername,
 	                                     cancellable,
 	                                     &tmp_err);
-	if (! ok)
+ exit:
+	if (tmp_err != NULL) {
 		g_propagate_error (err, tmp_err);
+		ok = FALSE;
+	}
 
+	if (fi != NULL)
+		camel_store_free_folder_info (CAMEL_STORE (priv->store), fi);
+
+	if (folder)
+		g_object_unref (folder);
+	
 	return ok;
 }
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]