66955 r=cavin sr=bienvenu. Implementing drag and drop messages from advanced search results to 3 pane.

Hooking up fcc, search results and drag and drop copies to copyService so that we can handle multiple sources/requests.
89285 r=cavin sr=bienvenu fixing copy to Sent folder failed sometimes by queuing copy requests
This commit is contained in:
naving%netscape.com 2002-08-16 22:22:55 +00:00
Родитель a423cfe794
Коммит 860341ecae
14 изменённых файлов: 247 добавлений и 207 удалений

Просмотреть файл

@ -69,14 +69,16 @@ interface nsIMessenger : nsISupports {
void DeleteFolders(in nsIRDFCompositeDataSource db,
in nsIRDFResource parentFolder,
in nsIRDFResource folder);
void CopyMessages(in nsIMsgFolder srcFolder,
in nsIMsgFolder destFolder,
in nsISupportsArray messageArray,
in boolean isMove);
void CopyMessages(in nsIRDFCompositeDataSource database,
in nsIRDFResource srcResource,
in nsIRDFResource dstResource,
in nsISupportsArray messages,
in boolean isMove);
void CopyFolders(in nsIRDFCompositeDataSource database,
in nsIRDFResource dstFolder,
in nsISupportsArray folders,
in boolean isMoveFolder);
in nsIRDFResource dstResource,
in nsISupportsArray folders,
in boolean isMoveFolder);
void OpenURL(in string url);
void RenameFolder(in nsIRDFCompositeDataSource db,

Просмотреть файл

@ -282,19 +282,20 @@ function DropOnFolderTree(row, orientation)
if (dropMessage) {
var sourceMsgHdr = list.GetElementAt(0).QueryInterface(Components.interfaces.nsIMsgDBHdr);
sourceFolder = sourceMsgHdr.folder;
sourceResource = sourceFolder.QueryInterface(Components.interfaces.nsIRDFResource);
sourceServer = sourceFolder.server;
try {
if (isSourceNews) {
// news to pop or imap is always a copy
messenger.CopyMessages(sourceFolder, targetFolder, list, false);
messenger.CopyMessages(GetFolderDatasource(), sourceResource, targetResource, list, false);
}
else {
var dragAction = dragSession.dragAction;
if (dragAction == nsIDragService.DRAGDROP_ACTION_COPY)
messenger.CopyMessages(sourceFolder, targetFolder, list, false);
messenger.CopyMessages(GetFolderDatasource(), sourceResource, targetResource, list, false);
else if (dragAction == nsIDragService.DRAGDROP_ACTION_MOVE)
messenger.CopyMessages(sourceFolder, targetFolder, list, true);
messenger.CopyMessages(GetFolderDatasource(), sourceResource, targetResource, list, true);
}
}
catch (ex) {

Просмотреть файл

@ -1145,7 +1145,8 @@ function GetSelectedMessages()
try {
var messageArray = {};
var length = {};
gDBView.getURIsForSelection(messageArray,length);
var view = GetDBView();
view.getURIsForSelection(messageArray,length);
return messageArray.value;
}
catch (ex) {

Просмотреть файл

@ -53,6 +53,7 @@ Rights Reserved.
<script src="chrome://messenger/content/mailWindowOverlay.js"/>
<script src="chrome://messenger/content/commandglue.js"/>
<script src="chrome://messenger/content/SearchDialog.js"/>
<script type="application/x-javascript" src="chrome://messenger/content/messengerdnd.js"/>
<script type="application/x-javascript" src="chrome://help/content/contextHelp.js"/>
<commands id="commands">

Просмотреть файл

@ -1144,31 +1144,48 @@ NS_IMETHODIMP nsMessenger::DeleteFolders(nsIRDFCompositeDataSource *db,
}
NS_IMETHODIMP
nsMessenger::CopyMessages(nsIMsgFolder *srcFolder, nsIMsgFolder *destFolder,
nsISupportsArray *messageArray,
nsMessenger::CopyMessages(nsIRDFCompositeDataSource *database,
nsIRDFResource *srcResource, // folder
nsIRDFResource *dstResource,
nsISupportsArray *argumentArray, // nsIMessages
PRBool isMove)
{
nsresult rv;
NS_ENSURE_ARG_POINTER(srcFolder);
NS_ENSURE_ARG_POINTER(destFolder);
NS_ENSURE_ARG_POINTER(messageArray);
rv = destFolder->CopyMessages(srcFolder, messageArray, isMove, mMsgWindow /* nsIMsgWindow */, nsnull /* listener */, PR_FALSE /* isFolder */, PR_TRUE /*allowUndo*/ );
NS_ENSURE_SUCCESS(rv,rv);
return rv;
NS_ENSURE_ARG_POINTER(srcResource);
NS_ENSURE_ARG_POINTER(dstResource);
NS_ENSURE_ARG_POINTER(argumentArray);
nsCOMPtr<nsIMsgFolder> srcFolder;
nsCOMPtr<nsISupportsArray> folderArray;
srcFolder = do_QueryInterface(srcResource);
if(!srcFolder)
return NS_ERROR_NO_INTERFACE;
nsCOMPtr<nsISupports> srcFolderSupports(do_QueryInterface(srcFolder));
if(srcFolderSupports)
argumentArray->InsertElementAt(srcFolderSupports, 0);
rv = NS_NewISupportsArray(getter_AddRefs(folderArray));
NS_ENSURE_SUCCESS(rv, rv);
folderArray->AppendElement(dstResource);
rv = DoCommand(database, isMove ? (char *)NC_RDF_MOVE : (char *)NC_RDF_COPY, folderArray, argumentArray);
return rv;
}
NS_IMETHODIMP
nsMessenger::MessageServiceFromURI(const char *uri, nsIMsgMessageService **msgService)
{
nsresult rv;
NS_ENSURE_ARG_POINTER(uri);
NS_ENSURE_ARG_POINTER(msgService);
rv = GetMessageServiceFromURI(uri, msgService);
NS_ENSURE_SUCCESS(rv,rv);
return rv;
nsresult rv;
NS_ENSURE_ARG_POINTER(uri);
NS_ENSURE_ARG_POINTER(msgService);
rv = GetMessageServiceFromURI(uri, msgService);
NS_ENSURE_SUCCESS(rv,rv);
return rv;
}
NS_IMETHODIMP
@ -1491,19 +1508,19 @@ nsMessenger::SendUnsentMessages(nsIMsgIdentity *aIdentity, nsIMsgWindow *aMsgWin
printf("We succesfully obtained a nsIMsgSendLater interface....\n");
#endif
SendLaterListener *sendLaterListener = new SendLaterListener(this);
if (!sendLaterListener)
return NS_ERROR_OUT_OF_MEMORY;
SendLaterListener *sendLaterListener = new SendLaterListener(this);
if (!sendLaterListener)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(sendLaterListener);
pMsgSendLater->AddListener(sendLaterListener);
pMsgSendLater->SetMsgWindow(aMsgWindow);
mSendingUnsentMsgs = PR_TRUE;
pMsgSendLater->SendUnsentMessages(aIdentity);
NS_RELEASE(sendLaterListener);
}
return NS_OK;
NS_ADDREF(sendLaterListener);
pMsgSendLater->AddListener(sendLaterListener);
pMsgSendLater->SetMsgWindow(aMsgWindow);
mSendingUnsentMsgs = PR_TRUE;
pMsgSendLater->SendUnsentMessages(aIdentity);
NS_RELEASE(sendLaterListener);
}
return NS_OK;
}
NS_IMETHODIMP nsMessenger::DoPrint()

Просмотреть файл

@ -183,15 +183,12 @@ nsMsgCopyService::ClearRequest(nsCopyRequest* aRequest, nsresult rv)
nsresult
nsMsgCopyService::DoCopy(nsCopyRequest* aRequest)
{
nsresult rv = NS_ERROR_NULL_POINTER;
NS_ENSURE_ARG(aRequest);
m_copyRequests.AppendElement((void*) aRequest);
if (m_copyRequests.Count() == 1) //if only one request, then go ahead and do the copy, otherwise the request is queued
return DoNextCopy();
if (aRequest)
{
m_copyRequests.AppendElement((void*) aRequest);
rv = DoNextCopy();
}
return rv;
return NS_OK;
}
nsresult
@ -217,6 +214,10 @@ nsMsgCopyService::DoNextCopy()
{
copySource = (nsCopySource*)
copyRequest->m_copySourceArray.ElementAt(j);
if (copySource->m_msgFolder == copyRequest->m_dstFolder) //don't do move/copy on itself, just skip
copySource->m_processed = PR_TRUE;
if (!copySource->m_processed) goto found;
}
if (j >= scnt) // all processed set the value
@ -239,13 +240,13 @@ nsMsgCopyService::DoNextCopy()
}
else if (copyRequest->m_requestType == nsCopyFoldersType )
{
copySource->m_processed = PR_TRUE;
{
copySource->m_processed = PR_TRUE;
rv = copyRequest->m_dstFolder->CopyFolder
(copySource->m_msgFolder,
copyRequest->m_isMoveOrDraftOrTemplate,
copyRequest->m_msgWindow, copyRequest->m_listener);
}
}
else if (copyRequest->m_requestType == nsCopyFileMessageType)
{
nsCOMPtr<nsIFileSpec> aSpec(do_QueryInterface(copyRequest->m_srcSupport, &rv));
@ -309,47 +310,96 @@ nsMsgCopyService::CopyMessages(nsIMsgFolder* srcFolder, /* UI src folder */
nsIMsgWindow* window,
PRBool allowUndo)
{
nsCopyRequest* copyRequest;
nsCopySource* copySource = nsnull;
nsresult rv = NS_ERROR_NULL_POINTER;
nsCOMPtr<nsISupportsArray> msgArray;
PRUint32 i, cnt;
nsCOMPtr<nsIMsgDBHdr> msg;
nsCOMPtr<nsIMsgFolder> curFolder;
nsCOMPtr<nsISupports> aSupport;
NS_ENSURE_ARG_POINTER(srcFolder);
NS_ENSURE_ARG_POINTER(messages);
NS_ENSURE_ARG_POINTER(dstFolder);
if (!srcFolder || !messages || !dstFolder) return rv;
nsCopyRequest* copyRequest;
nsCopySource* copySource = nsnull;
nsCOMPtr<nsISupportsArray> msgArray;
PRUint32 i, cnt;
nsCOMPtr<nsIMsgDBHdr> msg;
nsCOMPtr<nsIMsgFolder> curFolder;
nsCOMPtr<nsISupports> aSupport;
nsresult rv;
copyRequest = new nsCopyRequest();
if (!copyRequest)
return NS_ERROR_OUT_OF_MEMORY;
copyRequest = new nsCopyRequest();
if (!copyRequest) return rv;
aSupport = do_QueryInterface(srcFolder, &rv);
aSupport = do_QueryInterface(srcFolder, &rv);
rv = copyRequest->Init(nsCopyMessagesType, aSupport, dstFolder,
isMove, listener, window, allowUndo);
if (NS_FAILED(rv)) goto done;
rv = copyRequest->Init(nsCopyMessagesType, aSupport, dstFolder,
isMove, listener, window, allowUndo);
if (NS_FAILED(rv))
goto done;
rv = NS_NewISupportsArray(getter_AddRefs(msgArray));
if (NS_FAILED(rv)) goto done;
rv = NS_NewISupportsArray(getter_AddRefs(msgArray));
if (NS_FAILED(rv))
goto done;
messages->Count(&cnt);
copySource = copyRequest->AddNewCopySource(srcFolder);
messages->Count(&cnt);
for (i=0; i<cnt; i++)
// duplicate the message array so we could sort the messages by it's
// folder easily
for (i=0; i<cnt; i++)
{
aSupport = getter_AddRefs(messages->ElementAt(i));
msgArray->AppendElement(aSupport);
}
rv = msgArray->Count(&cnt);
if (NS_FAILED(rv))
goto done;
while (cnt-- > 0)
{
aSupport = getter_AddRefs(msgArray->ElementAt(cnt));
msg = do_QueryInterface(aSupport, &rv);
if (NS_FAILED(rv))
goto done;
rv = msg->GetFolder(getter_AddRefs(curFolder));
if (NS_FAILED(rv))
goto done;
if (!copySource)
{
aSupport = getter_AddRefs(messages->ElementAt(i));
msg = do_QueryInterface(aSupport, &rv);
copySource->AddMessage(msg);
copySource = copyRequest->AddNewCopySource(curFolder);
if (!copySource)
{
rv = NS_ERROR_OUT_OF_MEMORY;
goto done;
}
}
// undo stuff
if (NS_SUCCEEDED(rv) && copyRequest->m_allowUndo && copyRequest->m_copySourceArray.Count() > 1 &&
copyRequest->m_txnMgr)
copyRequest->m_txnMgr->BeginBatch();
if (curFolder == copySource->m_msgFolder)
{
copySource->AddMessage(msg);
msgArray->RemoveElementAt(cnt);
}
if (cnt == 0)
{
rv = msgArray->Count(&cnt);
if (cnt > 0)
copySource = nsnull; // * force to create a new one and
// * continue grouping the messages
}
}
// undo stuff
if (NS_SUCCEEDED(rv) && copyRequest->m_allowUndo && copyRequest->m_copySourceArray.Count() > 1 &&
copyRequest->m_txnMgr)
copyRequest->m_txnMgr->BeginBatch();
done:
if (NS_FAILED(rv))
delete copyRequest;
delete copyRequest;
else
rv = DoCopy(copyRequest);
rv = DoCopy(copyRequest);
msgArray->Clear();

Просмотреть файл

@ -1774,7 +1774,7 @@ NS_IMETHODIMP nsMsgDBView::GetURIsForSelection(char ***uris, PRUint32 *length)
for (PRUint32 i=0;i<numIndicies;i++)
{
nsMsgViewIndex selectedIndex = selection.GetAt(i);
if (!folder)
if (!m_folder) // must be a cross folder view, like search results
GetFolderForViewIndex(selectedIndex, getter_AddRefs(folder));
rv = GenerateURIForMsgKey(m_keys[selectedIndex], folder, next);
NS_ENSURE_SUCCESS(rv,rv);

Просмотреть файл

@ -167,9 +167,21 @@ nsMsgSearchDBView::OnSearchHit(nsIMsgDBHdr* aMsgHdr, nsIMsgFolder *folder)
{
NS_ENSURE_ARG(aMsgHdr);
NS_ENSURE_ARG(folder);
nsresult rv = NS_OK;
nsCOMPtr <nsISupports> supports = do_QueryInterface(folder);
if (m_folders->IndexOf(supports) < 0 ) //do this just for new folder
{
nsCOMPtr<nsIMsgDatabase> dbToUse;
nsCOMPtr<nsIDBFolderInfo> folderInfo;
folder->GetDBFolderInfoAndDB(getter_AddRefs(folderInfo), getter_AddRefs(dbToUse));
if (dbToUse)
{
dbToUse->AddListener(this);
nsCOMPtr <nsISupports> dbSupports = do_QueryInterface(dbToUse);
m_dbToUseList->AppendElement(dbSupports);
}
}
m_folders->AppendElement(supports);
nsMsgKey msgKey;
PRUint32 msgFlags;
@ -183,7 +195,7 @@ nsMsgSearchDBView::OnSearchHit(nsIMsgDBHdr* aMsgHdr, nsIMsgFolder *folder)
if (mTree)
mTree->RowCountChanged(GetSize() - 1, 1);
return rv;
return NS_OK;
}
NS_IMETHODIMP
@ -207,6 +219,12 @@ nsMsgSearchDBView::OnNewSearch()
{
PRInt32 oldSize = GetSize();
PRUint32 count=0;
m_dbToUseList->Count(&count);
for(PRUint32 j = 0; j < count; j++)
((nsIMsgDatabase*)m_dbToUseList->ElementAt(j))->RemoveListener(this);
m_dbToUseList->Clear();
m_folders->Clear();
m_keys.RemoveAll();
m_levels.RemoveAll();
@ -286,13 +304,13 @@ nsMsgSearchDBView::InitializeGlobalsForDeleteAndFile(nsMsgViewIndex *indices, PR
nsresult rv = NS_OK;
mCurIndex = 0;
//initialize and clear from the last usage
if (!m_uniqueFolders)
if (!m_uniqueFoldersSelected)
{
m_uniqueFolders = do_CreateInstance(NS_SUPPORTSARRAY_CONTRACTID, &rv);
m_uniqueFoldersSelected = do_CreateInstance(NS_SUPPORTSARRAY_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
}
else
m_uniqueFolders->Clear();
m_uniqueFoldersSelected->Clear();
if (!m_hdrsForEachFolder)
{
@ -302,41 +320,20 @@ nsMsgSearchDBView::InitializeGlobalsForDeleteAndFile(nsMsgViewIndex *indices, PR
else
m_hdrsForEachFolder->Clear();
PRUint32 count=0;
rv = m_dbToUseList->Count(&count);
NS_ENSURE_SUCCESS(rv,rv);
for(PRUint32 j = 0; j < count; j++)
((nsIMsgDatabase*)m_dbToUseList->ElementAt(j))->RemoveListener(this);
m_dbToUseList->Clear();
//Build unique folder list based on headers selected by the user
for (nsMsgViewIndex i = 0; i < (nsMsgViewIndex) numIndices; i++)
{
nsCOMPtr <nsISupports> curSupports = getter_AddRefs(m_folders->ElementAt(indices[i]));
if ( m_uniqueFolders->IndexOf(curSupports) < 0)
{
m_uniqueFolders->AppendElement(curSupports);
nsCOMPtr<nsIMsgFolder> curFolder = do_QueryInterface(curSupports);
nsCOMPtr <nsIMsgDatabase> dbToUse;
if (curFolder)
{
nsCOMPtr <nsIDBFolderInfo> folderInfo;
rv = curFolder->GetDBFolderInfoAndDB(getter_AddRefs(folderInfo), getter_AddRefs(dbToUse));
NS_ENSURE_SUCCESS(rv,rv);
dbToUse->AddListener(this);
nsCOMPtr <nsISupports> tmpSupports = do_QueryInterface(dbToUse);
m_dbToUseList->AppendElement(tmpSupports);
}
}
if ( m_uniqueFoldersSelected->IndexOf(curSupports) < 0)
m_uniqueFoldersSelected->AppendElement(curSupports);
}
PRUint32 numFolders =0;
rv = m_uniqueFolders->Count(&numFolders); //group the headers selected by each folder
rv = m_uniqueFoldersSelected->Count(&numFolders); //group the headers selected by each folder
NS_ENSURE_SUCCESS(rv,rv);
for (PRUint32 folderIndex=0; folderIndex < numFolders; folderIndex++)
{
nsCOMPtr <nsISupports> curSupports = getter_AddRefs(m_uniqueFolders->ElementAt(folderIndex));
nsCOMPtr <nsISupports> curSupports = getter_AddRefs(m_uniqueFoldersSelected->ElementAt(folderIndex));
nsCOMPtr <nsIMsgFolder> curFolder = do_QueryInterface(curSupports, &rv);
nsCOMPtr <nsISupportsArray> msgHdrsForOneFolder;
NS_NewISupportsArray(getter_AddRefs(msgHdrsForOneFolder));
@ -398,7 +395,7 @@ nsMsgSearchDBView::OnStopCopy(nsresult aStatus)
{
mCurIndex++;
PRUint32 numFolders =0;
rv = m_uniqueFolders->Count(&numFolders);
rv = m_uniqueFoldersSelected->Count(&numFolders);
if ( mCurIndex < numFolders)
ProcessRequestsInOneFolder(mMsgWindow);
}
@ -412,7 +409,7 @@ nsresult nsMsgSearchDBView::ProcessRequestsInOneFolder(nsIMsgWindow *window)
{
nsresult rv = NS_OK;
nsCOMPtr <nsISupports> curSupports = getter_AddRefs(m_uniqueFolders->ElementAt(mCurIndex));
nsCOMPtr <nsISupports> curSupports = getter_AddRefs(m_uniqueFoldersSelected->ElementAt(mCurIndex));
NS_ASSERTION(curSupports, "curSupports is null");
nsCOMPtr<nsIMsgFolder> curFolder = do_QueryInterface(curSupports);
nsCOMPtr <nsISupports> msgSupports = getter_AddRefs(m_hdrsForEachFolder->ElementAt(mCurIndex));
@ -427,10 +424,14 @@ nsresult nsMsgSearchDBView::ProcessRequestsInOneFolder(nsIMsgWindow *window)
NS_ASSERTION(!(curFolder == mDestFolder), "The source folder and the destination folder are the same");
if (NS_SUCCEEDED(rv) && curFolder != mDestFolder)
{
if (mCommand == nsMsgViewCommandType::moveMessages)
mDestFolder->CopyMessages(curFolder, messageArray, PR_TRUE /* isMove */,window, this, PR_FALSE /*is_Folder*/, PR_FALSE /*allowUndo*/);
else if (mCommand == nsMsgViewCommandType::copyMessages)
mDestFolder->CopyMessages(curFolder, messageArray, PR_FALSE /* isMove */, window, this, PR_FALSE /*is_Folder*/, PR_FALSE /*allowUndo*/);
nsCOMPtr<nsIMsgCopyService> copyService = do_GetService(NS_MSGCOPYSERVICE_CONTRACTID, &rv);
if (NS_SUCCEEDED(rv))
{
if (mCommand == nsMsgViewCommandType::moveMessages)
copyService->CopyMessages(curFolder, messageArray, mDestFolder, PR_TRUE /* isMove */, this, window, PR_FALSE /*allowUndo*/);
else if (mCommand == nsMsgViewCommandType::copyMessages)
copyService->CopyMessages(curFolder, messageArray, mDestFolder, PR_FALSE /* isMove */, this, window, PR_FALSE /*allowUndo*/);
}
}
}
return rv;
@ -439,11 +440,11 @@ nsresult nsMsgSearchDBView::ProcessRequestsInOneFolder(nsIMsgWindow *window)
nsresult nsMsgSearchDBView::ProcessRequestsInAllFolders(nsIMsgWindow *window)
{
PRUint32 numFolders =0;
nsresult rv = m_uniqueFolders->Count(&numFolders);
nsresult rv = m_uniqueFoldersSelected->Count(&numFolders);
NS_ENSURE_SUCCESS(rv,rv);
for (PRUint32 folderIndex=0; folderIndex < numFolders; folderIndex++)
{
nsCOMPtr <nsISupports> curSupports = getter_AddRefs(m_uniqueFolders->ElementAt(folderIndex));
nsCOMPtr <nsISupports> curSupports = getter_AddRefs(m_uniqueFoldersSelected->ElementAt(folderIndex));
NS_ASSERTION (curSupports, "curSupports is null");
nsCOMPtr<nsIMsgFolder> curFolder = do_QueryInterface(curSupports);

Просмотреть файл

@ -78,7 +78,7 @@ protected:
nsCOMPtr <nsISupportsArray> m_folders; // maybe we should store ranges, or the actual headers instead.
nsCOMPtr <nsISupportsArray> m_hdrsForEachFolder;
nsCOMPtr <nsISupportsArray> m_copyListenerList;
nsCOMPtr <nsISupportsArray> m_uniqueFolders;
nsCOMPtr <nsISupportsArray> m_uniqueFoldersSelected;
PRInt32 mCurIndex;
nsMsgViewIndex* mIndicesForChainedDeleteAndFile;

Просмотреть файл

@ -316,9 +316,11 @@ nsMsgCopy::DoCopy(nsIFileSpec *aDiskFile, nsIMsgFolder *dstFolder,
// ** make sure we have a valid copy listener while waiting for copy
// server to finish
nsCOMPtr<CopyListener> aCopyListener = do_QueryInterface(tPtr);
nsCOMPtr<nsIMsgCopyService> copyService = do_GetService(NS_MSGCOPYSERVICE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
rv = dstFolder->CopyFileMessage(aDiskFile, aMsgToReplace,
aIsDraft, msgWindow, mCopyListener);
rv = copyService->CopyFileMessage(aDiskFile, dstFolder, aMsgToReplace,
aIsDraft, mCopyListener, msgWindow);
// aCopyListener->mCopyInProgress can only be set when we are in the
// middle of the shutdown process
while (aCopyListener->mCopyInProgress)

Просмотреть файл

@ -4235,13 +4235,11 @@ nsImapMailFolder::OnStopRunningUrl(nsIURI *aUrl, nsresult aExitCode)
{
NS_PRECONDITION(aUrl, "just a sanity check since this is a test program");
nsresult rv = NS_OK;
PRBool sendEndCopyNotification = PR_FALSE;
m_urlRunning = PR_FALSE;
m_downloadingFolderForOfflineUse = PR_FALSE;
nsCOMPtr<nsIMsgMailSession> session =
do_GetService(NS_MSGMAILSESSION_CONTRACTID, &rv);
nsCOMPtr <nsIMsgCopyServiceListener> listener;
do_GetService(NS_MSGMAILSESSION_CONTRACTID, &rv);
if (aUrl)
{
nsCOMPtr<nsIMsgWindow> msgWindow;
@ -4329,10 +4327,7 @@ nsImapMailFolder::OnStopRunningUrl(nsIURI *aUrl, nsresult aExitCode)
if (txnMgr)
txnMgr->DoTransaction(m_copyState->m_undoMsgTxn);
}
if (m_copyState->m_listener)
listener = do_QueryInterface(m_copyState->m_listener);
ClearCopyState(aExitCode);
sendEndCopyNotification = PR_TRUE;
OnCopyCompleted(aExitCode);
}
// we're the dest folder of a move/copy - if we're not open in the ui,
// then we should clear our nsMsgDatabase pointer. Otherwise, the db would
@ -4417,20 +4412,12 @@ nsImapMailFolder::OnStopRunningUrl(nsIURI *aUrl, nsresult aExitCode)
if (txnMgr)
txnMgr->DoTransaction(m_copyState->m_undoMsgTxn);
}
if (m_copyState->m_listener)
listener = do_QueryInterface(m_copyState->m_listener);
ClearCopyState(aExitCode);
sendEndCopyNotification = PR_TRUE;
OnCopyCompleted(aExitCode);
}
}
else
{ //clear the copyState if copy has failed
if (m_copyState->m_listener)
listener = do_QueryInterface(m_copyState->m_listener);
ClearCopyState(aExitCode);
sendEndCopyNotification = PR_TRUE;
}
//clear the copyState if copy has failed
OnCopyCompleted(aExitCode);
}
break;
case nsIImapUrl::nsImapRenameFolder:
@ -4516,11 +4503,6 @@ nsImapMailFolder::OnStopRunningUrl(nsIURI *aUrl, nsresult aExitCode)
}
SetGettingNewMessages(PR_FALSE); // if we're not running a url, we must not be getting new mail :-)
// Only send the OnStopCopy notification if we have no copy state (which means we're doing an online
// move/copy, and have cleared the copy state above) or if we've finished the move/copy
// of multiple imap messages, one msg at a time (i.e., moving to a local folder).
if (listener && sendEndCopyNotification)
listener->OnStopCopy(aExitCode);
if (m_urlListener)
{
m_urlListener->OnStopRunningUrl(aUrl, aExitCode);
@ -5702,7 +5684,7 @@ nsImapMailFolder::CopyMessagesWithStream(nsIMsgFolder* srcFolder,
if (NS_SUCCEEDED(rv))
CopyStreamMessage(aMessage, this, msgWindow, isMove);
else
ClearCopyState(rv);
OnCopyCompleted(rv);
}
else
{
@ -6240,7 +6222,7 @@ nsImapMailFolder::CopyMessages(nsIMsgFolder* srcFolder,
else
{
NS_ASSERTION(PR_FALSE, "online copy failed");
ClearCopyState(rv);
OnCopyCompleted(rv);
}
done:
@ -6344,7 +6326,7 @@ nsImapMailFolder::CopyFileMessage(nsIFileSpec* fileSpec,
copySupport,
msgWindow);
if (NS_FAILED(rv))
ClearCopyState(rv);
OnCopyCompleted(rv);
return rv;
}
@ -6477,7 +6459,7 @@ nsImapMailFolder::InitCopyState(nsISupports* srcSupport,
}
void
nsImapMailFolder::ClearCopyState(nsresult rv)
nsImapMailFolder::OnCopyCompleted(nsresult rv)
{
if (m_copyState)
{

Просмотреть файл

@ -409,7 +409,7 @@ protected:
nsIMsgCopyServiceListener* listener,
nsIMsgWindow *msgWindow,
PRBool allowUndo);
void ClearCopyState(nsresult exitCode);
void OnCopyCompleted(nsresult exitCode);
nsresult BuildIdsAndKeyArray(nsISupportsArray* messages,
nsCString& msgIds, nsMsgKeyArray& keyArray);

Просмотреть файл

@ -1678,17 +1678,21 @@ nsMsgLocalMailFolder::InitCopyState(nsISupports* aSupport,
done:
if (NS_FAILED(rv))
ClearCopyState(PR_FALSE);
OnCopyCompleted(PR_FALSE);
return rv;
}
void
nsMsgLocalMailFolder::ClearCopyState(PRBool moveCopySucceeded)
nsMsgLocalMailFolder::OnCopyCompleted(PRBool moveCopySucceeded)
{
nsCOMPtr<nsISupports> srcSupport;
if (mCopyState)
{
srcSupport = mCopyState->m_srcSupport;
delete mCopyState;
mCopyState = nsnull;
mCopyState = nsnull;
}
// we are the destination folder for a move/copy
if (moveCopySucceeded && mDatabase)
@ -1713,6 +1717,12 @@ nsMsgLocalMailFolder::ClearCopyState(PRBool moveCopySucceeded)
&haveSemaphore);
if(NS_SUCCEEDED(result) && haveSemaphore)
ReleaseSemaphore(NS_STATIC_CAST(nsIMsgLocalMailFolder*, this));
nsCOMPtr<nsIMsgCopyService> copyService =
do_GetService(NS_MSGCOPYSERVICE_CONTRACTID, &result);
if (NS_SUCCEEDED(result)) //copyService will do listener->OnStopCopy()
copyService->NotifyCompletion(srcSupport, this, moveCopySucceeded ? NS_OK : NS_ERROR_FAILURE);
}
nsresult
@ -1827,7 +1837,7 @@ nsMsgLocalMailFolder::CopyMessages(nsIMsgFolder* srcFolder, nsISupportsArray*
if (NS_FAILED(rv))
{
ClearCopyState(PR_FALSE);
OnCopyCompleted(PR_FALSE);
}
else
{
@ -1862,7 +1872,7 @@ nsMsgLocalMailFolder::CopyMessages(nsIMsgFolder* srcFolder, nsISupportsArray*
if (NS_FAILED(rv))
{
NS_ASSERTION(PR_FALSE, "copy message failed");
ClearCopyState(PR_FALSE);
OnCopyCompleted(PR_FALSE);
}
}
}
@ -2174,7 +2184,7 @@ nsMsgLocalMailFolder::CopyFileMessage(nsIFileSpec* fileSpec, nsIMsgDBHdr*
done:
if(NS_FAILED(rv))
{
ClearCopyState(PR_FALSE);
OnCopyCompleted(PR_FALSE);
}
fileSpec->CloseStream();
@ -2482,7 +2492,7 @@ NS_IMETHODIMP nsMsgLocalMailFolder::EndCopy(PRBool copySucceeded)
hdrs in place. The message that has failed has been truncated so the msf file and berkeley mailbox
are in sync*/
ClearCopyState(PR_TRUE);
OnCopyCompleted(PR_TRUE);
// enable the dest folder
EnableNotifications(allMessageCountNotifications, PR_TRUE, PR_FALSE /*dbBatching*/); //dest folder doesn't need db batching
@ -2609,9 +2619,6 @@ NS_IMETHODIMP nsMsgLocalMailFolder::EndCopy(PRBool copySucceeded)
if (mCopyState->m_isFolder)
DoNextSubFolder(srcFolder, nsnull, nsnull); //Copy all subfolders then notify completion
nsCOMPtr<nsIMsgCopyService> copyService =
do_GetService(kMsgCopyServiceCID, &result);
if (mCopyState->m_msgWindow && mCopyState->m_undoMsgTxn)
{
nsCOMPtr<nsITransactionManager> txnMgr;
@ -2622,20 +2629,8 @@ NS_IMETHODIMP nsMsgLocalMailFolder::EndCopy(PRBool copySucceeded)
if (srcFolder && !mCopyState->m_isFolder)
srcFolder->NotifyFolderEvent(mDeleteOrMoveMsgCompletedAtom);
nsCOMPtr<nsISupports> srcSupport = do_QueryInterface(mCopyState->m_srcSupport);
nsCOMPtr<nsIMsgCopyServiceListener> listener =do_QueryInterface(mCopyState->m_listener);
if (!mCopyState->m_copyingMultipleMessages || multipleCopiesFinished)
ClearCopyState(PR_TRUE);
if (listener) //notify after clearing the copy state;
listener->OnStopCopy(NS_OK);
// OnStopCopy() should be called only once (listener is null when drag and drop msgs).
else if (NS_SUCCEEDED(result))
copyService->NotifyCompletion(srcSupport, this, rv);
}
OnCopyCompleted(PR_TRUE);
}
// enable the dest folder
EnableNotifications(allMessageCountNotifications, PR_TRUE, PR_FALSE /*dbBatching*/); //dest folder doesn't need db batching
}
@ -2659,7 +2654,7 @@ NS_IMETHODIMP nsMsgLocalMailFolder::EndMove(PRBool moveSucceeded)
hdrs in place. The message that has failed has been truncated so the msf file and berkeley mailbox
are in sync*/
ClearCopyState(PR_TRUE);
OnCopyCompleted(PR_TRUE);
// enable the dest folder
EnableNotifications(allMessageCountNotifications, PR_TRUE, PR_FALSE /*dbBatching*/ ); //dest folder doesn't need db batching
@ -2670,40 +2665,28 @@ NS_IMETHODIMP nsMsgLocalMailFolder::EndMove(PRBool moveSucceeded)
if (mCopyState && mCopyState->m_curCopyIndex >= mCopyState->m_totalMsgCount)
{
nsCOMPtr <nsIMsgCopyService> copyService = do_GetService(NS_MSGCOPYSERVICE_CONTRACTID, &result);
if (copyService && NS_SUCCEEDED(result))
//Notify that a completion finished.
nsCOMPtr<nsIMsgFolder> srcFolder = do_QueryInterface(mCopyState->m_srcSupport);
if(srcFolder)
{
//Notify that a completion finished.
nsCOMPtr<nsIMsgFolder> srcFolder = do_QueryInterface(mCopyState->m_srcSupport);
if(srcFolder)
{
// lets delete these all at once - much faster that way
result = srcFolder->DeleteMessages(mCopyState->m_messages, nsnull, PR_TRUE, PR_TRUE, nsnull, mCopyState->m_allowUndo);
srcFolder->NotifyFolderEvent(mDeleteOrMoveMsgCompletedAtom);
}
// enable the dest folder
EnableNotifications(allMessageCountNotifications, PR_TRUE, PR_FALSE /*dbBatching*/); //dest folder doesn't need db batching
if (mCopyState->m_msgWindow && mCopyState->m_undoMsgTxn)
{
nsCOMPtr<nsITransactionManager> txnMgr;
mCopyState->m_msgWindow->GetTransactionManager(getter_AddRefs(txnMgr));
if (txnMgr)
txnMgr->DoTransaction(mCopyState->m_undoMsgTxn);
}
nsCOMPtr<nsISupports> srcSupport = do_QueryInterface(mCopyState->m_srcSupport);
nsCOMPtr<nsIMsgCopyServiceListener> listener =do_QueryInterface(mCopyState->m_listener);
ClearCopyState(PR_TRUE); //clear the copy state so that the next message from a different folder can be moved
if (listener) //notify after clearing the copy state;
listener->OnStopCopy(NS_OK);
// ### we don't know if it succeeded
//passing in NS_OK because we only get in here if copy portion succeeded
copyService->NotifyCompletion(srcSupport, this, NS_OK);
// lets delete these all at once - much faster that way
result = srcFolder->DeleteMessages(mCopyState->m_messages, nsnull, PR_TRUE, PR_TRUE, nsnull, mCopyState->m_allowUndo);
srcFolder->NotifyFolderEvent(mDeleteOrMoveMsgCompletedAtom);
}
// enable the dest folder
EnableNotifications(allMessageCountNotifications, PR_TRUE, PR_FALSE /*dbBatching*/); //dest folder doesn't need db batching
if (mCopyState->m_msgWindow && mCopyState->m_undoMsgTxn)
{
nsCOMPtr<nsITransactionManager> txnMgr;
mCopyState->m_msgWindow->GetTransactionManager(getter_AddRefs(txnMgr));
if (txnMgr)
txnMgr->DoTransaction(mCopyState->m_undoMsgTxn);
}
nsCOMPtr<nsISupports> srcSupport = do_QueryInterface(mCopyState->m_srcSupport);
OnCopyCompleted(PR_TRUE); //clear the copy state so that the next message from a different folder can be move
}
return NS_OK;

Просмотреть файл

@ -207,7 +207,7 @@ protected:
virtual const char* GetIncomingServerType();
nsresult InitCopyState(nsISupports* aSupport, nsISupportsArray* messages,
PRBool isMove, nsIMsgCopyServiceListener* listener, nsIMsgWindow *msgWindow, PRBool isMoveFolder, PRBool allowUndo);
void ClearCopyState(PRBool moveCopySucceeded);
void OnCopyCompleted(PRBool moveCopySucceeded);
virtual nsresult CreateBaseMessageURI(const char *aURI);
protected:
PRBool mHaveReadNameFromDB;