fix 466730, make compact all compact imap offline stores, r=standard8, sr=neil

This commit is contained in:
David Bienvenu 2009-01-14 17:48:07 -08:00
Родитель 5842d58a31
Коммит be98895348
15 изменённых файлов: 431 добавлений и 167 удалений

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

@ -1312,11 +1312,10 @@ let gFolderTreeController = {
return;
// reset thread pane for non-imap folders.
if (!isImapFolder && (gDBView.msgFolder == folder || aCompactAll))
if (!isImapFolder && gDBView && (gDBView.msgFolder == folder || aCompactAll))
this._resetThreadPane();
if (aCompactAll)
folder.compactAll(null, msgWindow, null, true, null);
folder.compactAll(null, msgWindow, isImapFolder || folder.server.type == "news");
else
folder.compact(null, msgWindow);
},

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

@ -67,7 +67,7 @@ typedef long nsMsgBiffState;
// enumerated type for determining if a message has been replied to, forwarded, etc.
typedef long nsMsgDispositionState;
[scriptable, uuid(C5FF3B28-6A48-415A-BFB4-97D9DBE85E3B)]
[scriptable, uuid(38444311-d7fb-4fbc-a52e-1899320ce1da)]
interface nsIMsgFolder : nsISupports {
const nsMsgBiffState nsMsgBiffState_NewMail = 0; // User has new mail waiting.
@ -164,11 +164,22 @@ interface nsIMsgFolder : nsISupports {
void createStorageIfMissing(in nsIUrlListener urlListener);
void compact(in nsIUrlListener aListener, in nsIMsgWindow aMsgWindow);
/**
* Compact all folders in the account corresponding to this folder/
* Optionally compact their offline stores as well (imap/news)
*
* @param aListener Notified of completion, can be null.
* @param aMsgWindow For progress/status, can be null.
* @param aCompactOfflineAlso This controls whether we compact all
* offline stores as well.
*/
void compactAll(in nsIUrlListener aListener, in nsIMsgWindow aMsgWindow,
in nsISupportsArray aFolderArray, in boolean aCompactOfflineAlso,
in nsISupportsArray aOfflineFolderArray);
void compactAllOfflineStores(in nsIMsgWindow aMsgWindow,
in nsISupportsArray aOfflineFolderArray);
in boolean aCompactOfflineAlso);
void compactAllOfflineStores(in nsIUrlListener aListener,
in nsIMsgWindow aMsgWindow,
in nsIArray aOfflineFolderArray);
void emptyTrash(in nsIMsgWindow aMsgWindow, in nsIUrlListener aListener);
/**

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

@ -36,18 +36,44 @@
* ***** END LICENSE BLOCK ***** */
#include "nsISupports.idl"
#include "nsISupportsArray.idl"
interface nsIMsgFolder;
interface nsIMsgDatabase;
interface nsIMsgWindow;
interface nsIUrlListener;
interface nsIArray;
[scriptable, uuid(2af7d7a2-e5b6-11d4-a5b7-0060b0fc04b7)]
[scriptable, uuid(38c7e876-3083-4aea-8dcd-0ea0ec1753a3)]
/* Use this for any object that wants to handle compacting folders */
/**
* Use this for any object that wants to handle compacting folders.
* Currently, the folders themselves create this object.
*/
interface nsIMsgFolderCompactor : nsISupports
{
void compact(in nsIMsgFolder aFolder, in boolean aOfflineStore, in nsIMsgWindow aMsgWindow);
void compactAll(in nsISupportsArray aArrayOfFoldersToCompact, in nsIMsgWindow aMsgWindow, in boolean compactOfflineAlso, in nsISupportsArray aOfflineFolderArray);
/**
* Compact the given folder, or its offline store (imap/news only)
*
* @param aFolder The folder to compact
* @param aOfflineStore Just compact the offline store?
* @param aListener Notified of completion, can be null.
* @param aMsgWindow Used for progress/status, can be null
*/
void compact(in nsIMsgFolder aFolder, in boolean aOfflineStore,
in nsIUrlListener aListener, in nsIMsgWindow aMsgWindow);
/**
* Compact the passed in array of folders, and the passed in offline stores.
*
* @param aArrayOfFoldersToCompact The folders to compact.
* @param aOfflineFolderArray Folders whose offline stores we
* should compact, can be null.
* @param aListener Notified of completion, can be null.
* @param aMsgWindow Used for progress/status, can be null
*/
void compactFolders(in nsIArray aArrayOfFoldersToCompact,
in nsIArray aOfflineFolderArray,
in nsIUrlListener aListener,
in nsIMsgWindow aMsgWindow);
};

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

@ -58,6 +58,7 @@
#include "prprf.h"
#include "nsMsgLocalFolderHdrs.h"
#include "nsIMsgDatabase.h"
#include "nsArrayUtils.h"
//////////////////////////////////////////////////////////////////////////////
// nsFolderCompactState
@ -148,42 +149,49 @@ nsFolderCompactState::InitDB(nsIMsgDatabase *db)
return rv;
}
NS_IMETHODIMP nsFolderCompactState::CompactAll(nsISupportsArray *aArrayOfFoldersToCompact, nsIMsgWindow *aMsgWindow, PRBool aCompactOfflineAlso, nsISupportsArray *aOfflineFolderArray)
NS_IMETHODIMP nsFolderCompactState::CompactFolders(nsIArray *aArrayOfFoldersToCompact,
nsIArray *aOfflineFolderArray,
nsIUrlListener *aUrlListener,
nsIMsgWindow *aMsgWindow)
{
nsresult rv = NS_OK;
m_window = aMsgWindow;
if (aArrayOfFoldersToCompact)
m_folderArray =do_QueryInterface(aArrayOfFoldersToCompact, &rv);
m_listener = aUrlListener;
if (aArrayOfFoldersToCompact)
m_folderArray = aArrayOfFoldersToCompact;
else if (aOfflineFolderArray)
{
m_folderArray = do_QueryInterface(aOfflineFolderArray, &rv);
m_folderArray = aOfflineFolderArray;
m_compactingOfflineFolders = PR_TRUE;
aOfflineFolderArray = nsnull;
}
if (NS_FAILED(rv) || !m_folderArray)
return rv;
if (!m_folderArray)
return NS_OK;
m_compactAll = PR_TRUE;
m_compactOfflineAlso = aCompactOfflineAlso;
m_compactOfflineAlso = aOfflineFolderArray != nsnull;
if (m_compactOfflineAlso)
m_offlineFolderArray = do_QueryInterface(aOfflineFolderArray);
m_offlineFolderArray = aOfflineFolderArray;
m_folderIndex = 0;
nsresult rv = NS_OK;
nsCOMPtr<nsIMsgFolder> firstFolder = do_QueryElementAt(m_folderArray,
m_folderIndex, &rv);
if (NS_SUCCEEDED(rv) && firstFolder)
Compact(firstFolder, m_compactingOfflineFolders, aMsgWindow); //start with first folder from here.
Compact(firstFolder, m_compactingOfflineFolders, aUrlListener,
aMsgWindow); //start with first folder from here.
return rv;
}
NS_IMETHODIMP
nsFolderCompactState::Compact(nsIMsgFolder *folder, PRBool aOfflineStore, nsIMsgWindow *aMsgWindow)
nsFolderCompactState::Compact(nsIMsgFolder *folder, PRBool aOfflineStore,
nsIUrlListener *aListener, nsIMsgWindow *aMsgWindow)
{
NS_ENSURE_ARG_POINTER(folder);
m_listener = aListener;
if (!m_compactingOfflineFolders && !aOfflineStore)
{
{
nsCOMPtr <nsIMsgImapMailFolder> imapFolder = do_QueryInterface(folder);
if (imapFolder)
return folder->Compact(this, aMsgWindow);
@ -228,16 +236,16 @@ nsFolderCompactState::Compact(nsIMsgFolder *folder, PRBool aOfflineStore, nsIMsg
else
{
rv=folder->GetMsgDatabase(nsnull, getter_AddRefs(db));
NS_ENSURE_SUCCESS(rv,rv);
NS_ENSURE_SUCCESS(rv, rv);
}
rv = folder->GetFilePath(getter_AddRefs(path));
NS_ENSURE_SUCCESS(rv,rv);
NS_ENSURE_SUCCESS(rv, rv);
rv = folder->GetBaseMessageURI(baseMessageURI);
NS_ENSURE_SUCCESS(rv,rv);
NS_ENSURE_SUCCESS(rv, rv);
rv = Init(folder, baseMessageURI.get(), db, path, m_window);
NS_ENSURE_SUCCESS(rv,rv);
NS_ENSURE_SUCCESS(rv, rv);
PRBool isLocked;
m_folder->GetLocked(&isLocked);
@ -326,9 +334,9 @@ NS_IMETHODIMP nsFolderCompactState::OnStopRunningUrl(nsIURI *url, nsresult statu
{
if (m_parsingFolder)
{
m_parsingFolder=PR_FALSE;
m_parsingFolder = PR_FALSE;
if (NS_SUCCEEDED(status))
status=Compact(m_folder, m_compactingOfflineFolders, m_window);
status = Compact(m_folder, m_compactingOfflineFolders, this, m_window);
else if (m_compactAll)
CompactNextFolder();
}
@ -340,6 +348,10 @@ NS_IMETHODIMP nsFolderCompactState::OnStopRunningUrl(nsIURI *url, nsresult statu
prevFolder->SetMsgDatabase(nsnull);
CompactNextFolder();
}
else if (m_listener)
{
CompactCompleted(status);
}
return NS_OK;
}
@ -463,12 +475,19 @@ nsFolderCompactState::FinishCompact()
if (m_compactAll)
rv = CompactNextFolder();
else
ShowDoneStatus();
else
CompactCompleted(NS_OK);
return rv;
}
void nsFolderCompactState::CompactCompleted(nsresult exitCode)
{
if (m_listener)
m_listener->OnStopRunningUrl(nsnull, exitCode);
ShowDoneStatus();
}
nsresult
nsFolderCompactState::ReleaseFolderLock()
{
@ -496,36 +515,32 @@ void nsFolderCompactState::ShowDoneStatus()
nsresult
nsFolderCompactState::CompactNextFolder()
{
nsresult rv = NS_OK;
m_folderIndex++;
PRUint32 cnt=0;
rv = m_folderArray->Count(&cnt);
NS_ENSURE_SUCCESS(rv,rv);
if (m_folderIndex == cnt)
{
if (m_compactOfflineAlso)
{
m_compactingOfflineFolders = PR_TRUE;
nsCOMPtr<nsIMsgFolder> folder = do_QueryElementAt(m_folderArray,
m_folderIndex-1, &rv);
if (NS_SUCCEEDED(rv) && folder)
folder->CompactAllOfflineStores(m_window, m_offlineFolderArray);
}
else
{
ShowDoneStatus();
return rv;
}
}
nsCOMPtr<nsIMsgFolder> folder = do_QueryElementAt(m_folderArray,
m_folderIndex, &rv);
m_folderIndex++;
PRUint32 cnt = 0;
nsresult rv = m_folderArray->GetLength(&cnt);
NS_ENSURE_SUCCESS(rv,rv);
if (m_folderIndex == cnt)
{
if (!m_compactOfflineAlso)
{
CompactCompleted(NS_OK);
return rv;
}
m_compactingOfflineFolders = PR_TRUE;
nsCOMPtr<nsIMsgFolder> folder = do_QueryElementAt(m_folderArray,
m_folderIndex-1, &rv);
if (NS_SUCCEEDED(rv) && folder)
folder->CompactAllOfflineStores(this, m_window, m_offlineFolderArray);
if (NS_SUCCEEDED(rv) && folder)
rv = Compact(folder, m_compactingOfflineFolders, m_window);
else
ShowDoneStatus();
return rv;
}
nsCOMPtr<nsIMsgFolder> folder = do_QueryElementAt(m_folderArray,
m_folderIndex, &rv);
if (NS_SUCCEEDED(rv) && folder)
rv = Compact(folder, m_compactingOfflineFolders, m_listener, m_window);
else
CompactCompleted(rv);
return rv;
}
nsresult

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

@ -49,7 +49,10 @@
#define COMPACTOR_READ_BUFF_SIZE 16384
class nsFolderCompactState : public nsIMsgFolderCompactor, public nsIStreamListener, public nsICopyMessageStreamListener, public nsIUrlListener
class nsFolderCompactState : public nsIMsgFolderCompactor,
public nsIStreamListener,
public nsICopyMessageStreamListener,
public nsIUrlListener
{
public:
NS_DECL_ISUPPORTS
@ -75,6 +78,7 @@ protected:
nsresult ShowStatusMsg(const nsString& aMsg);
nsresult ReleaseFolderLock();
void ShowCompactingStatusMsg();
void CompactCompleted(nsresult exitCode);
void ShowDoneStatus();
nsresult CompactNextFolder();
void AdvanceToNextLine(const char *buffer, PRUint32 &bufferOffset, PRUint32 maxBufferOffset);
@ -93,7 +97,7 @@ protected:
char m_dataBuffer[COMPACTOR_READ_BUFF_SIZE + 1]; // temp data buffer for copying message
nsresult m_status; // the status of the copying operation
nsCOMPtr <nsIMsgMessageService> m_messageService; // message service for copying
nsCOMPtr<nsISupportsArray> m_folderArray; // to store all the folders in case of compact all
nsCOMPtr<nsIArray> m_folderArray; // folders we are compacting, if compacting multiple.
nsCOMPtr <nsIMsgWindow> m_window;
nsCOMPtr <nsIMsgDBHdr> m_curSrcHdr;
PRUint32 m_folderIndex; // tells which folder to compact in case of compact all
@ -106,8 +110,8 @@ protected:
PRBool m_startOfMsg;
PRInt32 m_statusOffset;
PRUint32 m_addedHeaderSize;
nsCOMPtr <nsISupportsArray> m_offlineFolderArray;
nsCOMPtr<nsIArray> m_offlineFolderArray;
nsCOMPtr<nsIUrlListener> m_listener;
};
class nsOfflineStoreCompactState : public nsFolderCompactState

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

@ -798,7 +798,8 @@ nsMsgFolderDataSource::DoCommand(nsISupportsArray/*<nsIRDFResource>*/* aSources,
}
else if ((aCommand == kNC_CompactAll))
{
rv = folder->CompactAll(nsnull, window, nsnull, PR_TRUE, nsnull);
// this will also compact offline stores for IMAP
rv = folder->CompactAll(nsnull, window, PR_TRUE);
}
else if ((aCommand == kNC_EmptyTrash))
{

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

@ -204,7 +204,7 @@ nsresult nsMsgPurgeService::PerformPurge()
NS_ENSURE_SUCCESS(rv, rv);
rv = rootFolder->ListDescendents(childFolders);
PRUint32 cnt =0;
PRUint32 cnt = 0;
childFolders->Count(&cnt);
nsCOMPtr<nsISupports> supports;

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

@ -0,0 +1,202 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
*
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/licenses/publicdomain/
*
* ***** END LICENSE BLOCK ***** */
/*
* Test suite for folder compaction
*
* Currently tested:
* - Compacting local folders
* TODO
* - Compacting imap offline stores.
*/
// Globals
var gMsgFile1, gMsgFile2, gMsgFile3;
var gLocalFolder2;
var gLocalFolder3;
var gLocalTrashFolder;
var gCurTestNum;
// After a compact (or other operation), this is what we expect the
// folder size to be.
var gExpectedFolderSize;
var gMsgHdrs = new Array();
const gCopyService = Cc["@mozilla.org/messenger/messagecopyservice;1"]
.getService(Ci.nsIMsgCopyService);
// nsIMsgCopyServiceListener implementation
var copyListener =
{
OnStartCopy: function() {},
OnProgress: function(aProgress, aProgressMax) {},
SetMessageKey: function(aKey)
{
let hdr = gLocalInboxFolder.GetMessageHeader(aKey);
gMsgHdrs.push({hdr: hdr, ID: hdr.messageId});
},
SetMessageId: function(aMessageId) {},
OnStopCopy: function(aStatus)
{
// Check: message successfully copied.
do_check_eq(aStatus, 0);
// Ugly hack: make sure we don't get stuck in a JS->C++->JS->C++... call stack
// This can happen with a bunch of synchronous functions grouped together, and
// can even cause tests to fail because they're still waiting for the listener
// to return
do_timeout(0, "doTest(++gCurTestNum)");
}
};
var urlListener =
{
OnStartRunningUrl: function (aUrl) {
},
OnStopRunningUrl: function (aUrl, aExitCode) {
// Check: message successfully copied.
do_check_eq(aExitCode, 0);
// Ugly hack: make sure we don't get stuck in a JS->C++->JS->C++... call stack
// This can happen with a bunch of synchronous functions grouped together, and
// can even cause tests to fail because they're still waiting for the listener
// to return
do_timeout(0, "doTest(++gCurTestNum)");
}
};
function copyFileMessage(file, destFolder, isDraftOrTemplate)
{
gCopyService.CopyFileMessage(file, destFolder, null, isDraftOrTemplate, 0, "", copyListener, null);
}
function copyMessages(items, isMove, srcFolder, destFolder)
{
var array = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray);
items.forEach(function (item) {
array.appendElement(item, false);
});
gCopyService.CopyMessages(srcFolder, array, destFolder, isMove, copyListener, null, true);
}
function deleteMessages(srcFolder, items)
{
var array = Cc["@mozilla.org/array;1"].createInstance(Ci.nsIMutableArray);
items.forEach(function (item) {
array.appendElement(item, false);
});
srcFolder.deleteMessages(array, null, false, true, copyListener, true);
}
function calculateFolderSize(folder)
{
let msgDB = folder.getMsgDatabase(null);
let enumerator = msgDB.EnumerateMessages();
let totalSize = 0;
if (enumerator)
{
while (enumerator.hasMoreElements())
{
var header = enumerator.getNext();
if (header instanceof Components.interfaces.nsIMsgDBHdr)
totalSize += header.messageSize;
}
}
return totalSize;
}
/*
* TESTS
*/
// Beware before commenting out a test -- later tests might just depend on earlier ones
const gTestArray =
[
// Copying messages from files
function testCopyFileMessage1() { copyFileMessage(gMsgFile1, gLocalInboxFolder, false); },
function testCopyFileMessage2() { copyFileMessage(gMsgFile2, gLocalInboxFolder, false); },
function testCopyFileMessage3() { copyFileMessage(gMsgFile3, gLocalInboxFolder, true); },
// Moving/copying messages
function testCopyMessages1() { copyMessages([gMsgHdrs[0].hdr], false, gLocalInboxFolder, gLocalFolder2); },
function testCopyMessages2() { copyMessages([gMsgHdrs[1].hdr, gMsgHdrs[2].hdr], false, gLocalInboxFolder, gLocalFolder2); },
function testMoveMessages1() { copyMessages([gMsgHdrs[0].hdr, gMsgHdrs[1].hdr], true, gLocalInboxFolder, gLocalFolder3); },
// Deleting messages
function testDeleteMessages1() { // delete to trash
// Let's take a moment to re-initialize stuff that got moved
var folder3DB = gLocalFolder3.getMsgDatabase(null);
gMsgHdrs[0].hdr = folder3DB.getMsgHdrForMessageID(gMsgHdrs[0].ID);
// Now delete the message
deleteMessages(gLocalFolder3, [gMsgHdrs[0].hdr], false, false);
},
function compactFolder()
{
gExpectedFolderSize = calculateFolderSize(gLocalFolder3);
do_check_neq(gLocalFolder3.expungedBytes, 0);
gLocalFolder3.compact(urlListener, null);
},
function compactAllFolders()
{
do_check_eq(gExpectedFolderSize, gLocalFolder3.filePath.fileSize);
gExpectedInboxSize = calculateFolderSize(gLocalInboxFolder);
gExpectedFolder2Size = calculateFolderSize(gLocalFolder2);
gExpectedFolder3Size = calculateFolderSize(gLocalFolder3);
gLocalInboxFolder.compactAll(urlListener, null, true);
},
function lastTestCheck()
{
do_check_eq(gExpectedInboxSize, gLocalInboxFolder.filePath.fileSize);
do_check_eq(gExpectedFolder2Size, gLocalFolder2.filePath.fileSize);
do_check_eq(gExpectedFolder3Size, gLocalFolder3.filePath.fileSize);
urlListener.OnStopRunningUrl(null, 0);
}
];
function run_test()
{
loadLocalMailAccount();
// Load up some messages so that we can copy them in later.
gMsgFile1 = do_get_file("../mailnews/test/data/bugmail10");
gMsgFile2 = do_get_file("../mailnews/test/data/bugmail11");
gMsgFile3 = do_get_file("../mailnews/test/data/draft1");
// Create another folder to move and copy messages around, and force initialization.
var rootFolder = gLocalIncomingServer.rootMsgFolder;
gLocalFolder2 = rootFolder.addSubfolder("folder2");
var folderName = gLocalFolder2.prettiestName;
// Create a third folder for more testing.
gLocalFolder3 = rootFolder.addSubfolder("folder3");
folderName = gLocalFolder3.prettiestName;
// "Master" do_test_pending(), paired with a do_test_finished() at the end of all the operations.
do_test_pending();
// do_test_finished();
// Do the test.
doTest(1);
}
function doTest(test)
{
if (test <= gTestArray.length)
{
gCurTestNum = test;
var testFn = gTestArray[test-1];
// Set a limit of three seconds; if the notifications haven't arrived by then there's a problem.
do_timeout(10000, "if (gCurTestNum == "+test+") \
do_throw('Notifications not received in 10000 ms for operation "+testFn.name+", current status is '+gCurrStatus);");
try {
testFn();
} catch(ex) {dump(ex);}
}
else
{
do_test_finished(); // for the one in run_test()
}
}

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

@ -359,9 +359,9 @@ NS_IMETHODIMP nsMsgDBFolder::OpenBackupMsgDatabase()
rv = backupDBDummyFolder->Append(folderName);
NS_ENSURE_SUCCESS(rv, rv);
mBackupDatabase = do_CreateInstance(NS_MAILBOXDB_CONTRACTID, &rv);
nsCOMPtr<nsIMsgDBService> msgDBService =
do_GetService(NS_MSGDB_SERVICE_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
rv = msgDBService->OpenMailDBFromFile(
backupDBDummyFolder, PR_FALSE, PR_TRUE, getter_AddRefs(mBackupDatabase));
@ -1600,12 +1600,12 @@ nsresult nsMsgDBFolder::EndNewOfflineMessage()
return NS_OK;
}
nsresult nsMsgDBFolder::CompactOfflineStore(nsIMsgWindow *inWindow)
nsresult nsMsgDBFolder::CompactOfflineStore(nsIMsgWindow *inWindow, nsIUrlListener *aListener)
{
nsresult rv;
nsCOMPtr <nsIMsgFolderCompactor> folderCompactor = do_CreateInstance(NS_MSGOFFLINESTORECOMPACTOR_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
return folderCompactor->Compact(this, PR_TRUE, inWindow);
return folderCompactor->Compact(this, PR_TRUE, aListener, inWindow);
}
nsresult
@ -1626,18 +1626,18 @@ nsMsgDBFolder::AutoCompact(nsIMsgWindow *aWindow)
{
nsCOMPtr<nsISupportsArray> allServers;
accountMgr->GetAllServers(getter_AddRefs(allServers));
NS_ENSURE_SUCCESS(rv,rv);
NS_ENSURE_SUCCESS(rv, rv);
PRUint32 numServers, serverIndex=0;
rv = allServers->Count(&numServers);
PRInt32 offlineSupportLevel;
if ( numServers > 0 )
{
nsCOMPtr<nsIMsgIncomingServer> server = do_QueryElementAt(allServers, serverIndex);
NS_ENSURE_SUCCESS(rv,rv);
nsCOMPtr<nsISupportsArray> folderArray;
nsCOMPtr<nsISupportsArray> offlineFolderArray;
NS_NewISupportsArray(getter_AddRefs(folderArray));
NS_NewISupportsArray(getter_AddRefs(offlineFolderArray));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIMutableArray> folderArray = do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIMutableArray> offlineFolderArray = do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
PRInt32 totalExpungedBytes = 0;
PRInt32 offlineExpungedBytes = 0;
PRInt32 localExpungedBytes = 0;
@ -1648,18 +1648,18 @@ nsMsgDBFolder::AutoCompact(nsIMsgWindow *aWindow)
if(NS_SUCCEEDED(rv) && rootFolder)
{
rv = server->GetOfflineSupportLevel(&offlineSupportLevel);
NS_ENSURE_SUCCESS(rv,rv);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsISupportsArray> allDescendents;
NS_NewISupportsArray(getter_AddRefs(allDescendents));
rootFolder->ListDescendents(allDescendents);
PRUint32 cnt=0;
PRUint32 cnt = 0;
rv = allDescendents->Count(&cnt);
NS_ENSURE_SUCCESS(rv,rv);
NS_ENSURE_SUCCESS(rv, rv);
PRUint32 expungedBytes=0;
if (offlineSupportLevel > 0)
{
PRUint32 flags;
for (PRUint32 i=0; i< cnt;i++)
for (PRUint32 i = 0; i < cnt; i++)
{
nsCOMPtr<nsIMsgFolder> folder = do_QueryElementAt(allDescendents, i);
expungedBytes = 0;
@ -1668,20 +1668,20 @@ nsMsgDBFolder::AutoCompact(nsIMsgWindow *aWindow)
folder->GetExpungedBytes(&expungedBytes);
if (expungedBytes > 0 )
{
offlineFolderArray->AppendElement(folder);
offlineFolderArray->AppendElement(folder, PR_FALSE);
offlineExpungedBytes += expungedBytes;
}
}
}
else //pop or local
{
for (PRUint32 i=0; i< cnt;i++)
for (PRUint32 i = 0; i < cnt; i++)
{
nsCOMPtr<nsIMsgFolder> folder = do_QueryElementAt(allDescendents, i);
folder->GetExpungedBytes(&expungedBytes);
if (expungedBytes > 0 )
{
folderArray->AppendElement(folder);
folderArray->AppendElement(folder, PR_FALSE);
localExpungedBytes += expungedBytes;
}
}
@ -1753,15 +1753,16 @@ nsMsgDBFolder::AutoCompact(nsIMsgWindow *aWindow)
if ( localExpungedBytes > 0)
{
nsCOMPtr <nsIMsgFolder> msgFolder = do_QueryElementAt(folderArray, 0, &rv);
if (msgFolder && NS_SUCCEEDED(rv))
nsCOMPtr <nsIMsgFolderCompactor> folderCompactor = do_CreateInstance(NS_MSGOFFLINESTORECOMPACTOR_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
if (offlineExpungedBytes > 0)
msgFolder->CompactAll(nsnull, aWindow, folderArray, PR_TRUE, offlineFolderArray);
folderCompactor->CompactFolders(folderArray, offlineFolderArray, nsnull, aWindow);
else
msgFolder->CompactAll(nsnull, aWindow, folderArray, PR_FALSE, nsnull);
folderCompactor->CompactFolders(folderArray, nsnull, nsnull, aWindow);
}
else if (offlineExpungedBytes > 0)
CompactAllOfflineStores(aWindow, offlineFolderArray);
CompactAllOfflineStores(nsnull, aWindow, offlineFolderArray);
}
}
}
@ -1771,13 +1772,15 @@ nsMsgDBFolder::AutoCompact(nsIMsgWindow *aWindow)
}
NS_IMETHODIMP
nsMsgDBFolder::CompactAllOfflineStores(nsIMsgWindow *aWindow, nsISupportsArray *aOfflineFolderArray)
nsMsgDBFolder::CompactAllOfflineStores(nsIUrlListener *aUrlListener,
nsIMsgWindow *aWindow,
nsIArray *aOfflineFolderArray)
{
nsresult rv= NS_OK;
nsCOMPtr <nsIMsgFolderCompactor> folderCompactor;
folderCompactor = do_CreateInstance(NS_MSGOFFLINESTORECOMPACTOR_CONTRACTID, &rv);
nsresult rv;
nsCOMPtr<nsIMsgFolderCompactor> folderCompactor
= folderCompactor = do_CreateInstance(NS_MSGOFFLINESTORECOMPACTOR_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
return folderCompactor->CompactAll(nsnull, aWindow, PR_TRUE, aOfflineFolderArray);
return folderCompactor->CompactFolders(nsnull, aOfflineFolderArray, aUrlListener, aWindow);
}
nsresult
@ -3258,7 +3261,7 @@ NS_IMETHODIMP nsMsgDBFolder::Compact(nsIUrlListener *aListener, nsIMsgWindow *aM
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsMsgDBFolder::CompactAll(nsIUrlListener *aListener, nsIMsgWindow *aMsgWindow, nsISupportsArray *aFolderArray, PRBool aCompactOfflineAlso, nsISupportsArray *aCompactOfflineArray)
NS_IMETHODIMP nsMsgDBFolder::CompactAll(nsIUrlListener *aListener, nsIMsgWindow *aMsgWindow, PRBool aCompactOfflineAlso)
{
NS_ASSERTION(PR_FALSE, "should be overridden by child class");
return NS_ERROR_NOT_IMPLEMENTED;

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

@ -153,7 +153,7 @@ protected:
nsresult StartNewOfflineMessage();
nsresult WriteStartOfNewLocalMessage();
nsresult EndNewOfflineMessage();
nsresult CompactOfflineStore(nsIMsgWindow *inWindow);
nsresult CompactOfflineStore(nsIMsgWindow *inWindow, nsIUrlListener *aUrlListener);
nsresult AutoCompact(nsIMsgWindow *aWindow);
// this is a helper routine that ignores whether MSG_FLAG_OFFLINE is set for the folder
nsresult MsgFitsDownloadCriteria(nsMsgKey msgKey, PRBool *result);

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

@ -1219,45 +1219,50 @@ NS_IMETHODIMP nsImapMailFolder::Compact(nsIUrlListener *aListener, nsIMsgWindow
return imapService->Expunge(m_thread, this, aListener, nsnull);
}
NS_IMETHODIMP nsImapMailFolder::CompactAll(nsIUrlListener *aListener, nsIMsgWindow *aMsgWindow, nsISupportsArray *aFolderArray,
PRBool aCompactOfflineAlso, nsISupportsArray *aOfflineFolderArray)
NS_IMETHODIMP nsImapMailFolder::CompactAll(nsIUrlListener *aListener,
nsIMsgWindow *aMsgWindow,
PRBool aCompactOfflineAlso)
{
NS_ASSERTION(!aOfflineFolderArray, "compacting automatically compacts offline stores");
nsresult rv;
nsCOMPtr<nsISupportsArray> folderArray;
nsCOMPtr<nsIMutableArray> folderArray, offlineFolderArray;
if (!aFolderArray)
nsCOMPtr<nsIMsgFolder> rootFolder;
nsCOMPtr<nsISupportsArray> allDescendents;
rv = GetRootFolder(getter_AddRefs(rootFolder));
if (NS_SUCCEEDED(rv) && rootFolder)
{
nsCOMPtr<nsIMsgFolder> rootFolder;
nsCOMPtr<nsISupportsArray> allDescendents;
rv = GetRootFolder(getter_AddRefs(rootFolder));
if (NS_SUCCEEDED(rv) && rootFolder)
allDescendents = do_CreateInstance(NS_SUPPORTSARRAY_CONTRACTID, &rv);
NS_ENSURE_TRUE(allDescendents, rv);
rootFolder->ListDescendents(allDescendents);
PRUint32 cnt = 0;
rv = allDescendents->Count(&cnt);
NS_ENSURE_SUCCESS(rv, rv);
folderArray = do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
NS_ENSURE_TRUE(folderArray, rv);
if (aCompactOfflineAlso)
{
allDescendents = do_CreateInstance(NS_SUPPORTSARRAY_CONTRACTID, &rv);
NS_ENSURE_TRUE(allDescendents, rv);
rootFolder->ListDescendents(allDescendents);
PRUint32 cnt =0;
rv = allDescendents->Count(&cnt);
NS_ENSURE_SUCCESS(rv,rv);
folderArray = do_CreateInstance(NS_SUPPORTSARRAY_CONTRACTID, &rv);
NS_ENSURE_TRUE(folderArray, rv);
for (PRUint32 i=0; i < cnt;i++)
{
nsCOMPtr<nsISupports> supports = getter_AddRefs(allDescendents->ElementAt(i));
nsCOMPtr<nsIMsgFolder> folder = do_QueryInterface(supports, &rv);
NS_ENSURE_SUCCESS(rv,rv);
rv = folderArray->AppendElement(supports);
}
rv = folderArray->Count(&cnt);
NS_ENSURE_SUCCESS(rv,rv);
if (cnt == 0)
return NotifyCompactCompleted();
offlineFolderArray = do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
NS_ENSURE_TRUE(offlineFolderArray, rv);
}
for (PRUint32 i = 0; i < cnt; i++)
{
nsCOMPtr<nsISupports> supports = dont_AddRef(allDescendents->ElementAt(i));
nsCOMPtr<nsIMsgFolder> folder = do_QueryInterface(supports, &rv);
NS_ENSURE_SUCCESS(rv, rv);
rv = folderArray->AppendElement(supports, PR_FALSE);
if (aCompactOfflineAlso)
offlineFolderArray->AppendElement(supports, PR_FALSE);
}
rv = folderArray->GetLength(&cnt);
NS_ENSURE_SUCCESS(rv, rv);
if (cnt == 0)
return NotifyCompactCompleted();
}
nsCOMPtr <nsIMsgFolderCompactor> folderCompactor = do_CreateInstance(NS_MSGLOCALFOLDERCOMPACTOR_CONTRACTID, &rv);
nsCOMPtr <nsIMsgFolderCompactor> folderCompactor =
do_CreateInstance(NS_MSGLOCALFOLDERCOMPACTOR_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
return folderCompactor->CompactAll(aFolderArray ? aFolderArray : folderArray.get(), aMsgWindow,
aCompactOfflineAlso, aOfflineFolderArray);
return folderCompactor->CompactFolders(folderArray, offlineFolderArray,
aListener, aMsgWindow);
}
NS_IMETHODIMP nsImapMailFolder::UpdateStatus(nsIUrlListener *aListener, nsIMsgWindow *aMsgWindow)

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

@ -70,6 +70,7 @@
class nsImapMoveCoalescer;
class nsIMsgIdentity;
class nsIMsgOfflineImapOperation;
#define COPY_BUFFER_SIZE 16384
@ -241,8 +242,8 @@ public:
NS_IMETHODIMP CreateStorageIfMissing(nsIUrlListener* urlListener);
NS_IMETHOD Compact(nsIUrlListener *aListener, nsIMsgWindow *aMsgWindow);
NS_IMETHOD CompactAll(nsIUrlListener *aListener, nsIMsgWindow *aMsgWindow, nsISupportsArray *aFolderArray,
PRBool aCompactOfflineAlso, nsISupportsArray *aOfflineFolderArray);
NS_IMETHOD CompactAll(nsIUrlListener *aListener, nsIMsgWindow *aMsgWindow,
PRBool aCompactOfflineAlso);
NS_IMETHOD EmptyTrash(nsIMsgWindow *msgWindow, nsIUrlListener *aListener);
NS_IMETHOD CopyDataToOutputStreamForAppend(nsIInputStream *aIStream,
PRInt32 aLength, nsIOutputStream *outputStream);

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

@ -831,53 +831,49 @@ nsMsgLocalMailFolder::CreateSubfolderInternal(const nsAString& folderName,
return rv;
}
NS_IMETHODIMP nsMsgLocalMailFolder::CompactAll(nsIUrlListener *aListener, nsIMsgWindow *aMsgWindow, nsISupportsArray *aFolderArray,
PRBool aCompactOfflineAlso, nsISupportsArray *aOfflineFolderArray)
NS_IMETHODIMP nsMsgLocalMailFolder::CompactAll(nsIUrlListener *aListener,
nsIMsgWindow *aMsgWindow,
PRBool aCompactOfflineAlso)
{
nsresult rv = NS_OK;
nsCOMPtr<nsISupportsArray> folderArray;
if (!aFolderArray)
nsCOMPtr<nsIMutableArray> folderArray;
nsCOMPtr<nsIMsgFolder> rootFolder;
nsCOMPtr<nsISupportsArray> allDescendents;
rv = GetRootFolder(getter_AddRefs(rootFolder));
if (NS_SUCCEEDED(rv) && rootFolder)
{
nsCOMPtr<nsIMsgFolder> rootFolder;
nsCOMPtr<nsISupportsArray> allDescendents;
rv = GetRootFolder(getter_AddRefs(rootFolder));
if (NS_SUCCEEDED(rv) && rootFolder)
NS_NewISupportsArray(getter_AddRefs(allDescendents));
rootFolder->ListDescendents(allDescendents);
PRUint32 cnt =0;
rv = allDescendents->Count(&cnt);
NS_ENSURE_SUCCESS(rv, rv);
folderArray = do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
PRUint32 expungedBytes = 0;
for (PRUint32 i = 0; i < cnt; i++)
{
NS_NewISupportsArray(getter_AddRefs(allDescendents));
rootFolder->ListDescendents(allDescendents);
PRUint32 cnt =0;
rv = allDescendents->Count(&cnt);
NS_ENSURE_SUCCESS(rv,rv);
NS_NewISupportsArray(getter_AddRefs(folderArray));
PRUint32 expungedBytes=0;
for (PRUint32 i = 0; i < cnt; i++)
{
nsCOMPtr<nsISupports> supports = getter_AddRefs(allDescendents->ElementAt(i));
nsCOMPtr<nsIMsgFolder> folder = do_QueryInterface(supports, &rv);
NS_ENSURE_SUCCESS(rv,rv);
nsCOMPtr<nsISupports> supports = dont_AddRef(allDescendents->ElementAt(i));
nsCOMPtr<nsIMsgFolder> folder = do_QueryInterface(supports, &rv);
NS_ENSURE_SUCCESS(rv, rv);
expungedBytes=0;
if (folder)
rv = folder->GetExpungedBytes(&expungedBytes);
expungedBytes = 0;
if (folder)
rv = folder->GetExpungedBytes(&expungedBytes);
NS_ENSURE_SUCCESS(rv,rv);
NS_ENSURE_SUCCESS(rv, rv);
if (expungedBytes > 0)
rv = folderArray->AppendElement(supports);
}
rv = folderArray->Count(&cnt);
NS_ENSURE_SUCCESS(rv,rv);
if (cnt == 0 )
return NotifyCompactCompleted();
if (expungedBytes > 0)
rv = folderArray->AppendElement(supports, PR_FALSE);
}
rv = folderArray->GetLength(&cnt);
NS_ENSURE_SUCCESS(rv,rv);
if (cnt == 0)
return NotifyCompactCompleted();
}
nsCOMPtr <nsIMsgFolderCompactor> folderCompactor = do_CreateInstance(NS_MSGLOCALFOLDERCOMPACTOR_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, rv);
if (aFolderArray)
rv = folderCompactor->CompactAll(aFolderArray, aMsgWindow, aCompactOfflineAlso, aOfflineFolderArray);
else if (folderArray)
rv = folderCompactor->CompactAll(folderArray, aMsgWindow, aCompactOfflineAlso, aOfflineFolderArray);
return rv;
return folderCompactor->CompactFolders(folderArray,
nsnull,
aListener, aMsgWindow);
}
NS_IMETHODIMP nsMsgLocalMailFolder::Compact(nsIUrlListener *aListener, nsIMsgWindow *aMsgWindow)
@ -890,7 +886,7 @@ NS_IMETHODIMP nsMsgLocalMailFolder::Compact(nsIUrlListener *aListener, nsIMsgWin
GetExpungedBytes(&expungedBytes);
// check if we need to compact the folder
if (expungedBytes > 0)
rv = folderCompactor->Compact(this, PR_FALSE, aMsgWindow);
rv = folderCompactor->Compact(this, PR_FALSE, aListener, aMsgWindow);
else
rv = NotifyCompactCompleted();
return rv;

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

@ -147,7 +147,7 @@ public:
NS_IMETHOD AddSubfolder(const nsAString& folderName, nsIMsgFolder** newFolder);
NS_IMETHOD Compact(nsIUrlListener *aListener, nsIMsgWindow *aMsgWindow);
NS_IMETHOD CompactAll(nsIUrlListener *aListener, nsIMsgWindow *aMsgWindow, nsISupportsArray *aFolderArray, PRBool aCompactOfflineAlso, nsISupportsArray *aOfflineFolderArray);
NS_IMETHOD CompactAll(nsIUrlListener *aListener, nsIMsgWindow *aMsgWindow, PRBool aCompactOfflineAlso);
NS_IMETHOD EmptyTrash(nsIMsgWindow *msgWindow, nsIUrlListener *aListener);
NS_IMETHOD Delete ();
NS_IMETHOD DeleteSubFolders(nsIArray *folders, nsIMsgWindow *msgWindow);

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

@ -1,6 +1,7 @@
From - Mon Jun 02 19:00:00 2008
X-Mozilla-Status: 0001
X-Mozilla-Status2: 00000000
X-Mozilla-Keys:
Return-path: <example@example.com>
Delivered-To: bugmail@example.org
Received: by 10.114.166.12 with SMTP id o12cs163262wae;