diff --git a/mailnews/base/search/public/nsIMsgFilterList.idl b/mailnews/base/search/public/nsIMsgFilterList.idl index 546ef5289d84..80138ce6ad09 100644 --- a/mailnews/base/search/public/nsIMsgFilterList.idl +++ b/mailnews/base/search/public/nsIMsgFilterList.idl @@ -37,7 +37,7 @@ interface nsIOFileStream; [scriptable, uuid(08ecbcb4-0493-11d3-a50a-0060b0fc04b7)] interface nsIMsgFilterList : nsISupports { - readonly attribute nsIMsgFolder folderForFilterList; + attribute nsIMsgFolder folder; readonly attribute unsigned long filterCount; nsIMsgFilter GetFilterAt(in unsigned long filterIndex); /* these methods don't delete filters - they just change the list. diff --git a/mailnews/base/search/public/nsIMsgFilterService.idl b/mailnews/base/search/public/nsIMsgFilterService.idl index 2487fd622118..0feea0786be6 100644 --- a/mailnews/base/search/public/nsIMsgFilterService.idl +++ b/mailnews/base/search/public/nsIMsgFilterService.idl @@ -24,7 +24,7 @@ [scriptable, uuid(6673cad0-072e-11d3-8d70-00805f8a6617)] interface nsIMsgFilterService : nsISupports { - [noscript] nsIMsgFilterList OpenFilterList(in nsFileSpecPtr filterFile); + [noscript] nsIMsgFilterList OpenFilterList(in nsFileSpecPtr filterFile, in nsIMsgFolder rootFolder); void CloseFilterList(in nsIMsgFilterList filterList); [noscript] void SaveFilterList(in nsIMsgFilterList filterList, diff --git a/mailnews/base/search/src/nsMsgFilter.cpp b/mailnews/base/search/src/nsMsgFilter.cpp index ae251f73c6b6..abad1e6fe474 100644 --- a/mailnews/base/search/src/nsMsgFilter.cpp +++ b/mailnews/base/search/src/nsMsgFilter.cpp @@ -24,6 +24,7 @@ // this file implements the nsMsgFilterList interface #include "msgCore.h" +#include "nsMsgBaseCID.h" #include "nsIMsgHdr.h" #include "nsMsgFilterList.h" #include "nsMsgFilter.h" @@ -32,6 +33,7 @@ #include "nsMsgLocalSearch.h" #include "nsMsgSearchTerm.h" #include "nsXPIDLString.h" +#include "nsIMsgAccountManager.h" static const char *kImapPrefix = "//imap:"; @@ -184,7 +186,7 @@ NS_IMETHODIMP nsMsgFilter::SetAction(nsMsgRuleActionType type, void *value) switch (type) { case nsMsgFilterAction::MoveToFolder: - m_action.m_folderName = (const char *) value; + m_action.m_folderUri = (const char *) value; break; case nsMsgFilterAction::ChangePriority: m_action.m_priority = (nsMsgPriority) (PRInt32) value; @@ -201,7 +203,7 @@ NS_IMETHODIMP nsMsgFilter::GetAction(nsMsgRuleActionType *type, void **value) switch (m_action.m_type) { case nsMsgFilterAction::MoveToFolder: - * (const char **) value = m_action.m_folderName.GetBuffer(); + * (const char **) value = m_action.m_folderUri.GetBuffer(); break; case nsMsgFilterAction::ChangePriority: * (nsMsgPriority *) value = m_action.m_priority; @@ -325,37 +327,86 @@ void nsMsgFilter::SetFilterScript(nsCString *fileName) m_scriptFileName = *fileName; } -nsresult nsMsgFilter::ConvertMoveToFolderValue(nsCString &relativePath) +nsresult nsMsgFilter::ConvertMoveToFolderValue(nsCString &moveValue) { -// m_action.m_folderName = relativePath; - // if relative path starts with kImap, this is a move to folder on the same server - if (relativePath.Find(kImapPrefix) == 0) - { - PRInt32 prefixLen = PL_strlen(kImapPrefix); - relativePath.Mid(m_action.m_originalServerPath, prefixLen, relativePath.Length() - prefixLen); - m_action.m_folderName = m_action.m_originalServerPath; - // convert the server path to the local full path -// MSG_IMAPFolderInfoMail *imapMailFolder = (filterList->GetFolderInfo()) ? filterList->GetFolderInfo()->GetIMAPFolderInfoMail() : (MSG_IMAPFolderInfoMail *)NULL; -// MSG_IMAPFolderInfoContainer *imapContainer = (imapMailFolder) ? imapMailFolder->GetIMAPContainer() : GetFilter()->GetMaster()->GetImapMailFolderTree(); + PRInt16 filterVersion = kFileVersion; + if (m_filterList) + filterVersion = m_filterList->GetVersion(); + if (filterVersion <= k60Beta1Version) + { + nsCOMPtr rootFolder; + nsXPIDLCString folderUri; + + m_filterList->GetFolder(getter_AddRefs(rootFolder)); + + // if relative path starts with kImap, this is a move to folder on the same server + if (moveValue.Find(kImapPrefix) == 0) + { + PRInt32 prefixLen = PL_strlen(kImapPrefix); + moveValue.Mid(m_action.m_originalServerPath, prefixLen, moveValue.Length() - prefixLen); + + nsCOMPtr destIFolder; + if (rootFolder) + { + rootFolder->FindSubFolder (m_action.m_originalServerPath, getter_AddRefs(destIFolder)); + + nsCOMPtr msgFolder; + msgFolder = do_QueryInterface(destIFolder); + destIFolder->GetURI(getter_Copies(folderUri)); + m_action.m_folderUri = folderUri; + moveValue = folderUri; + } + } + else + { + // start off leaving the value the same. + m_action.m_folderUri = moveValue; + nsresult rv = NS_OK; + + nsCOMPtr localMailRoot; + rootFolder->GetURI(getter_Copies(folderUri)); + // if the root folder is not imap, than the local mail root is the server root. + // otherwise, it's the migrated local folders. + if (nsCRT::strncmp("imap:", folderUri, 5)) + { + localMailRoot = rootFolder; + } + else + { + NS_WITH_SERVICE(nsIMsgAccountManager, accountManager, + NS_MSGACCOUNTMANAGER_PROGID, &rv); + if (NS_SUCCEEDED(rv)) + { + nsCOMPtr server; + rv = accountManager->GetLocalFoldersServer(getter_AddRefs(server)); + if (NS_SUCCEEDED(rv) && server) + { + rv = server->GetRootFolder(getter_AddRefs(localMailRoot)); + } + } + } + if (NS_SUCCEEDED(rv) && localMailRoot) + { + nsCOMPtr destIFolder; + localMailRoot->FindSubFolder (moveValue, getter_AddRefs(destIFolder)); + + if (destIFolder) + { + nsCOMPtr msgFolder; + msgFolder = do_QueryInterface(destIFolder); + destIFolder->GetURI(getter_Copies(folderUri)); + m_action.m_folderUri = folderUri; + moveValue = folderUri; + } + } + } + } + else + m_action.m_folderUri = moveValue; -// MSG_IMAPFolderInfoMail *imapFolder = NULL; -// if (imapContainer) -// imapFolder = GetFilter()->GetMaster()->FindImapMailFolder(imapContainer->GetHostName(), relativePath + nsCRT::strlen(MSG_Rule::kImapPrefix), NULL, PR_FALSE); -// if (imapFolder) -// m_action.m_value.m_folderName = nsCRT::strdup(imapFolder->GetPathname()); -// else -// { - // did the user switch servers?? - // we'll still save this filter, the filter code in the mail parser will handle this case -// m_action.m_value.m_folderName = nsCRT::strdup(""); -// } - } - else -// m_action.m_value.m_folderName = PR_smprintf("%s/%s", master->GetPrefs()->GetFolderDirectory(), relativePath); - m_action.m_folderName = relativePath; return NS_OK; - // set m_action.m_value.m_folderName + // set m_action.m_value.m_folderUri } nsresult nsMsgFilter::SaveToTextFile(nsIOFileStream *stream) @@ -387,8 +438,7 @@ nsresult nsMsgFilter::SaveRule() { case nsMsgFilterAction::MoveToFolder: { - nsCAutoString imapTargetString(kImapPrefix); - imapTargetString += m_action.m_folderName; + nsCAutoString imapTargetString(m_action.m_folderUri); err = filterList->WriteStrAttr(nsMsgFilterAttribActionValue, imapTargetString); } break; diff --git a/mailnews/base/search/src/nsMsgFilter.h b/mailnews/base/search/src/nsMsgFilter.h index 6b8167bd2940..3639724e1d84 100644 --- a/mailnews/base/search/src/nsMsgFilter.h +++ b/mailnews/base/search/src/nsMsgFilter.h @@ -36,7 +36,7 @@ public: nsMsgRuleActionType m_type; // this used to be a union - why bother? nsMsgPriority m_priority; /* priority to set rule to */ - nsCString m_folderName; /* Or some folder identifier, if such a thing is invented */ + nsCString m_folderUri; /* Or some folder identifier, if such a thing is invented */ nsCString m_originalServerPath; } ; diff --git a/mailnews/base/search/src/nsMsgFilterList.cpp b/mailnews/base/search/src/nsMsgFilterList.cpp index 9b2ef5d04272..401c558eb18a 100644 --- a/mailnews/base/search/src/nsMsgFilterList.cpp +++ b/mailnews/base/search/src/nsMsgFilterList.cpp @@ -31,9 +31,6 @@ #include "nsMsgUtils.h" #include "nsMsgSearchTerm.h" -const PRInt16 kFileVersion = 7; -const PRInt16 k45Version = 6; - nsMsgFilterList::nsMsgFilterList(nsIOFileStream *fileStream) { @@ -86,11 +83,21 @@ NS_IMETHODIMP nsMsgFilterList::SetLoggingEnabled(PRBool enable) return NS_OK; } -NS_IMETHODIMP nsMsgFilterList::GetFolderForFilterList(class nsIMsgFolder **aFolder) +NS_IMETHODIMP nsMsgFilterList::GetFolder(nsIMsgFolder **aFolder) { - return NS_ERROR_NOT_IMPLEMENTED; + NS_ENSURE_ARG(aFolder); + *aFolder = m_folder; + NS_IF_ADDREF(*aFolder); + return NS_OK; } +NS_IMETHODIMP nsMsgFilterList::SetFolder(nsIMsgFolder *aFolder) +{ + m_folder = aFolder; + return NS_OK; +} + + NS_IMETHODIMP nsMsgFilterList::GetLoggingEnabled(PRBool *aResult) { if (!aResult) diff --git a/mailnews/base/search/src/nsMsgFilterList.h b/mailnews/base/search/src/nsMsgFilterList.h index a44474be6269..50c1cac549c0 100644 --- a/mailnews/base/search/src/nsMsgFilterList.h +++ b/mailnews/base/search/src/nsMsgFilterList.h @@ -29,6 +29,11 @@ #include "nsCOMPtr.h" #include "nsISupportsArray.h" +const PRInt16 kFileVersion = 8; +const PRInt16 k60Beta1Version = 7; +const PRInt16 k45Version = 6; + + //////////////////////////////////////////////////////////////////////////////////////// // The Msg Filter List is an interface designed to make accessing filter lists // easier. Clients typically open a filter list and either enumerate the filters, diff --git a/mailnews/base/search/src/nsMsgFilterService.cpp b/mailnews/base/search/src/nsMsgFilterService.cpp index 3171b9fe0c11..1c781f0ebc1c 100644 --- a/mailnews/base/search/src/nsMsgFilterService.cpp +++ b/mailnews/base/search/src/nsMsgFilterService.cpp @@ -27,6 +27,8 @@ #include "nsMsgFilterService.h" #include "nsFileStream.h" #include "nsMsgFilterList.h" +#include "nsFileLocations.h" +#include "nsSpecialSystemDirectory.h" NS_IMPL_ADDREF(nsMsgFilterService) NS_IMPL_RELEASE(nsMsgFilterService) @@ -58,7 +60,7 @@ NS_IMETHODIMP nsMsgFilterService::QueryInterface(REFNSIID aIID, void** aResult) } -NS_IMETHODIMP nsMsgFilterService::OpenFilterList(nsFileSpec *filterFile, nsIMsgFilterList **resultFilterList) +NS_IMETHODIMP nsMsgFilterService::OpenFilterList(nsFileSpec *filterFile, nsIMsgFolder *rootFolder, nsIMsgFilterList **resultFilterList) { nsresult ret = NS_OK; @@ -70,10 +72,19 @@ NS_IMETHODIMP nsMsgFilterService::OpenFilterList(nsFileSpec *filterFile, nsIMsgF if (!filterList) return NS_ERROR_OUT_OF_MEMORY; NS_ADDREF(filterList); + filterList->SetFolder(rootFolder); if (filterFile->GetFileSize() > 0) ret = filterList->LoadTextFilters(); + fileStream->close(); if (NS_SUCCEEDED(ret)) + { *resultFilterList = filterList; + if (filterList->GetVersion() != kFileVersion) + { + + SaveFilterList(filterList, filterFile); + } + } else NS_RELEASE(filterList); return ret; @@ -89,11 +100,46 @@ NS_IMETHODIMP nsMsgFilterService::CloseFilterList(nsIMsgFilterList *filterList) NS_IMETHODIMP nsMsgFilterService::SaveFilterList(nsIMsgFilterList *filterList, nsFileSpec *filterFile) { nsresult ret = NS_OK; + nsCOMPtr tmpFiltersFile; + nsCOMPtr realFiltersFile; + nsCOMPtr parentDir; - nsIOFileStream *fileStream = new nsIOFileStream(*filterFile); - if (!fileStream) + nsSpecialSystemDirectory tmpFile(nsSpecialSystemDirectory::OS_TemporaryDirectory); + tmpFile += "tmprules.dat"; + + ret = NS_NewFileSpecWithSpec(tmpFile, getter_AddRefs(tmpFiltersFile)); + + NS_ASSERTION(NS_SUCCEEDED(ret),"writing filters file: failed to append filename"); + if (NS_FAILED(ret)) + return ret; + if (NS_SUCCEEDED(ret)) + ret = NS_NewFileSpecWithSpec(*filterFile, getter_AddRefs(realFiltersFile)); + + nsIOFileStream *tmpFileStream = nsnull; + + if (NS_SUCCEEDED(ret)) + ret = realFiltersFile->GetParent(getter_AddRefs(parentDir)); + + if (NS_SUCCEEDED(ret)) + tmpFileStream = new nsIOFileStream(tmpFile); + if (!tmpFileStream) return NS_ERROR_OUT_OF_MEMORY; + ret = filterList->SaveToFile(tmpFileStream); + tmpFileStream->close(); + if (NS_SUCCEEDED(ret)) + { + // can't move across drives + ret = tmpFiltersFile->CopyToDir(parentDir); + if (NS_SUCCEEDED(ret)) + { + filterFile->Delete(PR_FALSE); + parentDir->AppendRelativeUnixPath("tmprules.dat"); + parentDir->Rename("rules.dat"); + tmpFiltersFile->Delete(PR_FALSE); + } + } + NS_ASSERTION(NS_SUCCEEDED(ret), "error opening/saving filter list"); return ret; } diff --git a/mailnews/base/search/tests/filterTest.cpp b/mailnews/base/search/tests/filterTest.cpp index 1396bbb7f230..9265e4dd2b5d 100644 --- a/mailnews/base/search/tests/filterTest.cpp +++ b/mailnews/base/search/tests/filterTest.cpp @@ -240,7 +240,7 @@ nsresult nsFilterTestDriver::OnOpenFilterFile() if (filterFile.Exists()) { - nsresult res = m_filterService->OpenFilterList(&filterFile, getter_AddRefs(filterList)); + nsresult res = m_filterService->OpenFilterList(&filterFile, nsnull, getter_AddRefs(filterList)); if (NS_SUCCEEDED(res)) { } @@ -259,7 +259,7 @@ nsresult nsFilterTestDriver::OnWriteFilterList() if (filterFile.Exists()) { - nsresult res = m_filterService->OpenFilterList(&filterFile, getter_AddRefs(filterList)); + nsresult res = m_filterService->OpenFilterList(&filterFile, nsnull, getter_AddRefs(filterList)); if (NS_SUCCEEDED(res)) { filterFile.MakeUnique(); diff --git a/mailnews/base/src/nsMessengerMigrator.cpp b/mailnews/base/src/nsMessengerMigrator.cpp index 152885a997a4..0f387d86dbad 100644 --- a/mailnews/base/src/nsMessengerMigrator.cpp +++ b/mailnews/base/src/nsMessengerMigrator.cpp @@ -2265,7 +2265,7 @@ nsresult nsMessengerMigrator::MigrateFilters(nsIMsgIncomingServer *aServer) if (NS_FAILED(rv)) return rv; // open will migrate the filters. - rv = filterService->OpenFilterList(&filterFileSpec, getter_AddRefs(filterList)); + rv = filterService->OpenFilterList(&filterFileSpec, folder, getter_AddRefs(filterList)); if (NS_FAILED(rv)) return rv; if (!filterList) return NS_ERROR_FAILURE; diff --git a/mailnews/base/util/nsMsgIncomingServer.cpp b/mailnews/base/util/nsMsgIncomingServer.cpp index 5245aa0944ad..79b11440b910 100644 --- a/mailnews/base/util/nsMsgIncomingServer.cpp +++ b/mailnews/base/util/nsMsgIncomingServer.cpp @@ -903,7 +903,7 @@ nsMsgIncomingServer::GetFilterList(nsIMsgFilterList **aResult) do_GetService(kMsgFilterServiceCID, &rv); NS_ENSURE_SUCCESS(rv, rv); - rv = filterService->OpenFilterList(&filterFile, getter_AddRefs(mFilterList)); + rv = filterService->OpenFilterList(&filterFile, msgFolder, getter_AddRefs(mFilterList)); NS_ENSURE_SUCCESS(rv, rv); } diff --git a/mailnews/imap/src/nsImapMailFolder.cpp b/mailnews/imap/src/nsImapMailFolder.cpp index afa28e6941d5..8d6fe3e91ec8 100644 --- a/mailnews/imap/src/nsImapMailFolder.cpp +++ b/mailnews/imap/src/nsImapMailFolder.cpp @@ -1814,8 +1814,7 @@ NS_IMETHODIMP nsImapMailFolder::SetupHeaderParseStream( rootDir->GetFileSpec(&filterFile); // need a file spec for filters... filterFile += "rules.dat"; - nsresult res; - res = filterService->OpenFilterList(&filterFile, getter_AddRefs(m_filterList)); + nsresult res = filterService->OpenFilterList(&filterFile, rootFolder, getter_AddRefs(m_filterList)); } } } @@ -1906,7 +1905,7 @@ NS_IMETHODIMP nsImapMailFolder::NormalEndHeaderParseStream(nsIImapProtocol* PRUint32 msgFlags; newMsgHdr->GetFlags(&msgFlags); - if (!(msgFlags & MSG_FLAG_READ)) // only fire on unread msgs + if (!(msgFlags & (MSG_FLAG_READ || MSG_FLAG_IMAP_DELETED))) // only fire on unread msgs that haven't been deleted { rv = m_msgParser->GetAllHeaders(&headers, &headersSize); @@ -2196,10 +2195,10 @@ NS_IMETHODIMP nsImapMailFolder::ApplyFilterHit(nsIMsgFilter *filter, PRBool *app case nsMsgFilterAction::MoveToFolder: { // if moving to a different file, do it. - PRUnichar *folderName = nsnull; - rv = GetName(&folderName); + nsXPIDLCString uri; + rv = GetURI(getter_Copies(uri)); - if (value && nsCRT::strcasecmp(folderName, (char *) value)) + if (value && nsCRT::strcasecmp((const char *) uri, (const char *) value)) { msgHdr->GetFlags(&msgFlags); @@ -2250,7 +2249,6 @@ NS_IMETHODIMP nsImapMailFolder::ApplyFilterHit(nsIMsgFilter *filter, PRBool *app } } - nsAllocator::Free(folderName); } break; case nsMsgFilterAction::MarkRead: @@ -2371,7 +2369,7 @@ nsresult nsImapMailFolder::StoreImapFlags(imapMessageFlagsType flags, PRBool add nsresult nsImapMailFolder::MoveIncorporatedMessage(nsIMsgDBHdr *mailHdr, nsIMsgDatabase *sourceDB, - char *destFolder, + char *destFolderUri, nsIMsgFilter *filter) { nsresult err = NS_OK; @@ -2381,22 +2379,15 @@ nsresult nsImapMailFolder::MoveIncorporatedMessage(nsIMsgDBHdr *mailHdr, if (m_moveCoalescer) { - // look for matching imap folders, then pop folders - nsCOMPtr server; - nsresult rv = GetServer(getter_AddRefs(server)); - - nsCOMPtr rootFolder; - if (NS_SUCCEEDED(rv)) - rv = server->GetRootFolder(getter_AddRefs(rootFolder)); + NS_WITH_SERVICE(nsIRDFService, rdf, kRDFServiceCID, &err); + nsCOMPtr res; + err = rdf->GetResource(destFolderUri, getter_AddRefs(res)); + if (NS_FAILED(err)) + return err; - if (!NS_SUCCEEDED(rv)) - return rv; - - nsCOMPtr destIFolder; - rootFolder->FindSubFolder (destFolder, getter_AddRefs(destIFolder)); - - nsCOMPtr msgFolder; - msgFolder = do_QueryInterface(destIFolder); + nsCOMPtr destIFolder(do_QueryInterface(res, &err)); + if (NS_FAILED(err)) + return err; if (destIFolder) { @@ -2405,11 +2396,11 @@ nsresult nsImapMailFolder::MoveIncorporatedMessage(nsIMsgDBHdr *mailHdr, nsMsgKey keyToFilter; mailHdr->GetMessageKey(&keyToFilter); - if (sourceDB && msgFolder) + if (sourceDB && destIFolder) { PRBool imapDeleteIsMoveToTrash = DeleteIsMoveToTrash(); - m_moveCoalescer->AddMove (msgFolder, keyToFilter); + m_moveCoalescer->AddMove (destIFolder, keyToFilter); // For each folder, we need to keep track of the ids we want to move to that // folder - we used to store them in the MSG_FolderInfo and then when we'd finished // downloading headers, we'd iterate through all the folders looking for the ones @@ -2426,7 +2417,7 @@ nsresult nsImapMailFolder::MoveIncorporatedMessage(nsIMsgDBHdr *mailHdr, { } - msgFolder->SetFlag(MSG_FOLDER_FLAG_GOT_NEW); + destIFolder->SetFlag(MSG_FOLDER_FLAG_GOT_NEW); if (imapDeleteIsMoveToTrash) err = 0; diff --git a/mailnews/local/src/nsParseMailbox.cpp b/mailnews/local/src/nsParseMailbox.cpp index 394e5fa49fe4..c1ef615118d9 100644 --- a/mailnews/local/src/nsParseMailbox.cpp +++ b/mailnews/local/src/nsParseMailbox.cpp @@ -46,13 +46,16 @@ #include "nsIMsgFilterList.h" #include "nsIMsgFilter.h" #include "nsIIOService.h" +#include "nsRDFCID.h" #include "nsIPref.h" +#include "nsIRDFService.h" static NS_DEFINE_CID(kCMailDB, NS_MAILDB_CID); static NS_DEFINE_CID(kMsgFilterServiceCID, NS_MSGFILTERSERVICE_CID); static NS_DEFINE_CID(kPrefServiceCID, NS_PREF_CID); static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID); +static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID); /* the following macros actually implement addref, release and query interface for our component. */ NS_IMPL_ISUPPORTS_INHERITED(nsMsgMailboxParser, nsParseMailMessageState, nsIStreamListener); @@ -306,11 +309,11 @@ void nsMsgMailboxParser::FreeBuffers() void nsMsgMailboxParser::UpdateDBFolderInfo() { - UpdateDBFolderInfo(m_mailDB, m_mailboxName); + UpdateDBFolderInfo(m_mailDB); } // update folder info in db so we know not to reparse. -void nsMsgMailboxParser::UpdateDBFolderInfo(nsIMsgDatabase *mailDB, const char *mailboxName) +void nsMsgMailboxParser::UpdateDBFolderInfo(nsIMsgDatabase *mailDB) { // ### wrong - use method on db. mailDB->SetSummaryValid(PR_TRUE); @@ -1450,7 +1453,7 @@ nsParseNewMailState::Init(nsIFolder *rootFolder, nsFileSpec &folder, nsIOFileStr // need a file spec for filters... filterFile += "rules.dat"; nsresult res; - res = filterService->OpenFilterList(&filterFile, getter_AddRefs(m_filterList)); + res = filterService->OpenFilterList(&filterFile, rootMsgFolder, getter_AddRefs(m_filterList)); } m_logFile = nsnull; @@ -1798,16 +1801,31 @@ int nsParseNewMailState::MarkFilteredMessageRead(nsIMsgDBHdr *msgHdr) nsresult nsParseNewMailState::MoveIncorporatedMessage(nsIMsgDBHdr *mailHdr, nsIMsgDatabase *sourceDB, - char *destFolder, + char *destFolderUri, nsIMsgFilter *filter) { - int err = 0; + nsresult err = 0; nsIOFileStream *destFile; - nsCOMPtr destIFolder; - nsCOMPtr lockedFolder; - m_rootFolder->FindSubFolder (destFolder, getter_AddRefs(destIFolder)); - lockedFolder = do_QueryInterface(destIFolder); + NS_WITH_SERVICE(nsIRDFService, rdf, kRDFServiceCID, &err); + nsCOMPtr res; + err = rdf->GetResource(destFolderUri, getter_AddRefs(res)); + if (NS_FAILED(err)) + return err; + + nsCOMPtr destIFolder(do_QueryInterface(res, &err)); + if (NS_FAILED(err)) + return err; + + nsCOMPtr destIFolderSpec; + + nsFileSpec destFolderSpec; + destIFolder->GetPath(getter_AddRefs(destIFolderSpec)); + err = destIFolderSpec->GetFileSpec(&destFolderSpec); + + if (!NS_SUCCEEDED(err)) + return err; + nsISupports *myThis; QueryInterface(NS_GET_IID(nsISupports), (void **) &myThis); @@ -1816,7 +1834,7 @@ nsresult nsParseNewMailState::MoveIncorporatedMessage(nsIMsgDBHdr *mailHdr, // NS_RELEASE(myThis); // Make sure no one else is writing into this folder - if (lockedFolder && (err = lockedFolder->AcquireSemaphore (myISupports)) != 0) + if (destIFolder && (err = destIFolder->AcquireSemaphore (myISupports)) != 0) return err; NS_ASSERTION(m_inboxFileStream != 0, "no input file stream"); @@ -1825,8 +1843,8 @@ nsresult nsParseNewMailState::MoveIncorporatedMessage(nsIMsgDBHdr *mailHdr, #ifdef DEBUG_bienvenu NS_ASSERTION(PR_FALSE, "couldn't get source file in move filter"); #endif - if (lockedFolder) - lockedFolder->ReleaseSemaphore (myISupports); + if (destIFolder) + destIFolder->ReleaseSemaphore (myISupports); return NS_MSG_FOLDER_UNREADABLE; // ### dmb } @@ -1837,12 +1855,6 @@ nsresult nsParseNewMailState::MoveIncorporatedMessage(nsIMsgDBHdr *mailHdr, m_inboxFileStream->seek(PR_SEEK_SET, messageOffset); int newMsgPos; - nsFileSpec rootDirectory; - m_inboxFileSpec.GetParent(rootDirectory); - nsFileSpec destFolderSpec(rootDirectory); - // ### Not sure this will work if destFolder is a sub-folder -// destFolderSpec.SetLeafName(destFolder); - destFolderSpec += destFolder; destFile = new nsIOFileStream(destFolderSpec, PR_WRONLY | PR_CREATE_FILE); if (!destFile) @@ -1850,8 +1862,8 @@ nsresult nsParseNewMailState::MoveIncorporatedMessage(nsIMsgDBHdr *mailHdr, #ifdef DEBUG_bienvenu NS_ASSERTION(PR_FALSE, "out of memory"); #endif - if (lockedFolder) - lockedFolder->ReleaseSemaphore (myISupports); + if (destIFolder) + destIFolder->ReleaseSemaphore (myISupports); return NS_MSG_ERROR_WRITING_MAIL_FOLDER; } @@ -1898,8 +1910,8 @@ nsresult nsParseNewMailState::MoveIncorporatedMessage(nsIMsgDBHdr *mailHdr, // ### how to do this with a stream? destFolderSpec.Truncate(newMsgPos); - if (lockedFolder) - lockedFolder->ReleaseSemaphore(myISupports); + if (destIFolder) + destIFolder->ReleaseSemaphore(myISupports); if (destMailDB) destMailDB->Close(PR_TRUE); @@ -1947,22 +1959,22 @@ nsresult nsParseNewMailState::MoveIncorporatedMessage(nsIMsgDBHdr *mailHdr, if (m_inboxFileStream) m_inboxFileStream->seek(m_inboxFileSpec.GetFileSize()); - if (lockedFolder) - lockedFolder->ReleaseSemaphore (myISupports); + if (destIFolder) + destIFolder->ReleaseSemaphore (myISupports); // tell parser that we've truncated the Inbox mailHdr->GetMessageOffset(&messageOffset); nsParseMailMessageState::Init(messageOffset); - if (lockedFolder) - lockedFolder->SetFlag(MSG_FOLDER_FLAG_GOT_NEW); + if (destIFolder) + destIFolder->SetFlag(MSG_FOLDER_FLAG_GOT_NEW); if (destMailDB != nsnull) { // update the folder size so we won't reparse. - UpdateDBFolderInfo(destMailDB, destFolder); - if (lockedFolder != nsnull) - lockedFolder->SummaryChanged(); + UpdateDBFolderInfo(destMailDB); + if (destIFolder != nsnull) + destIFolder->SummaryChanged(); destMailDB->Close(PR_TRUE); } diff --git a/mailnews/local/src/nsParseMailbox.h b/mailnews/local/src/nsParseMailbox.h index 60b2b54f66c2..54252f67cf32 100644 --- a/mailnews/local/src/nsParseMailbox.h +++ b/mailnews/local/src/nsParseMailbox.h @@ -173,7 +173,7 @@ public: virtual PRInt32 HandleLine(char *line, PRUint32 line_length); void UpdateDBFolderInfo(); - void UpdateDBFolderInfo(nsIMsgDatabase *mailDB, const char *mailboxName); + void UpdateDBFolderInfo(nsIMsgDatabase *mailDB); void UpdateStatusText (PRUint32 stringID); // Update the progress bar based on what we know.