зеркало из https://github.com/mozilla/gecko-dev.git
fix playback of offline moves, removes duplicate, bogus header sr=sspitzer 78520 also white space fixes
This commit is contained in:
Родитель
6165949c20
Коммит
e044966ea3
|
@ -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, ¤tOp);
|
||||
|
||||
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, ¤tOp);
|
||||
|
||||
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, ¤tOp);
|
||||
if (m_KeyIndex < m_CurrentKeys.GetSize())
|
||||
m_currentDB->GetOfflineOpForKey(m_CurrentKeys[m_KeyIndex], PR_FALSE, ¤tOp);
|
||||
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");
|
||||
|
|
Загрузка…
Ссылка в новой задаче