fix 50722 problems renaming open imap folder r=mscott

git-svn-id: svn://10.0.0.236/trunk@78020 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
bienvenu%netscape.com
2000-09-02 14:42:14 +00:00
parent 6a74927cf2
commit 8f64370076
6 changed files with 126 additions and 47 deletions

View File

@@ -71,6 +71,7 @@ interface nsIImapIncomingServer : nsISupports {
void ResetNamespaceReferences();
void PseudoInterruptMsgLoad(in nsIImapUrl aImapUrl, out boolean interrupted);
void ResetConnection(in string folderName);
void CloseConnectionForFolder(in nsIMsgFolder aMsgFolder);
void CreatePRUnicharStringFromUTF7(in string aSourceString, out wstring aUnicodeStr);
void reDiscoverAllFolders();
attribute boolean doingLsub;

View File

@@ -24,6 +24,7 @@
#include "nsIMsgFolder.idl"
interface nsIMsgWindow;
interface nsIImapIncomingServer;
[scriptable, uuid(FBFEBE79-C1DD-11d2-8A40-0060B0FC04D2)]
interface nsIMsgImapMailFolder : nsISupports {
@@ -33,6 +34,7 @@ interface nsIMsgImapMailFolder : nsISupports {
void RenameLocal(in string newname);
void PrepareToRename();
void PerformExpand(in nsIMsgWindow aMsgWindow);
void RecursiveCloseActiveConnections(in nsIImapIncomingServer aImapServer);
attribute boolean verifiedAsOnlineFolder;
attribute boolean explicitlyVerify;

View File

@@ -737,6 +737,46 @@ nsImapIncomingServer::CreateProtocolInstance(nsIEventQueue *aEventQueue,
return rv;
}
NS_IMETHODIMP nsImapIncomingServer::CloseConnectionForFolder(nsIMsgFolder *aMsgFolder)
{
nsresult rv = NS_OK;
nsCOMPtr<nsIImapProtocol> connection;
nsCOMPtr<nsISupports> aSupport;
PRBool isBusy = PR_FALSE, isInbox = PR_FALSE;
PRUint32 cnt = 0;
nsXPIDLCString inFolderName;
nsXPIDLCString connectionFolderName;
nsCOMPtr <nsIMsgImapMailFolder> imapFolder = do_QueryInterface(aMsgFolder);
if (!imapFolder)
return NS_ERROR_NULL_POINTER;
rv = m_connectionCache->Count(&cnt);
if (NS_FAILED(rv)) return rv;
imapFolder->GetOnlineName(getter_Copies(inFolderName));
PR_CEnterMonitor(this);
for (PRUint32 i=0; i < cnt; i++)
{
aSupport = getter_AddRefs(m_connectionCache->ElementAt(i));
connection = do_QueryInterface(aSupport);
if (connection)
{
rv = connection->GetSelectedMailboxName(getter_Copies(connectionFolderName));
if (PL_strcmp(connectionFolderName,inFolderName) == 0)
{
rv = connection->IsBusy(&isBusy, &isInbox);
if (!isBusy)
rv = connection->TellThreadToDie(PR_TRUE);
break; // found it, end of the loop
}
}
}
PR_CExitMonitor(this);
return rv;
}
NS_IMETHODIMP nsImapIncomingServer::ResetConnection(const char* folderName)
{

View File

@@ -945,6 +945,12 @@ NS_IMETHODIMP nsImapMailFolder::Delete ()
NS_IMETHODIMP nsImapMailFolder::Rename (const PRUnichar *newName)
{
nsresult rv = NS_ERROR_FAILURE;
nsCOMPtr <nsIImapIncomingServer> incomingImapServer;
GetImapIncomingServer(getter_AddRefs(incomingImapServer));
if (incomingImapServer)
RecursiveCloseActiveConnections(incomingImapServer);
NS_WITH_SERVICE (nsIImapService, imapService, kCImapService, &rv);
if (NS_SUCCEEDED(rv))
rv = imapService->RenameLeaf(m_eventQueue, this, newName, this,
@@ -952,6 +958,31 @@ NS_IMETHODIMP nsImapMailFolder::Rename (const PRUnichar *newName)
return rv;
}
NS_IMETHODIMP nsImapMailFolder::RecursiveCloseActiveConnections(nsIImapIncomingServer *incomingImapServer)
{
NS_ENSURE_ARG(incomingImapServer);
incomingImapServer->CloseConnectionForFolder(this);
PRUint32 cnt = 0, i;
if (mSubFolders)
{
nsCOMPtr<nsISupports> aSupport;
nsCOMPtr<nsIMsgImapMailFolder> folder;
mSubFolders->Count(&cnt);
if (cnt > 0)
{
for (i = 0; i < cnt; i++)
{
aSupport = getter_AddRefs(mSubFolders->ElementAt(i));
folder = do_QueryInterface(aSupport);
if (folder)
folder->RecursiveCloseActiveConnections(incomingImapServer);
}
}
}
return NS_OK;
}
// this is called *after* we've done the rename on the server.
NS_IMETHODIMP nsImapMailFolder::PrepareToRename()
{
PRUint32 cnt = 0, i;
@@ -1123,6 +1154,24 @@ nsresult nsImapMailFolder::GetServerKey(char **serverKey)
return rv;
}
nsresult nsImapMailFolder::GetImapIncomingServer(nsIImapIncomingServer **aImapIncomingServer)
{
NS_ENSURE_ARG(aImapIncomingServer);
*aImapIncomingServer = nsnull;
nsCOMPtr<nsIMsgIncomingServer> server;
if (NS_SUCCEEDED(GetServer(getter_AddRefs(server))) && server)
{
nsCOMPtr <nsIImapIncomingServer> incomingServer = do_QueryInterface(server);
*aImapIncomingServer = incomingServer;
NS_IF_ADDREF(*aImapIncomingServer);
return NS_OK;
}
return NS_ERROR_NULL_POINTER;
}
NS_IMETHODIMP nsImapMailFolder::UserNeedsToAuthenticateForFolder(PRBool
displayOnly,
PRBool
@@ -1447,27 +1496,24 @@ NS_IMETHODIMP nsImapMailFolder::DeleteMessages(nsISupportsArray *messages,
nsIMsgWindow *msgWindow,
PRBool deleteStorage, PRBool isMove)
{
nsresult rv = NS_ERROR_FAILURE;
// *** jt - assuming delete is move to the trash folder for now
nsCOMPtr<nsIEnumerator> aEnumerator;
nsCOMPtr<nsIRDFResource> res;
nsCAutoString uri;
PRBool deleteImmediatelyNoTrash = PR_FALSE;
nsCAutoString messageIds;
nsMsgKeyArray srcKeyArray;
nsresult rv = NS_ERROR_FAILURE;
// *** jt - assuming delete is move to the trash folder for now
nsCOMPtr<nsIEnumerator> aEnumerator;
nsCOMPtr<nsIRDFResource> res;
nsCAutoString uri;
PRBool deleteImmediatelyNoTrash = PR_FALSE;
nsCAutoString messageIds;
nsMsgKeyArray srcKeyArray;
nsMsgImapDeleteModel deleteModel = nsMsgImapDeleteModels::MoveToTrash;
nsMsgImapDeleteModel deleteModel = nsMsgImapDeleteModels::MoveToTrash;
nsCOMPtr<nsIImapIncomingServer> imapServer;
nsCOMPtr<nsIMsgIncomingServer> server;
rv = GetFlag(MSG_FOLDER_FLAG_TRASH, &deleteImmediatelyNoTrash);
rv = GetImapIncomingServer(getter_AddRefs(imapServer));
if (NS_SUCCEEDED(GetServer(getter_AddRefs(server))) && server)
if (NS_SUCCEEDED(rv) && imapServer)
{
imapServer = do_QueryInterface(server);
if (imapServer)
imapServer->GetDeleteModel(&deleteModel);
imapServer->GetDeleteModel(&deleteModel);
if (deleteModel != nsMsgImapDeleteModels::MoveToTrash || deleteStorage)
deleteImmediatelyNoTrash = PR_TRUE;
}
@@ -1617,19 +1663,14 @@ nsImapMailFolder::DeleteSubFolders(nsISupportsArray* folders, nsIMsgWindow *msgW
if (canHaveSubFoldersOfTrash) // UW server doesn't set NOINFERIORS - check dual use pref
{
nsCOMPtr<nsIImapIncomingServer> imapServer;
nsCOMPtr<nsIMsgIncomingServer> server;
rv = GetImapIncomingServer(getter_AddRefs(imapServer));
rv = GetServer(getter_AddRefs(server));
if (server)
if (NS_SUCCEEDED(rv) && imapServer)
{
imapServer = do_QueryInterface(server, &rv);
if (NS_SUCCEEDED(rv) && imapServer)
{
PRBool serverSupportsDualUseFolders;
imapServer->GetDualUseFolders(&serverSupportsDualUseFolders);
if (!serverSupportsDualUseFolders)
canHaveSubFoldersOfTrash = PR_FALSE;
}
PRBool serverSupportsDualUseFolders;
imapServer->GetDualUseFolders(&serverSupportsDualUseFolders);
if (!serverSupportsDualUseFolders)
canHaveSubFoldersOfTrash = PR_FALSE;
}
}
if (!canHaveSubFoldersOfTrash)
@@ -3089,23 +3130,18 @@ PRBool nsImapMailFolder::ShowDeletedMessages()
if (!showDeleted)
{
nsCOMPtr<nsIImapIncomingServer> imapServer;
nsCOMPtr<nsIMsgIncomingServer> server;
nsresult rv = GetImapIncomingServer(getter_AddRefs(imapServer));
nsresult rv = GetServer(getter_AddRefs(server));
if (server)
if (NS_SUCCEEDED(rv) && imapServer)
{
imapServer = do_QueryInterface(server, &rv);
if (NS_SUCCEEDED(rv) && imapServer)
PRBool isAOLServer = PR_FALSE;
imapServer->GetIsAOLServer(&isAOLServer);
if (isAOLServer)
{
PRBool isAOLServer = PR_FALSE;
imapServer->GetIsAOLServer(&isAOLServer);
if (isAOLServer)
{
nsXPIDLString folderName;
GetName(getter_Copies(folderName));
if (!nsCRT::strncasecmp(folderName, "Trash", 5))
showDeleted = PR_TRUE;
}
nsXPIDLString folderName;
GetName(getter_Copies(folderName));
if (!nsCRT::strncasecmp(folderName, "Trash", 5))
showDeleted = PR_TRUE;
}
}
}
@@ -4377,11 +4413,8 @@ NS_IMETHODIMP nsImapMailFolder::PerformExpand(nsIMsgWindow *aMsgWindow)
nsresult rv;
PRBool usingSubscription = PR_FALSE;
nsCOMPtr<nsIImapIncomingServer> imapServer;
nsCOMPtr<nsIMsgIncomingServer> server;
rv = GetImapIncomingServer(getter_AddRefs(imapServer));
rv = GetServer(getter_AddRefs(server));
if (NS_FAILED(rv) || !server) return NS_ERROR_FAILURE;
imapServer = do_QueryInterface(server, &rv);
if (NS_FAILED(rv) || !imapServer) return NS_ERROR_FAILURE;
rv = imapServer->GetUsingSubscription(&usingSubscription);
if (NS_SUCCEEDED(rv) && !usingSubscription)

View File

@@ -284,6 +284,7 @@ protected:
nsresult GetTrashFolder(nsIMsgFolder **pTrashFolder);
PRBool TrashOrDescendentOfTrash(nsIMsgFolder* folder);
nsresult GetServerKey(char **serverKey);
nsresult GetImapIncomingServer(nsIImapIncomingServer **aImapIncomingServer);
nsresult DisplayStatusMsg(nsIImapUrl *aImapUrl, const PRUnichar *msg);

View File

@@ -778,6 +778,8 @@ nsImapProtocol::TellThreadToDie(PRBool isSaveToClose)
// **** jt - This routine should only be called by imap service.
nsAutoCMonitor(this);
m_urlInProgress = PR_TRUE; // let's say it's busy so no one tries to use
// this about to die connection.
PRBool closeNeeded = GetServerStateParser().GetIMAPstate() ==
nsImapServerResponseParser::kFolderSelected && isSaveToClose;
nsCString command;
@@ -1399,7 +1401,7 @@ NS_IMETHODIMP nsImapProtocol::IsBusy(PRBool *aIsConnectionBusy,
}
#define IS_SUBSCRIPTION_RELATED_ACTION(action) (action == nsIImapUrl::nsImapSubscribe\
|| action == nsIImapUrl::nsImapUnsubscribe || action == nsIImapUrl::nsImapDiscoverAllBoxesUrl)
|| action == nsIImapUrl::nsImapUnsubscribe || action == nsIImapUrl::nsImapDiscoverAllBoxesUrl || action == nsIImapUrl::nsImapListFolder)
// canRunUrl means the connection is not busy, and is in the selcted state
@@ -1460,7 +1462,7 @@ NS_IMETHODIMP nsImapProtocol::CanHandleUrl(nsIImapUrl * aImapUrl,
aImapUrl->GetRequiredImapState(&imapState);
// OK, this is a bit of a hack - we're going to pretend that
// a delete folder url requires a selected state connection on
// a delete or rename 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
@@ -1469,7 +1471,7 @@ NS_IMETHODIMP nsImapProtocol::CanHandleUrl(nsIImapUrl * aImapUrl,
// 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;
|| actionForProposedUrl == nsIImapUrl::nsImapDeleteFolder || actionForProposedUrl == nsIImapUrl::nsImapRenameFolder;
nsCOMPtr<nsIMsgMailNewsUrl> msgUrl = do_QueryInterface(aImapUrl);
nsCOMPtr<nsIMsgIncomingServer> server;