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:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user