fix playback of offline moves, removes duplicate, bogus header sr=sspitzer 78520 also white space fixes

This commit is contained in:
bienvenu%netscape.com 2001-05-05 02:43:58 +00:00
Родитель 6165949c20
Коммит e044966ea3
2 изменённых файлов: 400 добавлений и 402 удалений

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

@ -4680,45 +4680,45 @@ nsresult nsImapMailFolder::CopyMessagesOffline(nsIMsgFolder* srcFolder,
imapServer->GetDeleteModel(&deleteModel);
deleteToTrash = (deleteModel == nsMsgImapDeleteModels::MoveToTrash);
}
if (sourceMailDB)
{
if (sourceMailDB)
{
#ifdef DOING_OFFLINEUNDO_YET
UndoManager *undoManager = NULL;
if (state && state->sourcePane)
undoManager = state->sourcePane->GetUndoManager();
PRBool shouldUndoOffline = undoManager && NET_IsOffline();
if (shouldUndoOffline)
undoManager->StartBatch();
UndoManager *undoManager = NULL;
if (state && state->sourcePane)
undoManager = state->sourcePane->GetUndoManager();
PRBool shouldUndoOffline = undoManager && NET_IsOffline();
if (shouldUndoOffline)
undoManager->StartBatch();
#endif
// save the future ops in the source DB, if this is not a imap->local copy/move
// save the future ops in the source DB, if this is not a imap->local copy/move
GetDatabase(nsnull);
if (mDatabase)
{
// get the highest key in the dest db, so we can make up our fake keys
PRBool highWaterDeleted = PR_FALSE;
nsMsgKey fakeBase = 1;
if (mDatabase)
{
// get the highest key in the dest db, so we can make up our fake keys
PRBool highWaterDeleted = PR_FALSE;
nsMsgKey fakeBase = 1;
nsCOMPtr <nsIDBFolderInfo> folderInfo;
rv = mDatabase->GetDBFolderInfo(getter_AddRefs(folderInfo));
NS_ENSURE_SUCCESS(rv, rv);
nsMsgKey highWaterMark = nsMsgKey_None;
folderInfo->GetHighWater(&highWaterMark);
fakeBase += highWaterMark;
// put fake message in destination db, delete source if move
for (PRUint32 sourceKeyIndex=0; !stopit && (sourceKeyIndex < srcCount); sourceKeyIndex++)
{
PRBool messageReturningHome = PR_FALSE;
fakeBase += highWaterMark;
// put fake message in destination db, delete source if move
for (PRUint32 sourceKeyIndex=0; !stopit && (sourceKeyIndex < srcCount); sourceKeyIndex++)
{
PRBool messageReturningHome = PR_FALSE;
nsXPIDLCString sourceFolderURI;
srcFolder->GetURI(getter_Copies(sourceFolderURI));
nsXPIDLCString originalSrcFolderURI;
originalSrcFolderURI = sourceFolderURI.get();
nsCOMPtr<nsISupports> msgSupports;
nsCOMPtr<nsIMsgDBHdr> message;
msgSupports = getter_AddRefs(messages->ElementAt(sourceKeyIndex));
message = do_QueryInterface(msgSupports);
nsMsgKey originalKey;
@ -4731,174 +4731,174 @@ nsresult nsImapMailFolder::CopyMessagesOffline(nsIMsgFolder* srcFolder,
NS_ASSERTION(PR_FALSE, "bad msg in src array");
continue;
}
nsCOMPtr <nsIMsgOfflineImapOperation> sourceOp;
nsCOMPtr <nsIMsgOfflineImapOperation> sourceOp;
rv = sourceMailDB->GetOfflineOpForKey(originalKey, PR_TRUE, getter_AddRefs(sourceOp));
if (NS_SUCCEEDED(rv) && sourceOp)
{
if (NS_SUCCEEDED(rv) && sourceOp)
{
srcFolder->SetFlag(MSG_FOLDER_FLAG_OFFLINEEVENTS);
nsCOMPtr <nsIMsgDatabase> originalDB;
nsCOMPtr <nsIMsgDatabase> originalDB;
nsOfflineImapOperationType opType;
sourceOp->GetOperation(&opType);
// if we already have an offline op for this key, then we need to see if it was
// moved into the source folder while offline
if (opType == nsIMsgOfflineImapOperation::kMoveResult) // offline move
{
// gracious me, we are moving something we already moved while offline!
// find the original operation and clear it!
nsCOMPtr <nsIMsgOfflineImapOperation> originalOp;
{
// gracious me, we are moving something we already moved while offline!
// find the original operation and clear it!
nsCOMPtr <nsIMsgOfflineImapOperation> originalOp;
rv = GetClearedOriginalOp(sourceOp, getter_AddRefs(originalOp), getter_AddRefs(originalDB));
if (originalOp)
{
nsXPIDLCString originalString;
if (originalOp)
{
nsXPIDLCString originalString;
nsXPIDLCString srcFolderURI;
srcFolder->GetURI(getter_Copies(srcFolderURI));
sourceOp->GetSourceFolderURI(getter_Copies(originalString));
sourceOp->GetSourceFolderURI(getter_Copies(originalString));
sourceOp->GetMessageKey(&originalKey);
originalSrcFolderURI = originalString.get();
if (isMove)
sourceMailDB->RemoveOfflineOp(sourceOp);
sourceOp = originalOp;
sourceMailDB->RemoveOfflineOp(sourceOp);
sourceOp = originalOp;
if (!nsCRT::strcmp(originalSrcFolderURI, srcFolderURI))
{
messageReturningHome = PR_TRUE;
{
messageReturningHome = PR_TRUE;
originalDB->RemoveOfflineOp(originalOp);
}
}
}
if (!messageReturningHome)
{
}
}
}
if (!messageReturningHome)
{
nsXPIDLCString folderURI;
GetURI(getter_Copies(folderURI));
if (isMove)
{
sourceOp->SetDestinationFolderURI(folderURI); // offline move
GetURI(getter_Copies(folderURI));
if (isMove)
{
sourceOp->SetDestinationFolderURI(folderURI); // offline move
sourceOp->SetOperation(nsIMsgOfflineImapOperation::kMsgMoved);
}
else
sourceOp->AddMessageCopyOperation(folderURI); // offline copy
}
else
sourceOp->AddMessageCopyOperation(folderURI); // offline copy
#ifdef DOING_OFFLINEUNDO_YET
if (shouldUndoOffline && undoManager->GetState() == UndoIdle)
{ // only need undo if we're really offline and not pseudo offline
OfflineIMAPUndoAction *undoAction = new
OfflineIMAPUndoAction(state->sourcePane, (MSG_FolderInfo*) this, sourceOp->GetMessageKey(), opType,
sourceMailDB->GetFolderInfo(), dstFolder, 0, NULL, 0);
if (undoAction)
undoManager->AddUndoAction(undoAction);
}
if (shouldUndoOffline && undoManager->GetState() == UndoIdle)
{ // only need undo if we're really offline and not pseudo offline
OfflineIMAPUndoAction *undoAction = new
OfflineIMAPUndoAction(state->sourcePane, (MSG_FolderInfo*) this, sourceOp->GetMessageKey(), opType,
sourceMailDB->GetFolderInfo(), dstFolder, 0, NULL, 0);
if (undoAction)
undoManager->AddUndoAction(undoAction);
}
#endif
}
}
else
stopit = NS_ERROR_FAILURE;
nsCOMPtr <nsIMsgDBHdr> mailHdr;
}
}
else
stopit = NS_ERROR_FAILURE;
nsCOMPtr <nsIMsgDBHdr> mailHdr;
rv = sourceMailDB->GetMsgHdrForKey(originalKey, getter_AddRefs(mailHdr));
if (NS_SUCCEEDED(rv) && mailHdr)
{
PRBool successfulCopy = PR_FALSE;
if (NS_SUCCEEDED(rv) && mailHdr)
{
PRBool successfulCopy = PR_FALSE;
nsMsgKey srcDBhighWaterMark;
srcDbFolderInfo->GetHighWater(&srcDBhighWaterMark);
highWaterDeleted = !highWaterDeleted && isMove && deleteToTrash &&
(originalKey == srcDBhighWaterMark);
nsCOMPtr <nsIMsgDBHdr> newMailHdr;
rv = mDatabase->CopyHdrFromExistingHdr(fakeBase + sourceKeyIndex, mailHdr,
PR_TRUE, getter_AddRefs(newMailHdr));
highWaterDeleted = !highWaterDeleted && isMove && deleteToTrash &&
(originalKey == srcDBhighWaterMark);
nsCOMPtr <nsIMsgDBHdr> newMailHdr;
rv = mDatabase->CopyHdrFromExistingHdr(fakeBase + sourceKeyIndex, mailHdr,
PR_TRUE, getter_AddRefs(newMailHdr));
if (!newMailHdr || !NS_SUCCEEDED(rv))
{
NS_ASSERTION(PR_FALSE, "failed to copy hdr");
stopit = rv;
}
if (NS_SUCCEEDED(stopit))
{
nsCOMPtr <nsIMsgOfflineImapOperation> destOp;
mDatabase->GetOfflineOpForKey(fakeBase + sourceKeyIndex, PR_TRUE, getter_AddRefs(destOp));
if (destOp)
{
// check if this is a move back to the original mailbox, in which case
// we just delete the offline operation.
if (messageReturningHome)
{
mDatabase->RemoveOfflineOp(destOp);
}
else
{
if (NS_SUCCEEDED(stopit))
{
nsCOMPtr <nsIMsgOfflineImapOperation> destOp;
mDatabase->GetOfflineOpForKey(fakeBase + sourceKeyIndex, PR_TRUE, getter_AddRefs(destOp));
if (destOp)
{
// check if this is a move back to the original mailbox, in which case
// we just delete the offline operation.
if (messageReturningHome)
{
mDatabase->RemoveOfflineOp(destOp);
}
else
{
SetFlag(MSG_FOLDER_FLAG_OFFLINEEVENTS);
destOp->SetSourceFolderURI(originalSrcFolderURI);
destOp->SetSourceFolderURI(originalSrcFolderURI);
destOp->SetMessageKey(originalKey);
#ifdef DOING_OFFLINEUNDO_YET
if (shouldUndoOffline && undoManager->GetState() == UndoIdle)
{
OfflineIMAPUndoAction *undoAction = new
OfflineIMAPUndoAction(state->sourcePane, (MSG_FolderInfo*) this, destOp->GetMessageKey(), kAddedHeader,
state->destDB->GetFolderInfo(), dstFolder, 0, newMailHdr);
if (undoAction)
undoManager->AddUndoAction(undoAction);
}
if (shouldUndoOffline && undoManager->GetState() == UndoIdle)
{
OfflineIMAPUndoAction *undoAction = new
OfflineIMAPUndoAction(state->sourcePane, (MSG_FolderInfo*) this, destOp->GetMessageKey(), kAddedHeader,
state->destDB->GetFolderInfo(), dstFolder, 0, newMailHdr);
if (undoAction)
undoManager->AddUndoAction(undoAction);
}
#endif
}
}
else
stopit = NS_ERROR_FAILURE;
}
successfulCopy = NS_SUCCEEDED(stopit);
if (isMove && successfulCopy)
{
nsOfflineImapOperationType opType = nsIMsgOfflineImapOperation::kDeletedMsg;
if (!deleteToTrash)
opType = nsIMsgOfflineImapOperation::kMsgMarkedDeleted;
}
}
else
stopit = NS_ERROR_FAILURE;
}
successfulCopy = NS_SUCCEEDED(stopit);
if (isMove && successfulCopy)
{
nsOfflineImapOperationType opType = nsIMsgOfflineImapOperation::kDeletedMsg;
if (!deleteToTrash)
opType = nsIMsgOfflineImapOperation::kMsgMarkedDeleted;
#ifdef DOING_OFFLINEUNDO_YET
if (shouldUndoOffline && undoManager->GetState() == UndoIdle)
if (shouldUndoOffline && undoManager->GetState() == UndoIdle)
{
OfflineIMAPUndoAction *undoAction = new
OfflineIMAPUndoAction(state->sourcePane, (MSG_FolderInfo*) this, mailHdr->GetMessageKey(), opType,
sourceMailDB->GetFolderInfo(), dstFolder, 0, mailHdr);
if (undoAction)
undoManager->AddUndoAction(undoAction);
}
OfflineIMAPUndoAction *undoAction = new
OfflineIMAPUndoAction(state->sourcePane, (MSG_FolderInfo*) this, mailHdr->GetMessageKey(), opType,
sourceMailDB->GetFolderInfo(), dstFolder, 0, mailHdr);
if (undoAction)
undoManager->AddUndoAction(undoAction);
}
#endif
nsMsgKey msgKey;
mailHdr->GetMessageKey(&msgKey);
if (deleteToTrash)
sourceMailDB->DeleteMessage(msgKey, nsnull, PR_FALSE);
else
sourceMailDB->MarkImapDeleted(msgKey,PR_TRUE,nsnull); // offline delete
}
if (!successfulCopy)
highWaterDeleted = PR_FALSE;
}
}
if (deleteToTrash)
sourceMailDB->DeleteMessage(msgKey, nsnull, PR_FALSE);
else
sourceMailDB->MarkImapDeleted(msgKey,PR_TRUE,nsnull); // offline delete
}
if (!successfulCopy)
highWaterDeleted = PR_FALSE;
}
}
PRInt32 numVisibleMessages;
srcDbFolderInfo->GetNumVisibleMessages(&numVisibleMessages);
if (numVisibleMessages && highWaterDeleted)
{
// ListContext *listContext = nsnull;
// nsCOMPtr <nsIMsgDBHdr> highHdr;
// if (sourceMailDB->ListLast(&listContext, &highHdr) == NS_OK)
// {
// sourceMailDB->m_neoFolderInfo->m_LastMessageUID = highHdr->GetMessageKey();
// sourceMailDB->ListDone(listContext);
// }
}
if (isMove)
sourceMailDB->Commit(nsMsgDBCommitType::kLargeCommit);
// ListContext *listContext = nsnull;
// nsCOMPtr <nsIMsgDBHdr> highHdr;
// if (sourceMailDB->ListLast(&listContext, &highHdr) == NS_OK)
// {
// sourceMailDB->m_neoFolderInfo->m_LastMessageUID = highHdr->GetMessageKey();
// sourceMailDB->ListDone(listContext);
// }
}
if (isMove)
sourceMailDB->Commit(nsMsgDBCommitType::kLargeCommit);
mDatabase->Commit(nsMsgDBCommitType::kLargeCommit);
SummaryChanged();
srcFolder->SummaryChanged();
}
}
#ifdef DOING_OFFLINEUNDO_YET
if (shouldUndoOffline)

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

@ -30,7 +30,7 @@
#include "nsRDFCID.h"
#include "nsIMsgAccountManager.h"
#include "nsINntpIncomingServer.h"
// #include "nsIStreamObserver.h"
#include "nsIRequestObserver.h"
static NS_DEFINE_CID(kMsgAccountManagerCID, NS_MSGACCOUNTMANAGER_CID);
static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
@ -78,9 +78,8 @@ nsImapOfflineSync::OnStopRunningUrl(nsIURI* url, nsresult exitCode)
PRBool stopped = PR_FALSE;
if (m_window)
m_window->GetStopped(&stopped);
// if (stopped)
// exitCode = NS_BINDING_ABORTED;
if (stopped)
exitCode = NS_BINDING_ABORTED;
if (NS_SUCCEEDED(exitCode))
rv = ProcessNextOperation();
@ -492,7 +491,6 @@ PRBool nsImapOfflineSync::CreateOfflineFolder(nsIMsgFolder *folder)
PRInt32 nsImapOfflineSync::GetCurrentUIDValidity()
{
PRUint32 uidValidity;
uid_validity_info uidStruct;
if (m_currentFolder)
@ -515,296 +513,296 @@ PRInt32 nsImapOfflineSync::GetCurrentUIDValidity()
nsresult nsImapOfflineSync::ProcessNextOperation()
{
nsresult rv;
// find a folder that needs to process operations
nsIMsgFolder *deletedAllOfflineEventsInFolder = nsnull;
// if we haven't created offline folders, and we're updating all folders,
// first, find offline folders to create.
if (!m_createdOfflineFolders)
{
if (m_singleFolderToUpdate)
{
if (!m_pseudoOffline)
{
AdvanceToFirstIMAPFolder();
if (CreateOfflineFolders())
return NS_OK;
}
}
else
{
if (CreateOfflineFolders())
return NS_OK;
AdvanceToFirstIMAPFolder();
}
m_createdOfflineFolders = PR_TRUE;
}
// if updating one folder only, restore m_currentFolder to that folder
if (m_singleFolderToUpdate)
m_currentFolder = m_singleFolderToUpdate;
// find a folder that needs to process operations
nsIMsgFolder *deletedAllOfflineEventsInFolder = nsnull;
// if we haven't created offline folders, and we're updating all folders,
// first, find offline folders to create.
if (!m_createdOfflineFolders)
{
if (m_singleFolderToUpdate)
{
if (!m_pseudoOffline)
{
AdvanceToFirstIMAPFolder();
if (CreateOfflineFolders())
return NS_OK;
}
}
else
{
if (CreateOfflineFolders())
return NS_OK;
AdvanceToFirstIMAPFolder();
}
m_createdOfflineFolders = PR_TRUE;
}
// if updating one folder only, restore m_currentFolder to that folder
if (m_singleFolderToUpdate)
m_currentFolder = m_singleFolderToUpdate;
PRUint32 folderFlags;
nsCOMPtr <nsIDBFolderInfo> folderInfo;
while (m_currentFolder && !m_currentDB)
{
while (m_currentFolder && !m_currentDB)
{
m_currentFolder->GetFlags(&folderFlags);
// need to check if folder has offline events, or is configured for offline
if (folderFlags & (MSG_FOLDER_FLAG_OFFLINEEVENTS | MSG_FOLDER_FLAG_OFFLINE))
{
// need to check if folder has offline events, or is configured for offline
if (folderFlags & (MSG_FOLDER_FLAG_OFFLINEEVENTS | MSG_FOLDER_FLAG_OFFLINE))
{
m_currentFolder->GetDBFolderInfoAndDB(getter_AddRefs(folderInfo), getter_AddRefs(m_currentDB));
}
if (m_currentDB)
{
m_CurrentKeys.RemoveAll();
m_KeyIndex = 0;
if ((m_currentDB->ListAllOfflineOpIds(&m_CurrentKeys) != 0) || !m_CurrentKeys.GetSize())
{
m_currentDB = nsnull;
}
if (m_currentDB)
{
m_CurrentKeys.RemoveAll();
m_KeyIndex = 0;
if ((m_currentDB->ListAllOfflineOpIds(&m_CurrentKeys) != 0) || !m_CurrentKeys.GetSize())
{
m_currentDB = nsnull;
m_currentFolder->ClearFlag(MSG_FOLDER_FLAG_OFFLINEEVENTS);
}
else
{
// trash any ghost msgs
PRBool deletedGhostMsgs = PR_FALSE;
for (PRUint32 fakeIndex=0; fakeIndex < m_CurrentKeys.GetSize(); fakeIndex++)
{
nsCOMPtr <nsIMsgOfflineImapOperation> currentOp;
}
else
{
// trash any ghost msgs
PRBool deletedGhostMsgs = PR_FALSE;
for (PRUint32 fakeIndex=0; fakeIndex < m_CurrentKeys.GetSize(); fakeIndex++)
{
nsCOMPtr <nsIMsgOfflineImapOperation> currentOp;
m_currentDB->GetOfflineOpForKey(m_CurrentKeys[fakeIndex], PR_FALSE, getter_AddRefs(currentOp));
if (currentOp)
if (currentOp)
{
nsOfflineImapOperationType opType;
currentOp->GetOperation(&opType);
if (opType == nsIMsgOfflineImapOperation::kMoveResult)
{
m_currentDB->RemoveOfflineOp(currentOp);
deletedGhostMsgs = PR_TRUE;
nsCOMPtr <nsIMsgDBHdr> mailHdr;
{
nsMsgKey curKey;
currentOp->GetMessageKey(&curKey);
m_currentDB->RemoveOfflineOp(currentOp);
deletedGhostMsgs = PR_TRUE;
nsCOMPtr <nsIMsgDBHdr> mailHdr;
m_currentDB->DeleteMessage(curKey, nsnull, PR_FALSE);
}
}
}
}
if (deletedGhostMsgs)
m_currentFolder->SummaryChanged();
m_CurrentKeys.RemoveAll();
if ( (m_currentDB->ListAllOfflineOpIds(&m_CurrentKeys) != 0) || !m_CurrentKeys.GetSize() )
{
m_currentDB = nsnull;
if (deletedGhostMsgs)
deletedAllOfflineEventsInFolder = m_currentFolder;
}
else if (folderFlags & MSG_FOLDER_FLAG_IMAPBOX)
{
// if (imapFolder->GetHasOfflineEvents())
// XP_ASSERT(PR_FALSE);
if (!m_pseudoOffline) // if pseudo offline, falls through to playing ops back.
{
// there are operations to playback so check uid validity
SetCurrentUIDValidity(0); // force initial invalid state
}
if (deletedGhostMsgs)
m_currentFolder->SummaryChanged();
m_CurrentKeys.RemoveAll();
if ( (m_currentDB->ListAllOfflineOpIds(&m_CurrentKeys) != 0) || !m_CurrentKeys.GetSize() )
{
m_currentDB = nsnull;
if (deletedGhostMsgs)
deletedAllOfflineEventsInFolder = m_currentFolder;
}
else if (folderFlags & MSG_FOLDER_FLAG_IMAPBOX)
{
// if (imapFolder->GetHasOfflineEvents())
// XP_ASSERT(PR_FALSE);
if (!m_pseudoOffline) // if pseudo offline, falls through to playing ops back.
{
// there are operations to playback so check uid validity
SetCurrentUIDValidity(0); // force initial invalid state
// do a lite select here and hook ourselves up as a listener.
nsCOMPtr <nsIMsgImapMailFolder> imapFolder = do_QueryInterface(m_currentFolder, &rv);
if (imapFolder)
rv = imapFolder->LiteSelect(this);
return rv; // this is async, we have to return as be called again by the OnStopRunningUrl
}
}
}
}
if (!m_currentDB)
{
// only advance if we are doing all folders
if (!m_singleFolderToUpdate)
AdvanceToNextFolder();
else
m_currentFolder = nsnull; // force update of this folder now.
}
}
return rv; // this is async, we have to return as be called again by the OnStopRunningUrl
}
}
}
}
if (!m_currentDB)
{
// only advance if we are doing all folders
if (!m_singleFolderToUpdate)
AdvanceToNextFolder();
else
m_currentFolder = nsnull; // force update of this folder now.
}
}
if (m_currentFolder)
m_currentFolder->GetFlags(&folderFlags);
// do the current operation
if (m_currentDB)
{
PRBool currentFolderFinished = PR_FALSE;
// do the current operation
if (m_currentDB)
{
PRBool currentFolderFinished = PR_FALSE;
if (!folderInfo)
m_currentDB->GetDBFolderInfo(getter_AddRefs(folderInfo));
// user canceled the lite select! if GetCurrentUIDValidity() == 0
if ((m_KeyIndex < m_CurrentKeys.GetSize()) && (m_pseudoOffline || (GetCurrentUIDValidity() != 0) || !(folderFlags & MSG_FOLDER_FLAG_IMAPBOX)) )
{
// user canceled the lite select! if GetCurrentUIDValidity() == 0
if ((m_KeyIndex < m_CurrentKeys.GetSize()) && (m_pseudoOffline || (GetCurrentUIDValidity() != 0) || !(folderFlags & MSG_FOLDER_FLAG_IMAPBOX)) )
{
PRInt32 curFolderUidValidity;
folderInfo->GetImapUidValidity(&curFolderUidValidity);
PRBool uidvalidityChanged = (!m_pseudoOffline && folderFlags & MSG_FOLDER_FLAG_IMAPBOX) && (GetCurrentUIDValidity() != curFolderUidValidity);
nsIMsgOfflineImapOperation *currentOp = nsnull;
if (uidvalidityChanged)
DeleteAllOfflineOpsForCurrentDB();
else
m_currentDB->GetOfflineOpForKey(m_CurrentKeys[m_KeyIndex], PR_FALSE, &currentOp);
if (currentOp)
{
PRBool uidvalidityChanged = (!m_pseudoOffline && folderFlags & MSG_FOLDER_FLAG_IMAPBOX) && (GetCurrentUIDValidity() != curFolderUidValidity);
nsIMsgOfflineImapOperation *currentOp = nsnull;
if (uidvalidityChanged)
DeleteAllOfflineOpsForCurrentDB();
else
m_currentDB->GetOfflineOpForKey(m_CurrentKeys[m_KeyIndex], PR_FALSE, &currentOp);
if (currentOp)
{
nsOfflineImapOperationType opType;
if (currentOp)
currentOp->GetOperation(&opType);
// loop until we find the next db record that matches the current playback operation
while (currentOp && !(opType & mCurrentPlaybackOpType))
// loop until we find the next db record that matches the current playback operation
while (currentOp && !(opType & mCurrentPlaybackOpType))
{
currentOp = nsnull;
++m_KeyIndex;
if (m_KeyIndex < m_CurrentKeys.GetSize())
m_currentDB->GetOfflineOpForKey(m_CurrentKeys[m_KeyIndex], PR_FALSE, &currentOp);
if (m_KeyIndex < m_CurrentKeys.GetSize())
m_currentDB->GetOfflineOpForKey(m_CurrentKeys[m_KeyIndex], PR_FALSE, &currentOp);
if (currentOp)
currentOp->GetOperation(&opType);
}
// if we did not find a db record that matches the current playback operation,
// then move to the next playback operation and recurse.
if (!currentOp)
{
// we are done with the current type
if (mCurrentPlaybackOpType == nsIMsgOfflineImapOperation::kFlagsChanged)
{
mCurrentPlaybackOpType = nsIMsgOfflineImapOperation::kMsgCopy;
// recurse to deal with next type of operation
m_KeyIndex = 0;
ProcessNextOperation();
}
else if (mCurrentPlaybackOpType == nsIMsgOfflineImapOperation::kMsgCopy)
{
mCurrentPlaybackOpType = nsIMsgOfflineImapOperation::kMsgMoved;
// recurse to deal with next type of operation
m_KeyIndex = 0;
ProcessNextOperation();
}
else if (mCurrentPlaybackOpType == nsIMsgOfflineImapOperation::kMsgMoved)
{
mCurrentPlaybackOpType = nsIMsgOfflineImapOperation::kAppendDraft;
// recurse to deal with next type of operation
m_KeyIndex = 0;
ProcessNextOperation();
}
else if (mCurrentPlaybackOpType == nsIMsgOfflineImapOperation::kAppendDraft)
{
mCurrentPlaybackOpType = nsIMsgOfflineImapOperation::kAppendTemplate;
// recurse to deal with next type of operation
m_KeyIndex = 0;
ProcessNextOperation();
}
else if (mCurrentPlaybackOpType == nsIMsgOfflineImapOperation::kAppendTemplate)
{
mCurrentPlaybackOpType = nsIMsgOfflineImapOperation::kDeleteAllMsgs;
m_KeyIndex = 0;
ProcessNextOperation();
}
else
{
DeleteAllOfflineOpsForCurrentDB();
currentFolderFinished = PR_TRUE;
}
}
else
{
if (mCurrentPlaybackOpType == nsIMsgOfflineImapOperation::kFlagsChanged)
ProcessFlagOperation(currentOp);
else if (mCurrentPlaybackOpType == nsIMsgOfflineImapOperation::kMsgCopy)
ProcessCopyOperation(currentOp);
else if (mCurrentPlaybackOpType == nsIMsgOfflineImapOperation::kMsgMoved)
ProcessMoveOperation(currentOp);
else if (mCurrentPlaybackOpType == nsIMsgOfflineImapOperation::kAppendDraft)
ProcessAppendMsgOperation(currentOp, nsIMsgOfflineImapOperation::kAppendDraft);
else if (mCurrentPlaybackOpType == nsIMsgOfflineImapOperation::kAppendTemplate)
ProcessAppendMsgOperation(currentOp, nsIMsgOfflineImapOperation::kAppendTemplate);
else if (mCurrentPlaybackOpType == nsIMsgOfflineImapOperation::kDeleteAllMsgs)
ProcessEmptyTrash(currentOp);
else
NS_ASSERTION(PR_FALSE, "invalid playback op type");
// currentOp was unreferred by one of the Process functions
// so do not reference it again!
currentOp = nsnull;
}
}
else
currentFolderFinished = PR_TRUE;
}
else
currentFolderFinished = PR_TRUE;
if (currentFolderFinished)
{
m_currentDB = nsnull;
if (!m_singleFolderToUpdate)
{
AdvanceToNextFolder();
ProcessNextOperation();
return NS_OK;
}
else
m_currentFolder = nsnull;
}
}
if (!m_currentFolder && !m_mailboxupdatesStarted)
{
m_mailboxupdatesStarted = PR_TRUE;
// if we are updating more than one folder then we need the iterator
if (!m_singleFolderToUpdate)
AdvanceToFirstIMAPFolder();
// if we did not find a db record that matches the current playback operation,
// then move to the next playback operation and recurse.
if (!currentOp)
{
// we are done with the current type
if (mCurrentPlaybackOpType == nsIMsgOfflineImapOperation::kFlagsChanged)
{
mCurrentPlaybackOpType = nsIMsgOfflineImapOperation::kMsgCopy;
// recurse to deal with next type of operation
m_KeyIndex = 0;
ProcessNextOperation();
}
else if (mCurrentPlaybackOpType == nsIMsgOfflineImapOperation::kMsgCopy)
{
mCurrentPlaybackOpType = nsIMsgOfflineImapOperation::kMsgMoved;
// recurse to deal with next type of operation
m_KeyIndex = 0;
ProcessNextOperation();
}
else if (mCurrentPlaybackOpType == nsIMsgOfflineImapOperation::kMsgMoved)
{
mCurrentPlaybackOpType = nsIMsgOfflineImapOperation::kAppendDraft;
// recurse to deal with next type of operation
m_KeyIndex = 0;
ProcessNextOperation();
}
else if (mCurrentPlaybackOpType == nsIMsgOfflineImapOperation::kAppendDraft)
{
mCurrentPlaybackOpType = nsIMsgOfflineImapOperation::kAppendTemplate;
// recurse to deal with next type of operation
m_KeyIndex = 0;
ProcessNextOperation();
}
else if (mCurrentPlaybackOpType == nsIMsgOfflineImapOperation::kAppendTemplate)
{
mCurrentPlaybackOpType = nsIMsgOfflineImapOperation::kDeleteAllMsgs;
m_KeyIndex = 0;
ProcessNextOperation();
}
else
{
DeleteAllOfflineOpsForCurrentDB();
currentFolderFinished = PR_TRUE;
}
}
else
{
if (mCurrentPlaybackOpType == nsIMsgOfflineImapOperation::kFlagsChanged)
ProcessFlagOperation(currentOp);
else if (mCurrentPlaybackOpType == nsIMsgOfflineImapOperation::kMsgCopy)
ProcessCopyOperation(currentOp);
else if (mCurrentPlaybackOpType == nsIMsgOfflineImapOperation::kMsgMoved)
ProcessMoveOperation(currentOp);
else if (mCurrentPlaybackOpType == nsIMsgOfflineImapOperation::kAppendDraft)
ProcessAppendMsgOperation(currentOp, nsIMsgOfflineImapOperation::kAppendDraft);
else if (mCurrentPlaybackOpType == nsIMsgOfflineImapOperation::kAppendTemplate)
ProcessAppendMsgOperation(currentOp, nsIMsgOfflineImapOperation::kAppendTemplate);
else if (mCurrentPlaybackOpType == nsIMsgOfflineImapOperation::kDeleteAllMsgs)
ProcessEmptyTrash(currentOp);
else
NS_ASSERTION(PR_FALSE, "invalid playback op type");
// currentOp was unreferred by one of the Process functions
// so do not reference it again!
currentOp = nsnull;
}
}
else
currentFolderFinished = PR_TRUE;
}
else
currentFolderFinished = PR_TRUE;
if (currentFolderFinished)
{
m_currentDB = nsnull;
if (!m_singleFolderToUpdate)
{
AdvanceToNextFolder();
ProcessNextOperation();
return NS_OK;
}
else
m_currentFolder = nsnull;
}
}
if (!m_currentFolder && !m_mailboxupdatesStarted)
{
m_mailboxupdatesStarted = PR_TRUE;
// if we are updating more than one folder then we need the iterator
if (!m_singleFolderToUpdate)
AdvanceToFirstIMAPFolder();
if (m_singleFolderToUpdate)
{
m_singleFolderToUpdate->ClearFlag(MSG_FOLDER_FLAG_OFFLINEEVENTS);
m_singleFolderToUpdate->UpdateFolder(m_window);
m_singleFolderToUpdate->UpdateFolder(m_window);
// do we have to do anything? Old code would do a start update...
}
else
{
// this means that we are updating all of the folders. Update the INBOX first so the updates on the remaining
// folders pickup the results of any filter moves.
// nsIMsgFolder *inboxFolder;
if (!m_pseudoOffline )
{
NS_WITH_SERVICE(nsIMsgAccountManager, accountManager, kMsgAccountManagerCID, &rv);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsISupportsArray> servers;
rv = accountManager->GetAllServers(getter_AddRefs(servers));
if (NS_FAILED(rv)) return rv;
// this means that we are updating all of the folders. Update the INBOX first so the updates on the remaining
// folders pickup the results of any filter moves.
// nsIMsgFolder *inboxFolder;
if (!m_pseudoOffline )
{
NS_WITH_SERVICE(nsIMsgAccountManager, accountManager, kMsgAccountManagerCID, &rv);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsISupportsArray> servers;
rv = accountManager->GetAllServers(getter_AddRefs(servers));
if (NS_FAILED(rv)) return rv;
// ### for each imap server, call get new messages.
// get next folder...
// get next folder...
}
}
// MSG_FolderIterator *updateFolderIterator = m_singleFolderToUpdate ? (MSG_FolderIterator *) 0 : m_folderIterator;
// we are done playing commands back, now queue up the sync with each imap folder
// If we're using the iterator, m_currentFolder will be set correctly
// nsIMsgFolder * folder = m_singleFolderToUpdate ? m_singleFolderToUpdate : m_currentFolder;
// while (folder)
// {
// PRBool loadingFolder = m_workerPane->GetLoadingImapFolder() == folder;
// if ((folder->GetType() == FOLDER_IMAPMAIL) && (deletedAllOfflineEventsInFolder == folder || (folder->GetFolderPrefFlags() & MSG_FOLDER_FLAG_OFFLINE)
// || loadingFolder)
// && !(folder->GetFolderPrefFlags() & MSG_FOLDER_PREF_IMAPNOSELECT) )
// {
// PRBool lastChance = ((deletedAllOfflineEventsInFolder == folder) && m_singleFolderToUpdate) || loadingFolder;
// if deletedAllOfflineEventsInFolder == folder and we're only updating one folder, then we need to update newly selected folder
// I think this also means that we're really opening the folder...so we tell StartUpdate that we're loading a folder.
// if (!updateFolderIterator || !(imapMail->GetFlags() & MSG_FOLDER_FLAG_INBOX)) // avoid queueing the inbox twice
// imapMail->StartUpdateOfNewlySelectedFolder(m_workerPane, lastChance, queue, nsnsnull, PR_FALSE, PR_FALSE);
// }
// folder= m_singleFolderToUpdate ? (MSG_FolderInfo *)nsnull : updateFolderIterator->Next();
// }
}
// MSG_FolderIterator *updateFolderIterator = m_singleFolderToUpdate ? (MSG_FolderIterator *) 0 : m_folderIterator;
// we are done playing commands back, now queue up the sync with each imap folder
// If we're using the iterator, m_currentFolder will be set correctly
// nsIMsgFolder * folder = m_singleFolderToUpdate ? m_singleFolderToUpdate : m_currentFolder;
// while (folder)
// {
// PRBool loadingFolder = m_workerPane->GetLoadingImapFolder() == folder;
// if ((folder->GetType() == FOLDER_IMAPMAIL) && (deletedAllOfflineEventsInFolder == folder || (folder->GetFolderPrefFlags() & MSG_FOLDER_FLAG_OFFLINE)
// || loadingFolder)
// && !(folder->GetFolderPrefFlags() & MSG_FOLDER_PREF_IMAPNOSELECT) )
// {
// PRBool lastChance = ((deletedAllOfflineEventsInFolder == folder) && m_singleFolderToUpdate) || loadingFolder;
// if deletedAllOfflineEventsInFolder == folder and we're only updating one folder, then we need to update newly selected folder
// I think this also means that we're really opening the folder...so we tell StartUpdate that we're loading a folder.
// if (!updateFolderIterator || !(imapMail->GetFlags() & MSG_FOLDER_FLAG_INBOX)) // avoid queueing the inbox twice
// imapMail->StartUpdateOfNewlySelectedFolder(m_workerPane, lastChance, queue, nsnsnull, PR_FALSE, PR_FALSE);
// }
// folder= m_singleFolderToUpdate ? (MSG_FolderInfo *)nsnull : updateFolderIterator->Next();
// }
}
// if we get here, then I *think* we're done. Not sure, though.
#ifdef DEBUG_bienvenu
printf("done with offline imap sync\n");