bug 120485:Can't delete folders on IMAP server cascadely

r=bienvenu sr=mscott
Check in for Henry Jia's(henry.jia@sun.com) fix
This commit is contained in:
pete.zha%sun.com 2002-04-17 07:38:27 +00:00
parent 43746f29aa
commit 4e2b201681
2 changed files with 90 additions and 24 deletions

View File

@ -2038,7 +2038,8 @@ void nsImapProtocol::ProcessSelectedStateURL()
}
}
DeleteSubFolders(mailboxName);
PRBool deleteSelf = PR_FALSE;
DeleteSubFolders(mailboxName, deleteSelf); // don't delete self
}
break;
case nsIImapUrl::nsImapAppendDraftFromFile:
@ -5474,13 +5475,15 @@ PRBool nsImapProtocol::RenameHierarchyByHand(const char *oldParentMailboxName,
return renameSucceeded;
}
PRBool nsImapProtocol::DeleteSubFolders(const char* selectedMailbox)
PRBool nsImapProtocol::DeleteSubFolders(const char* selectedMailbox, PRBool &aDeleteSelf)
{
PRBool deleteSucceeded = PR_TRUE;
m_deletableChildren = new nsVoidArray();
if (m_deletableChildren)
{
PRBool folderDeleted = PR_FALSE;
m_hierarchyNameState = kDeleteSubFoldersInProgress;
nsCString pattern(selectedMailbox);
char onlineDirSeparator = kOnlineHierarchySeparatorUnknown;
@ -5500,7 +5503,29 @@ PRBool nsImapProtocol::DeleteSubFolders(const char* selectedMailbox)
// ** jt - why? I don't understand this.
PRInt32 numberToDelete = m_deletableChildren->Count();
PRInt32 outerIndex, innerIndex;
// intelligently decide if myself(either plain format or following the dir-separator)
// is in the sub-folder list
PRBool folderInSubfolderList = PR_FALSE; // For Performance
char *selectedMailboxDir = nsnull;
{
PRInt32 length = strlen(selectedMailbox);
selectedMailboxDir = (char *)PR_MALLOC(length+2);
if( selectedMailboxDir ) // only do the intelligent test if there is enough memory
{
strcpy(selectedMailboxDir, selectedMailbox);
selectedMailboxDir[length] = onlineDirSeparator;
selectedMailboxDir[length+1] = '\0';
PRInt32 i;
for( i=0; i<numberToDelete && !folderInSubfolderList; i++ )
{
char *currentName = (char *) m_deletableChildren->ElementAt(i);
if( !strcmp(currentName, selectedMailbox) || !strcmp(currentName, selectedMailboxDir) )
folderInSubfolderList = PR_TRUE;
}
}
}
deleteSucceeded = GetServerStateParser().LastCommandSuccessful();
for (outerIndex = 0;
(outerIndex < numberToDelete) && deleteSucceeded;
@ -5514,8 +5539,7 @@ PRBool nsImapProtocol::DeleteSubFolders(const char* selectedMailbox)
{
char *currentName =
(char *) m_deletableChildren->ElementAt(innerIndex);
if (!longestName ||
PL_strlen(longestName) < PL_strlen(currentName))
if (!longestName || strlen(longestName) < strlen(currentName))
{
longestName = currentName;
longestIndex = innerIndex;
@ -5543,23 +5567,57 @@ PRBool nsImapProtocol::DeleteSubFolders(const char* selectedMailbox)
// string passed to the list command. Be defensive and make sure
// we only delete children of the trash
if (longestName &&
PL_strcmp(selectedMailbox, longestName) &&
!PL_strncmp(selectedMailbox, longestName,
PL_strlen(selectedMailbox)))
strcmp(selectedMailbox, longestName) &&
!strncmp(selectedMailbox, longestName, strlen(selectedMailbox)))
{
nsCOMPtr<nsIImapIncomingServer> imapServer =
do_QueryReferent(m_server);
if (imapServer)
imapServer->ResetConnection(longestName);
PRBool deleted =
DeleteMailboxRespectingSubscriptions(longestName);
if (deleted)
FolderDeleted(longestName);
deleteSucceeded = deleted;
if( selectedMailboxDir && !strcmp(selectedMailboxDir, longestName) ) // just myself
{
if( aDeleteSelf )
{
PRBool deleted = DeleteMailboxRespectingSubscriptions(longestName);
if (deleted)
FolderDeleted(longestName);
folderDeleted = deleted;
deleteSucceeded = deleted;
}
}
else
{
nsCOMPtr<nsIImapIncomingServer> imapServer = do_QueryReferent(m_server);
if (imapServer)
imapServer->ResetConnection(longestName);
PRBool deleted = PR_FALSE;
if( folderInSubfolderList ) // for performance
{
nsVoidArray* pDeletableChildren = m_deletableChildren;
m_deletableChildren = nsnull;
PRBool folderDeleted = PR_TRUE;
deleted = DeleteSubFolders(longestName, folderDeleted);
// longestName may have subfolder list including itself
if( !folderDeleted )
{
if (deleted)
deleted = DeleteMailboxRespectingSubscriptions(longestName);
if (deleted)
FolderDeleted(longestName);
}
m_deletableChildren = pDeletableChildren;
}
else
{
deleted = DeleteMailboxRespectingSubscriptions(longestName);
if (deleted)
FolderDeleted(longestName);
}
deleteSucceeded = deleted;
}
}
PR_FREEIF(longestName);
}
aDeleteSelf = folderDeleted; // feedback if myself is deleted
PR_Free(selectedMailboxDir);
delete m_deletableChildren;
m_deletableChildren = nsnull;
}
@ -5612,11 +5670,16 @@ void nsImapProtocol::FolderRenamed(const char *oldName,
void nsImapProtocol::OnDeleteFolder(const char * sourceMailbox)
{
PRBool deleted = DeleteSubFolders(sourceMailbox);
if (deleted)
deleted = DeleteMailboxRespectingSubscriptions(sourceMailbox);
if (deleted)
FolderDeleted(sourceMailbox);
// intelligently delete the folder
PRBool folderDeleted = PR_TRUE;
PRBool deleted = DeleteSubFolders(sourceMailbox, folderDeleted);
if( !folderDeleted )
{
if (deleted)
deleted = DeleteMailboxRespectingSubscriptions(sourceMailbox);
if (deleted)
FolderDeleted(sourceMailbox);
}
}
void nsImapProtocol::OnRenameFolder(const char * sourceMailbox)

View File

@ -520,7 +520,10 @@ private:
void List(const char *mailboxPattern, PRBool addDirectoryIfNecessary);
void Subscribe(const char *mailboxName);
void Unsubscribe(const char *mailboxName);
PRBool DeleteSubFolders(const char* mailboxName);
// Some imap servers include the mailboxName following the dir-separator in the list of
// subfolders of the mailboxName. In fact, they are the same. So we should decide if
// we should delete such subfolder and provide feedback if the delete operation succeed.
PRBool DeleteSubFolders(const char* aMailboxName, PRBool & aDeleteSelf);
PRBool RenameHierarchyByHand(const char *oldParentMailboxName,
const char *newParentMailboxName);