17204. r=bienvenu sr=sspitzer; Add the automatically compact feature when the wasted
space exceeds the purge_threshold for offline and local folders. This also includes a patch by bienvenu to make CompactOfflineStores work. git-svn-id: svn://10.0.0.236/trunk@98909 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -147,7 +147,8 @@ const nsMsgBiffState nsMsgBiffState_Unknown = 2; // We dunno whether there is ne
|
||||
void createStorageIfMissing(in nsIUrlListener urlListener);
|
||||
|
||||
void compact(in nsIUrlListener aListener, in nsIMsgWindow aMsgWindow);
|
||||
void compactAll(in nsIUrlListener aListener, in nsIMsgWindow aMsgWindow);
|
||||
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);
|
||||
void emptyTrash(in nsIMsgWindow aMsgWindow, in nsIUrlListener aListener);
|
||||
|
||||
/**
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
*/
|
||||
|
||||
#include "nsISupports.idl"
|
||||
#include "nsISupportsArray.idl"
|
||||
|
||||
interface nsIMsgFolder;
|
||||
interface nsIMsgDatabase;
|
||||
@@ -35,7 +36,7 @@ interface nsIMsgFolderCompactor : nsISupports
|
||||
{
|
||||
void Init(in nsIMsgFolder folder, in string baseMsgUri, in nsIMsgDatabase db,
|
||||
in nsIFileSpec pathSpec, in nsIMsgWindow aMsgWindow);
|
||||
void InitCompactAll(in nsIMsgFolder folder, in nsIMsgWindow aMsgWindow);
|
||||
void startCompactingAll(in nsISupportsArray aArrayOfFoldersToCompact, in nsIMsgWindow aMsgWindow, in boolean compactOfflineAlso, in nsISupportsArray aOfflineFolderArray);
|
||||
// we probably want to add the ability to set an enumerator to determine which
|
||||
// messages to copy over in the compaction process.
|
||||
void StartCompacting();
|
||||
|
||||
@@ -63,6 +63,7 @@ downloadingMail=Downloading Mail for Offline Use
|
||||
sendingUnsent=Sending Unsent Messages
|
||||
|
||||
compactingFolder=Compacting folder %S...
|
||||
autoCompactAllFolders=Do you wish to compact all local and offline folders because the total wasted space in all accounts exceeds the purge threshhold?
|
||||
|
||||
# LOCALIZATION NOTES(verboseFolderFormat): %1$S is folder name, %2$S is server name
|
||||
verboseFolderFormat=%1$S on %2$S
|
||||
|
||||
@@ -57,6 +57,7 @@ nsFolderCompactState::nsFolderCompactState()
|
||||
m_status = NS_OK;
|
||||
m_messageService = nsnull;
|
||||
m_compactAll = PR_FALSE;
|
||||
m_compactOfflineAlso = PR_FALSE;
|
||||
m_folderIndex =0;
|
||||
}
|
||||
|
||||
@@ -143,46 +144,21 @@ nsFolderCompactState::InitDB(nsIMsgDatabase *db)
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsFolderCompactState::InitCompactAll(nsIMsgFolder *folder, nsIMsgWindow *aMsgWindow)
|
||||
NS_IMETHODIMP nsFolderCompactState::StartCompactingAll(nsISupportsArray *aArrayOfFoldersToCompact, nsIMsgWindow *aMsgWindow, PRBool aCompactOfflineAlso, nsISupportsArray *aOfflineFolderArray)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
nsCOMPtr<nsIMsgFolder> rootFolder;
|
||||
nsCOMPtr<nsISupportsArray> allDescendents;
|
||||
folder->GetRootFolder(getter_AddRefs(rootFolder));
|
||||
NS_NewISupportsArray(getter_AddRefs(allDescendents));
|
||||
rootFolder->ListDescendents(allDescendents);
|
||||
PRUint32 cnt =0;
|
||||
rv = allDescendents->Count(&cnt);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
if (aArrayOfFoldersToCompact)
|
||||
m_folderArray =do_QueryInterface(aArrayOfFoldersToCompact, &rv);
|
||||
|
||||
if (NS_FAILED(rv) || !m_folderArray)
|
||||
return rv;
|
||||
|
||||
m_window = aMsgWindow;
|
||||
NS_NewISupportsArray(getter_AddRefs(m_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);
|
||||
|
||||
expungedBytes=0;
|
||||
if (folder)
|
||||
rv = folder->GetExpungedBytes(&expungedBytes);
|
||||
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
if (expungedBytes > 0)
|
||||
rv = m_folderArray->AppendElement(supports);
|
||||
m_compactAll = PR_TRUE;
|
||||
m_compactOfflineAlso = aCompactOfflineAlso;
|
||||
if (m_compactOfflineAlso)
|
||||
m_offlineFolderArray = do_QueryInterface(aOfflineFolderArray);
|
||||
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
}
|
||||
|
||||
rv = m_folderArray->Count(&cnt);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
if ( cnt == 0)
|
||||
return rv; //no folders to compact
|
||||
else
|
||||
m_compactAll = PR_TRUE;
|
||||
|
||||
m_folderIndex = 0;
|
||||
nsCOMPtr<nsISupports> supports = getter_AddRefs(m_folderArray->ElementAt(m_folderIndex));
|
||||
nsCOMPtr<nsIMsgFolder> firstFolder = do_QueryInterface(supports, &rv);
|
||||
@@ -296,14 +272,11 @@ nsFolderCompactState::Init(nsIMsgFolder *folder, const char *baseMsgUri, nsIMsgD
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsFolderCompactState::StartCompacting()
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
if (m_size > 0)
|
||||
void nsFolderCompactState::ShowCompactingStatusMsg()
|
||||
{
|
||||
nsXPIDLString formatString;
|
||||
|
||||
rv = GetStatusFromMsgName("compactingFolder", getter_Copies(formatString));
|
||||
nsresult rv = GetStatusFromMsgName("compactingFolder", getter_Copies(formatString));
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
nsXPIDLString folderName;
|
||||
@@ -313,19 +286,17 @@ NS_IMETHODIMP nsFolderCompactState::StartCompacting()
|
||||
ShowStatusMsg(u);
|
||||
PR_FREEIF(u);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsFolderCompactState::StartCompacting()
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
if (m_size > 0)
|
||||
{
|
||||
ShowCompactingStatusMsg();
|
||||
AddRef();
|
||||
#ifdef OLD_WAY
|
||||
rv = BuildMessageURI(m_baseMessageUri,
|
||||
m_keyArray[0],
|
||||
m_messageUri);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
rv = m_messageService->CopyMessage(
|
||||
m_messageUri, this, PR_FALSE, nsnull,
|
||||
/* ### should get msg window! */ nsnull, nsnull);
|
||||
#else
|
||||
rv = m_messageService->CopyMessages(&m_keyArray, m_folder, this, PR_FALSE, nsnull, m_window, nsnull);
|
||||
// m_curIndex = m_size; // advance m_curIndex to the end - we're done
|
||||
#endif // OLD_WAY
|
||||
|
||||
}
|
||||
else
|
||||
@@ -391,24 +362,39 @@ nsFolderCompactState::FinishCompact()
|
||||
m_folder->GetMsgDatabase(m_window, getter_AddRefs(db));
|
||||
db = nsnull;
|
||||
if (m_compactAll)
|
||||
{
|
||||
m_folderIndex++;
|
||||
PRUint32 cnt=0;
|
||||
rv = m_folderArray->Count(&cnt);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
if (m_folderIndex == cnt)
|
||||
return rv;
|
||||
|
||||
nsCOMPtr<nsISupports> supports = getter_AddRefs(m_folderArray->ElementAt(m_folderIndex));
|
||||
nsCOMPtr<nsIMsgFolder> folder = do_QueryInterface(supports, &rv);
|
||||
|
||||
if (NS_SUCCEEDED(rv) && folder)
|
||||
CompactHelper(folder);
|
||||
}
|
||||
rv = CompactNextFolder();
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
nsCOMPtr<nsISupports> supports = getter_AddRefs(m_folderArray->ElementAt(m_folderIndex-1));
|
||||
nsCOMPtr<nsIMsgFolder> folder = do_QueryInterface(supports, &rv);
|
||||
if (NS_SUCCEEDED(rv) && folder)
|
||||
folder->CompactAllOfflineStores(m_window, m_offlineFolderArray);
|
||||
}
|
||||
else
|
||||
return rv;
|
||||
}
|
||||
nsCOMPtr<nsISupports> supports = getter_AddRefs(m_folderArray->ElementAt(m_folderIndex));
|
||||
nsCOMPtr<nsIMsgFolder> folder = do_QueryInterface(supports, &rv);
|
||||
|
||||
if (NS_SUCCEEDED(rv) && folder)
|
||||
rv = CompactHelper(folder);
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsFolderCompactState::GetMessage(nsIMsgDBHdr **message)
|
||||
{
|
||||
@@ -514,6 +500,7 @@ nsOfflineStoreCompactState::OnStopRequest(nsIRequest *request, nsISupports *ctxt
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
nsCOMPtr<nsIMsgDBHdr> msgHdr;
|
||||
nsCOMPtr<nsIMsgDBHdr> newMsgHdr;
|
||||
nsCOMPtr <nsIMsgStatusFeedback> statusFeedback;
|
||||
|
||||
if (NS_FAILED(rv)) goto done;
|
||||
uri = do_QueryInterface(ctxt, &rv);
|
||||
@@ -521,13 +508,20 @@ nsOfflineStoreCompactState::OnStopRequest(nsIRequest *request, nsISupports *ctxt
|
||||
rv = GetMessage(getter_AddRefs(msgHdr));
|
||||
if (NS_FAILED(rv)) goto done;
|
||||
|
||||
msgHdr->SetMessageOffset(m_startOfNewMsg);
|
||||
if (msgHdr)
|
||||
msgHdr->SetMessageOffset(m_startOfNewMsg);
|
||||
|
||||
m_db->Commit(nsMsgDBCommitType::kLargeCommit);
|
||||
if (m_window)
|
||||
{
|
||||
m_window->GetStatusFeedback(getter_AddRefs(statusFeedback));
|
||||
if (statusFeedback)
|
||||
statusFeedback->ShowProgress (100 * m_curIndex / m_size);
|
||||
}
|
||||
// advance to next message
|
||||
m_curIndex ++;
|
||||
if (m_curIndex >= m_size)
|
||||
{
|
||||
m_db->Commit(nsMsgDBCommitType::kLargeCommit);
|
||||
msgHdr = nsnull;;
|
||||
newMsgHdr = nsnull;
|
||||
// no more to copy finish it up
|
||||
@@ -597,6 +591,10 @@ nsOfflineStoreCompactState::FinishCompact()
|
||||
// rename the copied folder to be the original folder
|
||||
m_fileSpec.Rename((const char*) idlName);
|
||||
|
||||
PRUnichar emptyStr = 0;
|
||||
ShowStatusMsg(&emptyStr);
|
||||
if (m_compactAll)
|
||||
rv = CompactNextFolder();
|
||||
return rv;
|
||||
}
|
||||
|
||||
@@ -657,3 +655,27 @@ nsFolderCompactState::EndCopy(nsISupports *url, nsresult aStatus)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsOfflineStoreCompactState::StartCompacting()
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
if (m_size > 0 && m_curIndex == 0)
|
||||
{
|
||||
AddRef(); // we own ourselves, until we're done, anyway.
|
||||
ShowCompactingStatusMsg();
|
||||
m_messageUri.SetLength(0); // clear the previous message uri
|
||||
rv = BuildMessageURI(m_baseMessageUri,
|
||||
m_keyArray[0],
|
||||
m_messageUri);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
rv = m_messageService->CopyMessage(
|
||||
m_messageUri, this, PR_FALSE, nsnull, m_window, nsnull);
|
||||
|
||||
}
|
||||
else
|
||||
{ // no messages to copy with
|
||||
FinishCompact();
|
||||
// Release(); // we don't "own" ourselves yet.
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
@@ -55,6 +55,8 @@ public:
|
||||
nsresult BuildMessageURI(const char *baseURI, PRUint32 key, nsCString& uri);
|
||||
nsresult GetStatusFromMsgName(const char *statusMsgName, PRUnichar ** retval);
|
||||
nsresult ShowStatusMsg(const PRUnichar *aMsg);
|
||||
void ShowCompactingStatusMsg();
|
||||
nsresult CompactNextFolder();
|
||||
|
||||
char *m_baseMessageUri; // base message uri
|
||||
nsCString m_messageUri; // current message uri being copy
|
||||
@@ -74,6 +76,8 @@ public:
|
||||
nsCOMPtr <nsIMsgWindow> m_window;
|
||||
PRUint32 m_folderIndex; // tells which folder to compact in case of compact all
|
||||
PRBool m_compactAll; //flag for compact all
|
||||
PRBool m_compactOfflineAlso; //whether to compact offline also
|
||||
nsCOMPtr <nsISupportsArray> m_offlineFolderArray;
|
||||
|
||||
};
|
||||
|
||||
@@ -85,6 +89,7 @@ public:
|
||||
virtual ~nsOfflineStoreCompactState(void);
|
||||
virtual nsresult InitDB(nsIMsgDatabase *db);
|
||||
|
||||
NS_IMETHOD StartCompacting();
|
||||
NS_IMETHOD OnStopRequest(nsIRequest *request, nsISupports *ctxt,
|
||||
nsresult status);
|
||||
|
||||
|
||||
@@ -731,7 +731,7 @@ nsMsgFolderDataSource::DoCommand(nsISupportsArray/*<nsIRDFResource>*/* aSources,
|
||||
}
|
||||
else if ((aCommand == kNC_CompactAll))
|
||||
{
|
||||
rv = folder->CompactAll(nsnull, mWindow);
|
||||
rv = folder->CompactAll(nsnull, mWindow, nsnull, PR_FALSE, nsnull);
|
||||
}
|
||||
else if ((aCommand == kNC_EmptyTrash))
|
||||
{
|
||||
@@ -743,8 +743,8 @@ nsMsgFolderDataSource::DoCommand(nsISupportsArray/*<nsIRDFResource>*/* aSources,
|
||||
nsCOMPtr<nsIRDFLiteral> literal = do_QueryInterface(elem, &rv);
|
||||
if(NS_SUCCEEDED(rv))
|
||||
{
|
||||
PRUnichar *name;
|
||||
literal->GetValue(&name);
|
||||
PRUnichar *name;
|
||||
literal->GetValue(&name);
|
||||
|
||||
rv = folder->Rename(name,mWindow);
|
||||
PR_FREEIF(name);
|
||||
|
||||
@@ -38,11 +38,23 @@
|
||||
#include "nsITransport.h"
|
||||
#include "nsIFileTransportService.h"
|
||||
#include "nsIMsgFolderCompactor.h"
|
||||
#include "nsMsgUtils.h"
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsIMsgWindow.h"
|
||||
#include "nsIPrompt.h"
|
||||
#include "nsIInterfaceRequestor.h"
|
||||
#include "nsIStringBundle.h"
|
||||
|
||||
|
||||
#define oneHour 3600000000
|
||||
#include "nsMsgUtils.h"
|
||||
|
||||
static NS_DEFINE_CID(kPrefServiceCID, NS_PREF_CID);
|
||||
static NS_DEFINE_CID(kMsgAccountManagerCID, NS_MSGACCOUNTMANAGER_CID);
|
||||
static PRTime gtimeOfLastPurgeCheck = 0; //variable to know when to check for purge_threshhold
|
||||
|
||||
|
||||
#define PREF_MAIL_PROMPT_PURGE_THRESHOLD "mail.prompt_purge_threshhold"
|
||||
#define PREF_MAIL_PURGE_THRESHOLD "mail.purge_threshhold"
|
||||
|
||||
nsIAtom* nsMsgDBFolder::mFolderLoadedAtom=nsnull;
|
||||
nsIAtom* nsMsgDBFolder::mDeleteOrMoveMsgCompletedAtom=nsnull;
|
||||
@@ -576,7 +588,6 @@ nsresult nsMsgDBFolder::CreateFileSpecForDB(const char *userLeafName, nsFileSpec
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(dbFileSpec);
|
||||
NS_ENSURE_ARG_POINTER(userLeafName);
|
||||
|
||||
nsCAutoString proposedDBName(userLeafName);
|
||||
NS_MsgHashIfNecessary(proposedDBName);
|
||||
|
||||
@@ -1326,3 +1337,190 @@ nsresult nsMsgDBFolder::CompactOfflineStore(nsIMsgWindow *inWindow)
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsMsgDBFolder::AutoCompact(nsIMsgWindow *aWindow)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aWindow);
|
||||
nsresult rv = NS_OK;
|
||||
PRTime timeNow = PR_Now(); //time in microsec
|
||||
PRTime timeOfLastPurgeCheck = gtimeOfLastPurgeCheck;
|
||||
PRBool prompt;
|
||||
rv = GetPromptPurgeThreshold(&prompt);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
timeOfLastPurgeCheck += oneHour;
|
||||
if ((timeOfLastPurgeCheck == oneHour || timeOfLastPurgeCheck < timeNow) && prompt)
|
||||
{
|
||||
nsCOMPtr<nsIMsgAccountManager> accountMgr = do_GetService(NS_MSGACCOUNTMANAGER_CONTRACTID, &rv);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
nsCOMPtr<nsISupportsArray> allServers;
|
||||
accountMgr->GetAllServers(getter_AddRefs(allServers));
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
PRUint32 numServers, serverIndex=0;
|
||||
rv = allServers->Count(&numServers);
|
||||
PRInt32 offlineSupportLevel;
|
||||
if ( numServers > 0 )
|
||||
{
|
||||
nsCOMPtr <nsISupports> serverSupports = allServers->ElementAt(serverIndex);
|
||||
nsCOMPtr<nsIMsgIncomingServer> server = do_QueryInterface(serverSupports);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
nsCOMPtr<nsISupportsArray> folderArray;
|
||||
nsCOMPtr<nsISupportsArray> offlineFolderArray;
|
||||
NS_NewISupportsArray(getter_AddRefs(folderArray));
|
||||
NS_NewISupportsArray(getter_AddRefs(offlineFolderArray));
|
||||
PRInt32 totalExpungedBytes=0;
|
||||
PRInt32 offlineExpungedBytes =0;
|
||||
PRInt32 localExpungedBytes = 0;
|
||||
do
|
||||
{
|
||||
nsCOMPtr<nsIFolder> rootFolder;
|
||||
rv = server->GetRootFolder(getter_AddRefs(rootFolder));
|
||||
if(NS_SUCCEEDED(rv) && rootFolder)
|
||||
{
|
||||
rv = server->GetOfflineSupportLevel(&offlineSupportLevel);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
nsCOMPtr<nsISupportsArray> allDescendents;
|
||||
NS_NewISupportsArray(getter_AddRefs(allDescendents));
|
||||
rootFolder->ListDescendents(allDescendents);
|
||||
PRUint32 cnt=0;
|
||||
rv = allDescendents->Count(&cnt);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
PRUint32 expungedBytes=0;
|
||||
|
||||
if (offlineSupportLevel > 0)
|
||||
{
|
||||
PRUint32 flags;
|
||||
for (PRUint32 i=0; i< cnt;i++)
|
||||
{
|
||||
nsCOMPtr<nsISupports> supports = getter_AddRefs(allDescendents->ElementAt(i));
|
||||
nsCOMPtr<nsIMsgFolder> folder = do_QueryInterface(supports, &rv);
|
||||
expungedBytes = 0;
|
||||
folder->GetFlags(&flags);
|
||||
if (flags & MSG_FOLDER_FLAG_OFFLINE)
|
||||
folder->GetExpungedBytes(&expungedBytes);
|
||||
if (expungedBytes > 0 )
|
||||
{
|
||||
offlineFolderArray->AppendElement(supports);
|
||||
offlineExpungedBytes += expungedBytes;
|
||||
}
|
||||
}
|
||||
}
|
||||
else //pop or local
|
||||
{
|
||||
for (PRUint32 i=0; i< cnt;i++)
|
||||
{
|
||||
nsCOMPtr<nsISupports> supports = getter_AddRefs(allDescendents->ElementAt(i));
|
||||
nsCOMPtr<nsIMsgFolder> folder = do_QueryInterface(supports, &rv);
|
||||
folder->GetExpungedBytes(&expungedBytes);
|
||||
if (expungedBytes > 0 )
|
||||
{
|
||||
folderArray->AppendElement(supports);
|
||||
localExpungedBytes += expungedBytes;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
serverSupports = allServers->ElementAt(++serverIndex);
|
||||
server = do_QueryInterface(serverSupports, &rv);
|
||||
}
|
||||
while (serverIndex < numServers);
|
||||
totalExpungedBytes = localExpungedBytes + offlineExpungedBytes;
|
||||
PRInt32 purgeThreshold;
|
||||
rv = GetPurgeThreshold(&purgeThreshold);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (totalExpungedBytes > (purgeThreshold*1024))
|
||||
{
|
||||
nsCOMPtr<nsIDocShell> docShell;
|
||||
if (aWindow)
|
||||
{
|
||||
aWindow->GetRootDocShell(getter_AddRefs(docShell));
|
||||
nsCOMPtr<nsIStringBundleService> bundleService =
|
||||
do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsCOMPtr<nsIStringBundle> bundle;
|
||||
rv = bundleService->CreateBundle("chrome://messenger/locale/messenger.properties",
|
||||
getter_AddRefs(bundle));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsXPIDLString alertString;
|
||||
bundle->GetStringFromName(NS_LITERAL_STRING("autoCompactAllFolders").get(),
|
||||
getter_Copies(alertString));
|
||||
if (docShell)
|
||||
{
|
||||
nsCOMPtr<nsIPrompt> dialog(do_GetInterface(docShell));
|
||||
if (dialog && alertString)
|
||||
{
|
||||
PRBool okToCompact = PR_FALSE;
|
||||
dialog->Confirm(nsnull, alertString.get(), &okToCompact);
|
||||
if (okToCompact)
|
||||
{
|
||||
if ( localExpungedBytes > 0)
|
||||
{
|
||||
nsCOMPtr <nsISupports> aSupports = getter_AddRefs(folderArray->ElementAt(0));
|
||||
nsCOMPtr <nsIMsgFolder> msgFolder = do_QueryInterface(aSupports, &rv);
|
||||
if (msgFolder && NS_SUCCEEDED(rv))
|
||||
if (offlineExpungedBytes > 0)
|
||||
msgFolder->CompactAll(nsnull, aWindow, folderArray, PR_TRUE, offlineFolderArray);
|
||||
else
|
||||
msgFolder->CompactAll(nsnull, aWindow, folderArray, PR_FALSE, nsnull);
|
||||
}
|
||||
else if (offlineExpungedBytes > 0)
|
||||
CompactAllOfflineStores(aWindow, offlineFolderArray);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
gtimeOfLastPurgeCheck = PR_Now();
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMsgDBFolder::CompactAllOfflineStores(nsIMsgWindow *aWindow, nsISupportsArray *aOfflineFolderArray)
|
||||
{
|
||||
nsresult rv= NS_OK;
|
||||
nsCOMPtr <nsIMsgFolderCompactor> folderCompactor;
|
||||
folderCompactor = do_CreateInstance(NS_MSGOFFLINESTORECOMPACTOR_CONTRACTID, &rv);
|
||||
|
||||
if (NS_SUCCEEDED(rv) && folderCompactor)
|
||||
rv = folderCompactor->StartCompactingAll(aOfflineFolderArray, aWindow, PR_FALSE, nsnull);
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsMsgDBFolder::GetPromptPurgeThreshold(PRBool *aPrompt)
|
||||
{
|
||||
NS_ENSURE_ARG(aPrompt);
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIPref> prefService = do_GetService(NS_PREF_CONTRACTID, &rv);
|
||||
if (NS_SUCCEEDED(rv) && prefService)
|
||||
{
|
||||
rv = prefService->GetBoolPref(PREF_MAIL_PROMPT_PURGE_THRESHOLD, aPrompt);
|
||||
if (NS_FAILED(rv))
|
||||
{
|
||||
*aPrompt = PR_FALSE;
|
||||
rv = NS_OK;
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsMsgDBFolder::GetPurgeThreshold(PRInt32 *aThreshold)
|
||||
{
|
||||
NS_ENSURE_ARG(aThreshold);
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIPref> prefService = do_GetService(NS_PREF_CONTRACTID, &rv);
|
||||
if (NS_SUCCEEDED(rv) && prefService)
|
||||
{
|
||||
rv = prefService->GetIntPref(PREF_MAIL_PURGE_THRESHOLD, aThreshold);
|
||||
if (NS_FAILED(rv))
|
||||
{
|
||||
*aThreshold = 0;
|
||||
rv = NS_OK;
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "nsIMsgHdr.h"
|
||||
#include "nsIOutputStream.h"
|
||||
#include "nsITransport.h"
|
||||
#include "nsIMsgStringService.h"
|
||||
class nsIMsgFolderCacheElement;
|
||||
|
||||
/*
|
||||
@@ -95,9 +96,11 @@ public:
|
||||
NS_IMETHOD SetRetentionSettings(nsIMsgRetentionSettings *settings);
|
||||
NS_IMETHOD GetDownloadSettings(nsIMsgDownloadSettings **settings);
|
||||
NS_IMETHOD SetDownloadSettings(nsIMsgDownloadSettings *settings);
|
||||
NS_IMETHOD CompactAllOfflineStores(nsIMsgWindow *msgWindow, nsISupportsArray *aOfflineFolderArray);
|
||||
NS_IMETHOD GetOfflineStoreOutputStream(nsIOutputStream **outputStream);
|
||||
NS_IMETHOD GetOfflineStoreInputStream(nsIInputStream **outputStream);
|
||||
NS_IMETHOD IsCommandEnabled(const char *command, PRBool *result);
|
||||
|
||||
protected:
|
||||
virtual nsresult ReadDBFolderInfo(PRBool force);
|
||||
virtual nsresult FlushToFolderCache();
|
||||
@@ -117,9 +120,11 @@ protected:
|
||||
nsresult WriteStartOfNewLocalMessage();
|
||||
nsresult EndNewOfflineMessage();
|
||||
nsresult CompactOfflineStore(nsIMsgWindow *inWindow);
|
||||
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);
|
||||
|
||||
nsresult GetPromptPurgeThreshold(PRBool *aPrompt);
|
||||
nsresult GetPurgeThreshold(PRInt32 *aThreshold);
|
||||
protected:
|
||||
nsCOMPtr<nsIMsgDatabase> mDatabase;
|
||||
nsString mCharset;
|
||||
|
||||
@@ -1165,7 +1165,7 @@ NS_IMETHODIMP nsMsgFolder::Compact(nsIUrlListener *aListener, nsIMsgWindow *aMsg
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgFolder::CompactAll(nsIUrlListener *aListener, nsIMsgWindow *aMsgWindow)
|
||||
NS_IMETHODIMP nsMsgFolder::CompactAll(nsIUrlListener *aListener, nsIMsgWindow *aMsgWindow, nsISupportsArray *aFolderArray, PRBool aCompactOfflineAlso, nsISupportsArray *aCompactOfflineArray)
|
||||
{
|
||||
NS_ASSERTION(PR_FALSE, "should be overridden by child class");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
@@ -95,7 +95,7 @@ public:
|
||||
NS_IMETHOD CreateSubfolder(const PRUnichar *folderName, nsIMsgWindow *msgWindow);
|
||||
NS_IMETHOD AddSubfolder(nsAutoString *folderName, nsIMsgFolder **newFolder);
|
||||
NS_IMETHOD Compact(nsIUrlListener *aListener, nsIMsgWindow *msgWindow);
|
||||
NS_IMETHOD CompactAll(nsIUrlListener *aListener, nsIMsgWindow *msgWindow);
|
||||
NS_IMETHOD CompactAll(nsIUrlListener *aListener, nsIMsgWindow *msgWindow, nsISupportsArray *aFolderArray, PRBool aCompactOfflineAlso, nsISupportsArray *aOfflineFolderArray);
|
||||
NS_IMETHOD EmptyTrash(nsIMsgWindow *msgWindow, nsIUrlListener *aListener);
|
||||
NS_IMETHOD Rename(const PRUnichar *name, nsIMsgWindow *msgWindow);
|
||||
NS_IMETHOD ContainsChildNamed(const char *name, PRBool *_retval);
|
||||
|
||||
@@ -634,6 +634,8 @@ nsImapMailFolder::UpdateFolder(nsIMsgWindow *msgWindow)
|
||||
else if (NS_SUCCEEDED(rv)) // tell the front end that the folder is loaded if we're not going to
|
||||
{ // actually run a url.
|
||||
NotifyFolderEvent(mFolderLoadedAtom);
|
||||
rv = AutoCompact(msgWindow);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
}
|
||||
|
||||
return rv;
|
||||
@@ -738,6 +740,7 @@ NS_IMETHODIMP nsImapMailFolder::CreateClientSubfolderInfo(const char *folderName
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
uri.Append('/');
|
||||
uri.AppendWithConversion(parentName);
|
||||
|
||||
rv = rdf->GetResource(uri,
|
||||
getter_AddRefs(res));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
@@ -1015,7 +1018,7 @@ NS_IMETHODIMP nsImapMailFolder::Compact(nsIUrlListener *aListener, nsIMsgWindow
|
||||
// compact offline part purely for testing purposes
|
||||
if (WeAreOffline() && (mFlags & MSG_FOLDER_FLAG_OFFLINE))
|
||||
{
|
||||
rv = CompactOfflineStore(nsnull);
|
||||
rv = CompactOfflineStore(aMsgWindow);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1028,7 +1031,7 @@ NS_IMETHODIMP nsImapMailFolder::Compact(nsIUrlListener *aListener, nsIMsgWindow
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsImapMailFolder::CompactAll(nsIUrlListener *aListener, nsIMsgWindow *aMsgWindow)
|
||||
NS_IMETHODIMP nsImapMailFolder::CompactAll(nsIUrlListener *aListener, nsIMsgWindow *aMsgWindow, nsISupportsArray *aFolderArray, PRBool aCompactOfflineAlso, nsISupportsArray *aOfflineFolderArray)
|
||||
{
|
||||
return Compact(aListener, aMsgWindow); //for now
|
||||
}
|
||||
|
||||
@@ -126,7 +126,7 @@ public:
|
||||
NS_IMETHODIMP CreateStorageIfMissing(nsIUrlListener* urlListener);
|
||||
|
||||
NS_IMETHOD Compact(nsIUrlListener *aListener, nsIMsgWindow *aMsgWindow);
|
||||
NS_IMETHOD CompactAll(nsIUrlListener *aListener, nsIMsgWindow *aMsgWindow);
|
||||
NS_IMETHOD CompactAll(nsIUrlListener *aListener, nsIMsgWindow *aMsgWindow, nsISupportsArray *aFolderArray, PRBool aCompactOfflineAlso, nsISupportsArray *aOfflineFolderArray);
|
||||
NS_IMETHOD EmptyTrash(nsIMsgWindow *msgWindow, nsIUrlListener *aListener);
|
||||
NS_IMETHOD Delete ();
|
||||
NS_IMETHOD Rename (const PRUnichar *newName, nsIMsgWindow *msgWindow);
|
||||
|
||||
@@ -565,7 +565,7 @@ nsresult nsMsgLocalMailFolder::GetDatabase(nsIMsgWindow *aMsgWindow)
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
//We must have loaded the folder so send a notification
|
||||
NotifyFolderEvent(mFolderLoadedAtom);
|
||||
//Otherwise we have a valid database so lets extract necessary info.
|
||||
@@ -583,13 +583,16 @@ nsMsgLocalMailFolder::UpdateFolder(nsIMsgWindow *aWindow)
|
||||
//If we don't currently have a database, get it. Otherwise, the folder has been updated (presumably this
|
||||
//changes when we download headers when opening inbox). If it's updated, send NotifyFolderLoaded.
|
||||
if(!mDatabase)
|
||||
rv = GetDatabase(aWindow); // this will cause a reparse, if needed.
|
||||
rv = GetDatabase(aWindow); // this will cause a reparse, if needed.
|
||||
else
|
||||
NotifyFolderEvent(mFolderLoadedAtom);
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
{
|
||||
NotifyFolderEvent(mFolderLoadedAtom);
|
||||
rv = AutoCompact(aWindow);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}NS_IMETHODIMP
|
||||
nsMsgLocalMailFolder::GetMessages(nsIMsgWindow *aMsgWindow, nsISimpleEnumerator* *result)
|
||||
{
|
||||
nsresult rv = GetDatabase(aMsgWindow);
|
||||
@@ -842,14 +845,50 @@ nsMsgLocalMailFolder::CreateSubfolder(const PRUnichar *folderName, nsIMsgWindow
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgLocalMailFolder::CompactAll(nsIUrlListener *aListener, nsIMsgWindow *aMsgWindow)
|
||||
NS_IMETHODIMP nsMsgLocalMailFolder::CompactAll(nsIUrlListener *aListener, nsIMsgWindow *aMsgWindow, nsISupportsArray *aFolderArray, PRBool aCompactOfflineAlso, nsISupportsArray *aOfflineFolderArray)
|
||||
{
|
||||
nsresult rv;
|
||||
nsresult rv = NS_OK;
|
||||
nsCOMPtr<nsISupportsArray> folderArray;
|
||||
if (!aFolderArray)
|
||||
{
|
||||
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);
|
||||
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);
|
||||
|
||||
expungedBytes=0;
|
||||
if (folder)
|
||||
rv = folder->GetExpungedBytes(&expungedBytes);
|
||||
|
||||
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 NS_OK;
|
||||
}
|
||||
}
|
||||
nsCOMPtr <nsIMsgFolderCompactor> folderCompactor = do_CreateInstance(NS_MSGLOCALFOLDERCOMPACTOR_CONTRACTID, &rv);
|
||||
if (NS_SUCCEEDED(rv) && folderCompactor)
|
||||
{
|
||||
rv=folderCompactor->InitCompactAll(this, aMsgWindow); // start with each folder compaction from there
|
||||
}
|
||||
if (aFolderArray)
|
||||
rv = folderCompactor->StartCompactingAll(aFolderArray, aMsgWindow, aCompactOfflineAlso, aOfflineFolderArray);
|
||||
else if (folderArray)
|
||||
rv = folderCompactor->StartCompactingAll(folderArray, aMsgWindow, aCompactOfflineAlso, aOfflineFolderArray);
|
||||
return rv;
|
||||
}
|
||||
|
||||
@@ -916,7 +955,6 @@ NS_IMETHODIMP nsMsgLocalMailFolder::EmptyTrash(nsIMsgWindow *msgWindow,
|
||||
rv = aEnumerator->First(); //will fail if no subfolders
|
||||
if (NS_FAILED(rv)) return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIFolder> parent;
|
||||
rv = trashFolder->GetParent(getter_AddRefs(parent));
|
||||
if (NS_SUCCEEDED(rv) && parent)
|
||||
|
||||
@@ -111,7 +111,7 @@ public:
|
||||
NS_IMETHOD AddSubfolder(nsAutoString *folderName, nsIMsgFolder** newFolder);
|
||||
|
||||
NS_IMETHOD Compact(nsIUrlListener *aListener, nsIMsgWindow *aMsgWindow);
|
||||
NS_IMETHOD CompactAll(nsIUrlListener *aListener, nsIMsgWindow *aMsgWindow);
|
||||
NS_IMETHOD CompactAll(nsIUrlListener *aListener, nsIMsgWindow *aMsgWindow, nsISupportsArray *aFolderArray, PRBool aCompactOfflineAlso, nsISupportsArray *aOfflineFolderArray);
|
||||
NS_IMETHOD EmptyTrash(nsIMsgWindow *msgWindow, nsIUrlListener *aListener);
|
||||
NS_IMETHOD Delete ();
|
||||
NS_IMETHOD DeleteSubFolders(nsISupportsArray *folders, nsIMsgWindow *msgWindow);
|
||||
|
||||
@@ -429,6 +429,8 @@ nsMsgNewsFolder::UpdateFolder(nsIMsgWindow *aWindow)
|
||||
rv = mDatabase->ApplyRetentionSettings(retentionSettings);
|
||||
}
|
||||
rv = GetNewMessages(aWindow);
|
||||
rv = AutoCompact(aWindow);
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
}
|
||||
if (rv == NS_MSG_ERROR_OFFLINE)
|
||||
{
|
||||
|
||||
@@ -271,8 +271,8 @@ nsNntpService::DisplayMessage(const char* aMessageURI, nsISupports * aDisplayCon
|
||||
return server->DisplayOfflineMsg(aMsgWindow);
|
||||
}
|
||||
}
|
||||
newsFolder->SetSaveArticleOffline(shouldStoreMsgOffline);
|
||||
}
|
||||
newsFolder->SetSaveArticleOffline(shouldStoreMsgOffline);
|
||||
}
|
||||
|
||||
// now is where our behavior differs....if the consumer is the docshell then we want to
|
||||
|
||||
Reference in New Issue
Block a user