RetroZilla/mailnews/base/search/src/nsMsgSearchSession.cpp
2015-10-20 23:03:22 -04:00

765 lines
22 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 2000
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Howard Chu <hyc@symas.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "msgCore.h"
#include "nsMsgSearchCore.h"
#include "nsMsgSearchAdapter.h"
#include "nsMsgSearchBoolExpression.h"
#include "nsMsgSearchSession.h"
#include "nsMsgResultElement.h"
#include "nsMsgSearchTerm.h"
#include "nsMsgSearchScopeTerm.h"
#include "nsIMsgMessageService.h"
#include "nsMsgUtils.h"
#include "nsXPIDLString.h"
#include "nsIMsgSearchNotify.h"
#include "nsIMsgMailSession.h"
#include "nsMsgBaseCID.h"
#include "nsMsgFolderFlags.h"
#include "nsMsgLocalSearch.h"
NS_IMPL_ISUPPORTS3(nsMsgSearchSession, nsIMsgSearchSession, nsIUrlListener, nsISupportsWeakReference)
nsMsgSearchSession::nsMsgSearchSession()
{
m_sortAttribute = nsMsgSearchAttrib::Sender;
m_idxRunningScope = 0;
m_urlQueueIndex = 0;
m_handlingError = PR_FALSE;
m_expressionTree = nsnull;
m_searchPaused = PR_FALSE;
NS_NewISupportsArray(getter_AddRefs(m_termList));
}
nsMsgSearchSession::~nsMsgSearchSession()
{
InterruptSearch();
delete m_expressionTree;
DestroyResultList ();
DestroyScopeList ();
DestroyTermList ();
}
/* [noscript] void AddSearchTerm (in nsMsgSearchAttribute attrib, in nsMsgSearchOperator op, in nsMsgSearchValue value, in boolean BooleanAND, in string arbitraryHeader); */
NS_IMETHODIMP
nsMsgSearchSession::AddSearchTerm(nsMsgSearchAttribValue attrib,
nsMsgSearchOpValue op,
nsIMsgSearchValue * value,
PRBool BooleanANDp,
const char *arbitraryHeader)
{
// stupid gcc
nsMsgSearchBooleanOperator boolOp;
if (BooleanANDp)
boolOp = (nsMsgSearchBooleanOperator)nsMsgSearchBooleanOp::BooleanAND;
else
boolOp = (nsMsgSearchBooleanOperator)nsMsgSearchBooleanOp::BooleanOR;
nsMsgSearchTerm *pTerm = new nsMsgSearchTerm (attrib, op, value,
boolOp, arbitraryHeader);
if (nsnull == pTerm)
return NS_ERROR_OUT_OF_MEMORY;
m_termList->AppendElement (pTerm);
// force the expression tree to rebuild whenever we change the terms
delete m_expressionTree;
m_expressionTree = nsnull;
return NS_OK;
}
NS_IMETHODIMP
nsMsgSearchSession::AppendTerm(nsIMsgSearchTerm *aTerm)
{
NS_ENSURE_ARG_POINTER(aTerm);
NS_ENSURE_TRUE(m_termList, NS_ERROR_NOT_INITIALIZED);
delete m_expressionTree;
m_expressionTree = nsnull;
return m_termList->AppendElement(aTerm);
}
NS_IMETHODIMP
nsMsgSearchSession::GetSearchTerms(nsISupportsArray **aResult)
{
NS_ENSURE_ARG_POINTER(aResult);
*aResult = m_termList;
NS_ADDREF(*aResult);
return NS_OK;
}
NS_IMETHODIMP
nsMsgSearchSession::CreateTerm(nsIMsgSearchTerm **aResult)
{
nsMsgSearchTerm *term = new nsMsgSearchTerm;
NS_ENSURE_TRUE(term, NS_ERROR_OUT_OF_MEMORY);
*aResult = NS_STATIC_CAST(nsIMsgSearchTerm*,term);
NS_ADDREF(*aResult);
return NS_OK;
}
/* void RegisterListener (in nsIMsgSearchNotify listener); */
NS_IMETHODIMP nsMsgSearchSession::RegisterListener(nsIMsgSearchNotify *listener)
{
nsresult ret = NS_OK;
if (!m_listenerList)
ret = NS_NewISupportsArray(getter_AddRefs(m_listenerList));
if (NS_SUCCEEDED(ret) && m_listenerList)
m_listenerList->AppendElement(listener);
return ret;
}
/* void UnregisterListener (in nsIMsgSearchNotify listener); */
NS_IMETHODIMP nsMsgSearchSession::UnregisterListener(nsIMsgSearchNotify *listener)
{
if (m_listenerList)
m_listenerList->RemoveElement(listener);
return NS_OK;
}
/* readonly attribute long numSearchTerms; */
NS_IMETHODIMP nsMsgSearchSession::GetNumSearchTerms(PRUint32 *aNumSearchTerms)
{
NS_ENSURE_ARG(aNumSearchTerms);
return m_termList->Count(aNumSearchTerms);
}
/* [noscript] void GetNthSearchTerm (in long whichTerm, in nsMsgSearchAttribute attrib, in nsMsgSearchOperator op, in nsMsgSearchValue value); */
NS_IMETHODIMP
nsMsgSearchSession::GetNthSearchTerm(PRInt32 whichTerm,
nsMsgSearchAttribValue attrib,
nsMsgSearchOpValue op,
nsIMsgSearchValue * value)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
/* long CountSearchScopes (); */
NS_IMETHODIMP nsMsgSearchSession::CountSearchScopes(PRInt32 *_retval)
{
NS_ENSURE_ARG(_retval);
*_retval = m_scopeList.Count();
return NS_OK;
}
/* void GetNthSearchScope (in long which, out nsMsgSearchScope scopeId, out nsIMsgFolder folder); */
NS_IMETHODIMP
nsMsgSearchSession::GetNthSearchScope(PRInt32 which,
nsMsgSearchScopeValue *scopeId,
nsIMsgFolder **folder)
{
// argh, does this do an addref?
nsMsgSearchScopeTerm *scopeTerm = (nsMsgSearchScopeTerm *) m_scopeList.SafeElementAt(which);
if (!scopeTerm) return NS_ERROR_INVALID_ARG;
*scopeId = scopeTerm->m_attribute;
*folder = scopeTerm->m_folder;
NS_IF_ADDREF(*folder);
return NS_OK;
}
/* void AddScopeTerm (in nsMsgSearchScopeValue scope, in nsIMsgFolder folder); */
NS_IMETHODIMP
nsMsgSearchSession::AddScopeTerm(nsMsgSearchScopeValue scope,
nsIMsgFolder *folder)
{
if (scope != nsMsgSearchScope::allSearchableGroups)
{
NS_ASSERTION(folder, "need folder if not searching all groups");
if (!folder)
return NS_ERROR_NULL_POINTER;
}
nsMsgSearchScopeTerm *pScopeTerm = new nsMsgSearchScopeTerm(this, scope, folder);
if (!pScopeTerm)
return NS_ERROR_OUT_OF_MEMORY;
m_scopeList.AppendElement(pScopeTerm);
return NS_OK;
}
NS_IMETHODIMP
nsMsgSearchSession::AddDirectoryScopeTerm(nsMsgSearchScopeValue scope)
{
nsMsgSearchScopeTerm *pScopeTerm = new nsMsgSearchScopeTerm(this, scope, nsnull);
if (!pScopeTerm)
return NS_ERROR_OUT_OF_MEMORY;
m_scopeList.AppendElement(pScopeTerm);
return NS_OK;
}
NS_IMETHODIMP nsMsgSearchSession::ClearScopes()
{
DestroyScopeList();
return NS_OK;
}
/* [noscript] boolean ScopeUsesCustomHeaders (in nsMsgSearchScope scope, in voidStar selection, in boolean forFilters); */
NS_IMETHODIMP
nsMsgSearchSession::ScopeUsesCustomHeaders(nsMsgSearchScopeValue scope,
void * selection,
PRBool forFilters,
PRBool *_retval)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
/* boolean IsStringAttribute (in nsMsgSearchAttribute attrib); */
NS_IMETHODIMP
nsMsgSearchSession::IsStringAttribute(nsMsgSearchAttribValue attrib,
PRBool *_retval)
{
NS_ENSURE_ARG(_retval);
return NS_ERROR_NOT_IMPLEMENTED;
}
/* void AddAllScopes (in nsMsgSearchScope attrib); */
NS_IMETHODIMP
nsMsgSearchSession::AddAllScopes(nsMsgSearchScopeValue attrib)
{
// don't think this is needed.
return NS_ERROR_NOT_IMPLEMENTED;
}
/* void Search (); */
NS_IMETHODIMP nsMsgSearchSession::Search(nsIMsgWindow *aWindow)
{
nsresult err = Initialize ();
NS_ENSURE_SUCCESS(err,err);
if (m_listenerList) {
PRUint32 count;
m_listenerList->Count(&count);
for (PRUint32 i=0; i<count;i++) {
nsCOMPtr<nsIMsgSearchNotify> listener;
m_listenerList->QueryElementAt(i, NS_GET_IID(nsIMsgSearchNotify),
(void **)getter_AddRefs(listener));
if (listener)
listener->OnNewSearch();
}
}
m_window = aWindow;
if (NS_SUCCEEDED(err))
err = BeginSearching ();
return err;
}
/* void InterruptSearch (); */
NS_IMETHODIMP nsMsgSearchSession::InterruptSearch()
{
if (m_window)
{
EnableFolderNotifications(PR_TRUE);
if (m_idxRunningScope < m_scopeList.Count())
m_window->StopUrls();
while (m_idxRunningScope < m_scopeList.Count())
{
ReleaseFolderDBRef();
m_idxRunningScope++;
}
//m_idxRunningScope = m_scopeList.Count() so it will make us not run another url
}
if (m_backgroundTimer)
{
m_backgroundTimer->Cancel();
NotifyListenersDone(NS_OK); // ### is there a cancelled status?
m_backgroundTimer = nsnull;
}
return NS_OK;
}
NS_IMETHODIMP nsMsgSearchSession::PauseSearch()
{
if (m_backgroundTimer)
{
m_backgroundTimer->Cancel();
m_searchPaused = PR_TRUE;
return NS_OK;
}
else
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP nsMsgSearchSession::ResumeSearch()
{
if (m_searchPaused)
{
m_searchPaused = PR_FALSE;
return StartTimer();
}
else
return NS_ERROR_FAILURE;
}
/* [noscript] readonly attribute voidStar searchParam; */
NS_IMETHODIMP nsMsgSearchSession::GetSearchParam(void * *aSearchParam)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
/* readonly attribute nsMsgSearchType searchType; */
NS_IMETHODIMP nsMsgSearchSession::GetSearchType(nsMsgSearchType * *aSearchType)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
/* [noscript] nsMsgSearchType SetSearchParam (in nsMsgSearchType type, in voidStar param); */
NS_IMETHODIMP nsMsgSearchSession::SetSearchParam(nsMsgSearchType *type, void * param, nsMsgSearchType **_retval)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
/* readonly attribute long numResults; */
NS_IMETHODIMP nsMsgSearchSession::GetNumResults(PRInt32 *aNumResults)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsMsgSearchSession::SetWindow(nsIMsgWindow *aWindow)
{
m_window = aWindow;
return NS_OK;
}
NS_IMETHODIMP nsMsgSearchSession::GetWindow(nsIMsgWindow **aWindowPtr)
{
NS_ENSURE_ARG(aWindowPtr);
*aWindowPtr = m_window;
NS_IF_ADDREF(*aWindowPtr);
return NS_OK;
}
/* void OnStartRunningUrl (in nsIURI url); */
NS_IMETHODIMP nsMsgSearchSession::OnStartRunningUrl(nsIURI *url)
{
return NS_OK;
}
/* void OnStopRunningUrl (in nsIURI url, in nsresult aExitCode); */
NS_IMETHODIMP nsMsgSearchSession::OnStopRunningUrl(nsIURI *url, nsresult aExitCode)
{
nsCOMPtr <nsIMsgSearchAdapter> runningAdapter;
nsresult rv = GetRunningAdapter (getter_AddRefs(runningAdapter));
// tell the current adapter that the current url has run.
if (NS_SUCCEEDED(rv) && runningAdapter)
{
runningAdapter->CurrentUrlDone(aExitCode);
EnableFolderNotifications(PR_TRUE);
ReleaseFolderDBRef();
}
m_idxRunningScope++;
if (++m_urlQueueIndex < m_urlQueue.Count())
GetNextUrl();
else if (m_idxRunningScope < m_scopeList.Count())
DoNextSearch();
else
NotifyListenersDone(aExitCode);
return NS_OK;
}
nsresult nsMsgSearchSession::Initialize()
{
// Loop over scope terms, initializing an adapter per term. This
// architecture is necessitated by two things:
// 1. There might be more than one kind of adapter per if online
// *and* offline mail mail folders are selected, or if newsgroups
// belonging to Dredd *and* INN are selected
// 2. Most of the protocols are only capable of searching one scope at a
// time, so we'll do each scope in a separate adapter on the client
nsMsgSearchScopeTerm *scopeTerm = nsnull;
nsresult err = NS_OK;
PRUint32 numTerms;
m_termList->Count(&numTerms);
// Ensure that the FE has added scopes and terms to this search
NS_ASSERTION(numTerms > 0, "no terms to search!");
if (numTerms == 0)
return NS_MSG_ERROR_NO_SEARCH_VALUES;
// if we don't have any search scopes to search, return that code.
if (m_scopeList.Count() == 0)
return NS_MSG_ERROR_INVALID_SEARCH_SCOPE;
m_urlQueue.Clear(); // clear out old urls, if any.
m_idxRunningScope = 0;
m_urlQueueIndex = 0;
// If this term list (loosely specified here by the first term) should be
// scheduled in parallel, build up a list of scopes to do the round-robin scheduling
for (int i = 0; i < m_scopeList.Count() && NS_SUCCEEDED(err); i++)
{
scopeTerm = m_scopeList.ElementAt(i);
// NS_ASSERTION(scopeTerm->IsValid());
err = scopeTerm->InitializeAdapter (m_termList);
}
return err;
}
nsresult nsMsgSearchSession::BeginSearching()
{
// Here's a sloppy way to start the URL, but I don't really have time to
// unify the scheduling mechanisms. If the first scope is a newsgroup, and
// it's not Dredd-capable, we build the URL queue. All other searches can be
// done with one URL
if (m_window)
m_window->SetStopped(PR_FALSE);
return DoNextSearch();
}
nsresult nsMsgSearchSession::DoNextSearch()
{
nsMsgSearchScopeTerm *scope = m_scopeList.ElementAt(m_idxRunningScope);
if (scope->m_attribute == nsMsgSearchScope::onlineMail ||
(scope->m_attribute == nsMsgSearchScope::news && scope->m_searchServer))
return BuildUrlQueue ();
else
return SearchWOUrls();
}
nsresult nsMsgSearchSession::BuildUrlQueue ()
{
PRInt32 i;
for (i = m_idxRunningScope; i < m_scopeList.Count(); i++)
{
nsMsgSearchScopeTerm *scope = m_scopeList.ElementAt(i);
if (scope->m_attribute != nsMsgSearchScope::onlineMail &&
(scope->m_attribute != nsMsgSearchScope::news && scope->m_searchServer))
break;
nsCOMPtr <nsIMsgSearchAdapter> adapter = do_QueryInterface((m_scopeList.ElementAt(i))->m_adapter);
nsXPIDLCString url;
if (adapter)
{
adapter->GetEncoding(getter_Copies(url));
AddUrl (url);
}
}
if (i > 0)
GetNextUrl();
return NS_OK;
}
nsresult nsMsgSearchSession::GetNextUrl()
{
nsCString nextUrl;
nsCOMPtr <nsIMsgMessageService> msgService;
PRBool stopped = PR_FALSE;
if (m_window)
m_window->GetStopped(&stopped);
if (stopped)
return NS_OK;
m_urlQueue.CStringAt(m_urlQueueIndex, nextUrl);
nsMsgSearchScopeTerm *currentTerm = GetRunningScope();
EnableFolderNotifications(PR_FALSE);
nsCOMPtr <nsIMsgFolder> folder = currentTerm->m_folder;
if (folder)
{
nsXPIDLCString folderUri;
folder->GetURI(getter_Copies(folderUri));
nsresult rv = GetMessageServiceFromURI(folderUri.get(), getter_AddRefs(msgService));
if (NS_SUCCEEDED(rv) && msgService && currentTerm)
msgService->Search(this, m_window, currentTerm->m_folder, nextUrl.get());
return rv;
}
return NS_OK;
}
nsresult nsMsgSearchSession::AddUrl(const char *url)
{
nsCString urlCString(url);
m_urlQueue.AppendCString(urlCString);
return NS_OK;
}
/* static */ void nsMsgSearchSession::TimerCallback(nsITimer *aTimer, void *aClosure)
{
nsMsgSearchSession *searchSession = (nsMsgSearchSession *) aClosure;
PRBool done;
PRBool stopped = PR_FALSE;
searchSession->TimeSlice(&done);
if (searchSession->m_window)
searchSession->m_window->GetStopped(&stopped);
if (done || stopped)
{
aTimer->Cancel();
searchSession->m_backgroundTimer = nsnull;
if (searchSession->m_idxRunningScope < searchSession->m_scopeList.Count())
searchSession->DoNextSearch();
else
searchSession->NotifyListenersDone(NS_OK);
}
}
nsresult nsMsgSearchSession::StartTimer()
{
nsresult err;
PRBool done;
m_backgroundTimer = do_CreateInstance("@mozilla.org/timer;1", &err);
m_backgroundTimer->InitWithFuncCallback(TimerCallback, (void *) this, 0,
nsITimer::TYPE_REPEATING_SLACK);
// ### start meteors?
return TimeSlice(&done);
}
nsresult nsMsgSearchSession::SearchWOUrls ()
{
EnableFolderNotifications(PR_FALSE);
return StartTimer();
}
NS_IMETHODIMP nsMsgSearchSession::GetRunningAdapter (nsIMsgSearchAdapter **aSearchAdapter)
{
NS_ENSURE_ARG(aSearchAdapter);
nsMsgSearchScopeTerm *scope = GetRunningScope();
if (scope)
{
NS_ADDREF(*aSearchAdapter = scope->m_adapter);
return NS_OK;
}
*aSearchAdapter = nsnull;
return NS_OK;
}
NS_IMETHODIMP nsMsgSearchSession::AddSearchHit(nsIMsgDBHdr *header, nsIMsgFolder *folder)
{
if (m_listenerList)
{
PRUint32 count;
m_listenerList->Count(&count);
for (PRUint32 i = 0; i < count; i++)
{
nsCOMPtr<nsIMsgSearchNotify> pListener;
m_listenerList->QueryElementAt(i, NS_GET_IID(nsIMsgSearchNotify),
(void **)getter_AddRefs(pListener));
if (pListener)
pListener->OnSearchHit(header, folder);
}
}
return NS_OK;
}
nsresult nsMsgSearchSession::NotifyListenersDone(nsresult status)
{
if (m_listenerList)
{
PRUint32 count;
m_listenerList->Count(&count);
for (PRUint32 i = 0; i < count; i++)
{
nsCOMPtr<nsIMsgSearchNotify> pListener;
m_listenerList->QueryElementAt(i, NS_GET_IID(nsIMsgSearchNotify),
(void **)getter_AddRefs(pListener));
if (pListener)
pListener->OnSearchDone(status);
}
}
return NS_OK;
}
NS_IMETHODIMP nsMsgSearchSession::AddResultElement (nsMsgResultElement *element)
{
NS_ASSERTION(element, "no null elements");
m_resultList.AppendElement (element);
return NS_OK;
}
void nsMsgSearchSession::DestroyResultList ()
{
nsMsgResultElement *result = nsnull;
for (int i = 0; i < m_resultList.Count(); i++)
{
result = m_resultList.ElementAt(i);
// NS_ASSERTION (result->IsValid(), "invalid search result");
delete result;
}
m_resultList.Clear();
}
void nsMsgSearchSession::DestroyScopeList()
{
nsMsgSearchScopeTerm *scope = NULL;
PRInt32 count = m_scopeList.Count();
for (PRInt32 i = count-1; i >= 0; i--)
{
scope = m_scopeList.ElementAt(i);
// NS_ASSERTION (scope->IsValid(), "invalid search scope");
delete scope;
}
m_scopeList.Clear();
}
void nsMsgSearchSession::DestroyTermList ()
{
m_termList->Clear();
}
nsMsgSearchScopeTerm *nsMsgSearchSession::GetRunningScope()
{
return (nsMsgSearchScopeTerm *) m_scopeList.SafeElementAt(m_idxRunningScope);
}
nsresult nsMsgSearchSession::TimeSlice (PRBool *aDone)
{
// we only do serial for now.
return TimeSliceSerial(aDone);
}
void nsMsgSearchSession::ReleaseFolderDBRef()
{
nsMsgSearchScopeTerm *scope = GetRunningScope();
if (scope)
{
PRBool isOpen =PR_FALSE;
PRUint32 flags;
nsCOMPtr <nsIMsgFolder> folder;
scope->GetFolder(getter_AddRefs(folder));
nsCOMPtr <nsIMsgMailSession> mailSession = do_GetService(NS_MSGMAILSESSION_CONTRACTID);
if (mailSession && folder)
{
mailSession->IsFolderOpenInWindow(folder, &isOpen);
folder->GetFlags(&flags);
/*we don't null out the db reference for inbox because inbox is like the "main" folder
and performance outweighs footprint */
if (!isOpen && !(MSG_FOLDER_FLAG_INBOX & flags))
folder->SetMsgDatabase(nsnull);
}
}
}
nsresult nsMsgSearchSession::TimeSliceSerial (PRBool *aDone)
{
// This version of TimeSlice runs each scope term one at a time, and waits until one
// scope term is finished before starting another one. When we're searching the local
// disk, this is the fastest way to do it.
NS_ENSURE_ARG(aDone);
nsresult rv = NS_OK;
nsMsgSearchScopeTerm *scope = GetRunningScope();
if (scope)
{
rv = scope->TimeSlice (aDone);
if (NS_FAILED(rv))
*aDone = PR_TRUE;
if (*aDone || NS_FAILED(rv))
{
EnableFolderNotifications(PR_TRUE);
ReleaseFolderDBRef();
m_idxRunningScope++;
EnableFolderNotifications(PR_FALSE);
// check if the next scope is an online search; if so,
// set *aDone to true so that we'll try to run the next
// search in TimerCallback.
scope = GetRunningScope();
if (scope && (scope->m_attribute == nsMsgSearchScope::onlineMail ||
(scope->m_attribute == nsMsgSearchScope::news && scope->m_searchServer)))
{
*aDone = PR_TRUE;
return rv;
}
}
*aDone = PR_FALSE;
return rv;
}
else
{
*aDone = PR_TRUE;
return NS_OK;
}
}
void
nsMsgSearchSession::EnableFolderNotifications(PRBool aEnable)
{
nsMsgSearchScopeTerm *scope = GetRunningScope();
if (scope)
{
nsCOMPtr<nsIMsgFolder> folder;
scope->GetFolder(getter_AddRefs(folder));
if (folder) //enable msg count notifications
folder->EnableNotifications(nsIMsgFolder::allMessageCountNotifications, aEnable, PR_FALSE);
}
}
//this method is used for adding new hdrs to quick search view
NS_IMETHODIMP
nsMsgSearchSession::MatchHdr(nsIMsgDBHdr *aMsgHdr, nsIMsgDatabase *aDatabase, PRBool *aResult)
{
nsMsgSearchScopeTerm *scope = (nsMsgSearchScopeTerm *)m_scopeList.SafeElementAt(0);
if (scope)
{
if (!scope->m_adapter)
scope->InitializeAdapter(m_termList);
if (scope->m_adapter)
{
nsXPIDLString nullCharset, folderCharset;
scope->m_adapter->GetSearchCharsets(getter_Copies(nullCharset), getter_Copies(folderCharset));
NS_ConvertUCS2toUTF8 charset(folderCharset.get());
nsMsgSearchOfflineMail::MatchTermsForSearch(aMsgHdr, m_termList, charset.get(), scope, aDatabase, &m_expressionTree, aResult);
}
}
return NS_OK;
}