fix problems deleting imap folders, and aol imap trash view, r=mscott 50232 11689 33217

This commit is contained in:
bienvenu%netscape.com 2000-08-25 02:45:36 +00:00
parent f196fa716f
commit 27e286afc7
6 changed files with 139 additions and 44 deletions

View File

@ -326,3 +326,8 @@
## @name IMAP_DEFAULT_ACCOUNT_NAME
## @loc None
5057=Mail for %S
## @name IMAP_DELETE_NO_TRASH
## @loc None
5058=Deleting this folder is not undoable and will delete all of the messages it contains. Are you sure you still want to delete this folder?

View File

@ -963,6 +963,10 @@ NS_IMETHODIMP nsImapIncomingServer::PossibleImapMailbox(const char *folderPath,
nsCOMPtr <nsIMsgImapMailFolder> imapFolder = do_QueryInterface(child);
if (imapFolder)
{
PRBool isAOLServer = PR_FALSE;
GetIsAOLServer(&isAOLServer);
nsXPIDLCString onlineName;
nsXPIDLString unicodeName;
imapFolder->SetVerifiedAsOnlineFolder(PR_TRUE);
@ -975,7 +979,11 @@ NS_IMETHODIMP nsImapIncomingServer::PossibleImapMailbox(const char *folderPath,
imapFolder->SetOnlineName(dupFolderPath);
if (NS_SUCCEEDED(CreatePRUnicharStringFromUTF7(folderName, getter_Copies(unicodeName))))
child->SetName(unicodeName);
if (isAOLServer && onlineName && !nsCRT::strcasecmp(onlineName, "RECYCLE"))
{
nsAutoString trashName; trashName.AssignWithConversion("Trash");
child->SetPrettyName(trashName.GetUnicode()); // don't localize - it's a semi-reserved name for IMAP
}
}
}
return NS_OK;

View File

@ -1556,8 +1556,11 @@ NS_IMETHODIMP nsImapMailFolder::DeleteMessages(nsISupportsArray *messages,
return rv;
}
// check if folder is the trash, or a descendent of the trash
// so we can tell if the folders we're deleting from it should
// be *really* deleted.
PRBool
nsImapMailFolder::InTrash(nsIMsgFolder* folder)
nsImapMailFolder::TrashOrDescendentOfTrash(nsIMsgFolder* folder)
{
nsCOMPtr<nsIMsgFolder> parent;
nsCOMPtr<nsIFolder> iFolder;
@ -1571,14 +1574,14 @@ nsImapMailFolder::InTrash(nsIMsgFolder* folder)
do
{
rv = curFolder->GetFlags(&flags);
if (NS_FAILED(rv)) return PR_FALSE;
if (flags & MSG_FOLDER_FLAG_TRASH)
return PR_TRUE;
rv = curFolder->GetParent(getter_AddRefs(iFolder));
if (NS_FAILED(rv)) return PR_FALSE;
parent = do_QueryInterface(iFolder, &rv);
if (NS_FAILED(rv)) return PR_FALSE;
rv = parent->GetFlags(&flags);
if (NS_FAILED(rv)) return PR_FALSE;
if (flags & MSG_FOLDER_FLAG_TRASH)
return PR_TRUE;
curFolder = do_QueryInterface(parent, &rv);
} while (NS_SUCCEEDED(rv) && curFolder);
@ -1593,7 +1596,8 @@ nsImapMailFolder::DeleteSubFolders(nsISupportsArray* folders, nsIMsgWindow *msgW
nsCOMPtr<nsIMsgFolder> trashFolder;
PRUint32 i, folderCount = 0;
nsresult rv;
PRBool deleteFromTrash = InTrash(this);;
// "this" is the folder we're deleting from
PRBool deleteNoTrash = TrashOrDescendentOfTrash(this);;
PRBool moveToTrash = PR_FALSE;
NS_WITH_SERVICE (nsIImapService, imapService, kCImapService, &rv);
@ -1608,38 +1612,68 @@ nsImapMailFolder::DeleteSubFolders(nsISupportsArray* folders, nsIMsgWindow *msgW
msgWindow->GetRootDocShell(getter_AddRefs(docShell));
nsCOMPtr<nsIPrompt> dialog;
if (docShell) dialog = do_GetInterface(docShell);
PRUnichar *moveToTrashStr = IMAPGetStringByID(IMAP_MOVE_FOLDER_TO_TRASH);
if (dialog && moveToTrashStr) {
dialog->Confirm(nsnull, moveToTrashStr, &moveToTrash);
}
for (i = 0; i < folderCount; i++)
if (!deleteNoTrash)
{
folderSupport = getter_AddRefs(folders->ElementAt(i));
curFolder = do_QueryInterface(folderSupport, &rv);
if (NS_SUCCEEDED(rv))
PRBool canHaveSubFoldersOfTrash = PR_TRUE;
trashFolder->GetCanCreateSubfolders(&canHaveSubFoldersOfTrash);
if (canHaveSubFoldersOfTrash) // UW server doesn't set NOINFERIORS - check dual use pref
{
nsCOMPtr<nsIImapIncomingServer> imapServer;
nsCOMPtr<nsIMsgIncomingServer> server;
nsresult rv = GetServer(getter_AddRefs(server));
if (server)
{
urlListener = do_QueryInterface(curFolder);
if (deleteFromTrash)
rv = imapService->DeleteFolder(m_eventQueue,
imapServer = do_QueryInterface(server, &rv);
if (NS_SUCCEEDED(rv) && imapServer)
{
PRBool serverSupportsDualUseFolders;
imapServer->GetDualUseFolders(&serverSupportsDualUseFolders);
if (!serverSupportsDualUseFolders)
canHaveSubFoldersOfTrash = PR_FALSE;
}
}
}
if (!canHaveSubFoldersOfTrash)
deleteNoTrash = PR_TRUE;
}
PRUnichar *confirmationStr = IMAPGetStringByID((!deleteNoTrash)
? IMAP_MOVE_FOLDER_TO_TRASH : IMAP_DELETE_NO_TRASH);
PRBool confirmed = PR_FALSE;
if (dialog && confirmationStr) {
dialog->Confirm(nsnull, confirmationStr, &confirmed);
}
if (confirmed)
{
for (i = 0; i < folderCount; i++)
{
folderSupport = getter_AddRefs(folders->ElementAt(i));
curFolder = do_QueryInterface(folderSupport, &rv);
if (NS_SUCCEEDED(rv))
{
urlListener = do_QueryInterface(curFolder);
if (deleteNoTrash)
rv = imapService->DeleteFolder(m_eventQueue,
curFolder,
urlListener,
nsnull);
else
rv = imapService->MoveFolder(m_eventQueue,
curFolder,
trashFolder,
urlListener,
nsnull);
else if (moveToTrash)
rv = imapService->MoveFolder(m_eventQueue,
curFolder,
trashFolder,
urlListener,
nsnull);
}
}
}
}
if (moveToTrashStr)
nsCRT::free(moveToTrashStr);
if (confirmationStr)
nsCRT::free(confirmationStr);
}
}
if (deleteFromTrash || moveToTrash)
if (deleteNoTrash || moveToTrash)
return nsMsgFolder::DeleteSubFolders(folders, nsnull);
else
return rv;
@ -3045,16 +3079,39 @@ PRBool nsImapMailFolder::ShowDeletedMessages()
nsresult err;
NS_WITH_SERVICE(nsIImapHostSessionList, hostSession,
kCImapHostSessionList, &err);
PRBool rv = PR_FALSE;
PRBool showDeleted = PR_FALSE;
if (NS_SUCCEEDED(err) && hostSession)
if (NS_SUCCEEDED(err) && hostSession)
{
char *serverKey = nsnull;
GetServerKey(&serverKey);
err = hostSession->GetShowDeletedMessagesForHost(serverKey, rv);
PR_FREEIF(serverKey);
nsXPIDLCString serverKey;
GetServerKey(getter_Copies(serverKey));
err = hostSession->GetShowDeletedMessagesForHost(serverKey, showDeleted);
}
return rv;
// check for special folders that need to show deleted messages
if (!showDeleted)
{
nsCOMPtr<nsIImapIncomingServer> imapServer;
nsCOMPtr<nsIMsgIncomingServer> server;
nsresult rv = GetServer(getter_AddRefs(server));
if (server)
{
imapServer = do_QueryInterface(server, &rv);
if (NS_SUCCEEDED(rv) && imapServer)
{
PRBool isAOLServer = PR_FALSE;
imapServer->GetIsAOLServer(&isAOLServer);
if (isAOLServer)
{
nsXPIDLString folderName;
GetName(getter_Copies(folderName));
if (!nsCRT::strncasecmp(folderName, "Trash", 5))
showDeleted = PR_TRUE;
}
}
}
}
return showDeleted;
}

View File

@ -282,7 +282,7 @@ protected:
void ParseUidString(char *uidString, nsMsgKeyArray &keys);
nsresult GetFolder(const char *name, nsIMsgFolder **pFolder);
nsresult GetTrashFolder(nsIMsgFolder **pTrashFolder);
PRBool InTrash(nsIMsgFolder* folder);
PRBool TrashOrDescendentOfTrash(nsIMsgFolder* folder);
nsresult GetServerKey(char **serverKey);
nsresult DisplayStatusMsg(nsIImapUrl *aImapUrl, const PRUnichar *msg);

View File

@ -20,6 +20,10 @@
* Contributor(s):
* Pierre Phaneuf <pp@ludusdesign.com>
*/
#ifdef DEBUG_bienvenu
#define DOING_PSEUDO_MAILBOXES
#endif
// sorry, this has to be before the pre-compiled header
#define FORCE_PR_LOG /* Allow logging in the release build */
// as does this
@ -1451,10 +1455,21 @@ NS_IMETHODIMP nsImapProtocol::CanHandleUrl(nsIImapUrl * aImapUrl,
}
nsImapState imapState;
nsImapAction actionForProposedUrl;
aImapUrl->GetImapAction(&actionForProposedUrl);
aImapUrl->GetRequiredImapState(&imapState);
PRBool isSelectedStateUrl = imapState ==
nsIImapUrl::nsImapSelectedState;
// OK, this is a bit of a hack - we're going to pretend that
// a delete folder url requires a selected state connection on
// the folder to be deleted. This isn't technically true,
// but we would much rather use that connection for several reasons,
// one is that some UW servers require us to use that connection
// the other is that we don't want to leave a connection dangling in
// the selected state for the deleted folder.
// If we don't find a connection in that selected state,
// we'll fall back to the first free connection.
PRBool isSelectedStateUrl = imapState == nsIImapUrl::nsImapSelectedState
|| actionForProposedUrl == nsIImapUrl::nsImapDeleteFolder;
nsCOMPtr<nsIMsgMailNewsUrl> msgUrl = do_QueryInterface(aImapUrl);
nsCOMPtr<nsIMsgIncomingServer> server;
@ -1513,7 +1528,6 @@ NS_IMETHODIMP nsImapProtocol::CanHandleUrl(nsIImapUrl * aImapUrl,
else // *** jt - an authenticated state url can be run in either
// authenticated or selected state
{
nsImapAction actionForProposedUrl;
nsImapAction actionForRunningUrl;
// If proposed url is subscription related, and we are currently running
@ -1521,7 +1535,6 @@ NS_IMETHODIMP nsImapProtocol::CanHandleUrl(nsIImapUrl * aImapUrl,
// Otherwise, we can run this url if we're not busy.
// If we never find a running subscription-related url, the caller will
// just use whatever free connection it can find, which is what we want.
aImapUrl->GetImapAction(&actionForProposedUrl);
if (IS_SUBSCRIPTION_RELATED_ACTION(actionForProposedUrl))
{
if (isBusy && m_runningUrl)
@ -5795,7 +5808,18 @@ void nsImapProtocol::CreateMailbox(const char *mailboxName)
void nsImapProtocol::DeleteMailbox(const char *mailboxName)
{
ProgressEventFunctionUsingIdWithString (IMAP_STATUS_DELETING_MAILBOX, mailboxName);
// check if this connection currently has the folder to be deleted selected.
// If so, we should close it because at least some UW servers don't like you deleting
// a folder you have open.
if (GetServerStateParser().GetIMAPstate() ==
nsImapServerResponseParser::kFolderSelected && GetServerStateParser().GetSelectedMailboxName() &&
PL_strcmp(GetServerStateParser().GetSelectedMailboxName(),
mailboxName) == 0)
Close();
ProgressEventFunctionUsingIdWithString (IMAP_STATUS_DELETING_MAILBOX, mailboxName);
IncrementCommandTagNumber();

View File

@ -89,4 +89,5 @@ NS_END_EXTERN_C
#define IMAP_MOVE_FOLDER_TO_TRASH 5055
#define IMAP_NO_NEW_MESSAGES 5056
#define IMAP_DEFAULT_ACCOUNT_NAME 5057
#define IMAP_DELETE_NO_TRASH 5058
#endif /* _nsImapStringBundle_H__ */