зеркало из https://github.com/mozilla/gecko-dev.git
more work on search BE, 33101 r=alecf parse local folders before searching
This commit is contained in:
Родитель
c557ad7fb9
Коммит
a2394b0581
|
@ -89,7 +89,15 @@ interface nsIMsgSearchSession : nsISupports {
|
|||
|
||||
void Search(in nsIMsgWindow aWindow);
|
||||
void InterruptSearch();
|
||||
|
||||
|
||||
// these two methods are used when the search session is using
|
||||
// a timer to do local search, and the search adapter needs
|
||||
// to run a url (e.g., to reparse a local folder) and wants to
|
||||
// pause the timer while running the url. This will fail if the
|
||||
// current adapter is not using a timer.
|
||||
void PauseSearch();
|
||||
void ResumeSearch();
|
||||
|
||||
[noscript] readonly attribute voidPtr searchParam;
|
||||
readonly attribute nsMsgSearchType searchType;
|
||||
|
||||
|
@ -101,6 +109,7 @@ interface nsIMsgSearchSession : nsISupports {
|
|||
void AddSearchHit(in nsIMsgDBHdr header, in nsIMsgFolder folder);
|
||||
|
||||
readonly attribute long numResults;
|
||||
attribute nsIMsgWindow window;
|
||||
|
||||
/* these longs are all actually of type nsMsgSearchBooleanOp */
|
||||
const long BooleanOR=0;
|
||||
|
|
|
@ -35,6 +35,8 @@
|
|||
|
||||
#include "nsMsgBaseCID.h"
|
||||
#include "nsMsgSearchValue.h"
|
||||
#include "nsIMsgLocalMailFolder.h"
|
||||
#include "nsIMsgWindow.h"
|
||||
|
||||
static NS_DEFINE_CID(kValidityManagerCID, NS_MSGSEARCHVALIDITYMANAGER_CID);
|
||||
|
||||
|
@ -237,6 +239,7 @@ PRInt32 nsMsgSearchBoolExpression::GenerateEncodeStr(nsCString * buffer)
|
|||
|
||||
//---------------- Adapter class for searching offline IMAP folders -----------
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
nsMsgSearchIMAPOfflineMail::nsMsgSearchIMAPOfflineMail (nsIMsgSearchScopeTerm *scope, nsISupportsArray *termList) : nsMsgSearchOfflineMail(scope, termList)
|
||||
{
|
||||
|
||||
|
@ -292,13 +295,12 @@ nsresult nsMsgSearchIMAPOfflineMail::ValidateTerms ()
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED(nsMsgSearchOfflineMail, nsMsgSearchAdapter, nsIUrlListener)
|
||||
|
||||
nsMsgSearchOfflineMail::nsMsgSearchOfflineMail (nsIMsgSearchScopeTerm *scope, nsISupportsArray *termList) : nsMsgSearchAdapter (scope, termList)
|
||||
{
|
||||
m_db = nsnull;
|
||||
m_listContext = nsnull;
|
||||
|
||||
m_mailboxParser = nsnull;
|
||||
m_parserState = kOpenFolderState;
|
||||
}
|
||||
|
||||
|
||||
|
@ -373,26 +375,22 @@ nsresult nsMsgSearchOfflineMail::OpenSummaryFile ()
|
|||
break;
|
||||
case NS_MSG_ERROR_FOLDER_SUMMARY_MISSING:
|
||||
case NS_MSG_ERROR_FOLDER_SUMMARY_OUT_OF_DATE:
|
||||
#ifdef HANDLE_OUT_OF_DATE_SUMMARY_FILES // which we don't yet.
|
||||
m_mailboxParser = new nsMsgMailboxParser (m_scope->GetMailPath());
|
||||
if (!m_mailboxParser)
|
||||
err = NS_ERROR_OUT_OF_MEMORY;
|
||||
else
|
||||
{
|
||||
nsCOMPtr<nsIMsgLocalMailFolder> localFolder = do_QueryInterface(scopeFolder, &err);
|
||||
if (NS_SUCCEEDED(err) && localFolder)
|
||||
{
|
||||
// Remove the old summary file so maildb::open can create a new one
|
||||
XP_FileRemove (m_scope->GetMailPath(), xpMailFolderSummary);
|
||||
dbErr = MailDB::Open (m_scope->GetMailPath(), PR_TRUE /*create?*/, &mailDb, PR_TRUE /*upgrading?*/);
|
||||
NS_ASSERTION(mailDb, "couldn't opn DB");
|
||||
nsCOMPtr<nsIMsgSearchSession> searchSession;
|
||||
m_scope->GetSearchSession(getter_AddRefs(searchSession));
|
||||
if (searchSession)
|
||||
{
|
||||
nsCOMPtr <nsIMsgWindow> searchWindow;
|
||||
|
||||
// Initialize the async parser to rebuild the summary file
|
||||
m_parserState = kOpenFolderState;
|
||||
m_mailboxParser->SetContext (m_scope->m_frame->GetContext());
|
||||
m_mailboxParser->SetDB (mailDb);
|
||||
m_mailboxParser->SetFolder(m_scope->m_folder);
|
||||
m_mailboxParser->SetIgnoreNonMailFolder(PR_TRUE);
|
||||
err = NS_OK;
|
||||
searchSession->GetWindow(getter_AddRefs(searchWindow));
|
||||
searchSession->PauseSearch();
|
||||
localFolder->ParseFolder(searchWindow, this);
|
||||
}
|
||||
}
|
||||
#endif // HANDLE_OUT_OF_DATE_SUMMARY_FILES
|
||||
}
|
||||
break;
|
||||
default:
|
||||
{
|
||||
|
@ -656,19 +654,14 @@ nsresult nsMsgSearchOfflineMail::Search (PRBool *aDone)
|
|||
nsCOMPtr<nsIMsgDBHdr> msgDBHdr;
|
||||
|
||||
*aDone = PR_FALSE;
|
||||
// If we need to parse the mailbox before searching it, give another time
|
||||
// slice to the parser
|
||||
if (m_mailboxParser)
|
||||
err = BuildSummaryFile ();
|
||||
else
|
||||
// Try to open the DB lazily. This will set up a parser if one is required
|
||||
if (!m_db)
|
||||
err = OpenSummaryFile ();
|
||||
// Try to open the DB lazily. This will set up a parser if one is required
|
||||
if (!m_db)
|
||||
err = OpenSummaryFile ();
|
||||
if (!m_db) // must be reparsing.
|
||||
return err;
|
||||
// Reparsing is unnecessary or completed
|
||||
if (m_mailboxParser == nsnull && NS_SUCCEEDED(err))
|
||||
if (NS_SUCCEEDED(err))
|
||||
{
|
||||
NS_ASSERTION (m_db, "unable to open db for search");
|
||||
|
||||
if (!m_listContext)
|
||||
dbErr = m_db->EnumerateMessages (getter_AddRefs(m_listContext));
|
||||
if (NS_SUCCEEDED(dbErr) && m_listContext)
|
||||
|
@ -753,12 +746,24 @@ nsMsgSearchOfflineMail::Abort ()
|
|||
m_db->Close(PR_TRUE /* commit in case we downloaded new headers */);
|
||||
m_db = nsnull;
|
||||
|
||||
// If we got aborted in the middle of parsing a mail folder, we should
|
||||
// free the parser object (esp. so it releases the folderInfo's semaphore)
|
||||
if (m_mailboxParser)
|
||||
delete m_mailboxParser;
|
||||
m_mailboxParser = nsnull;
|
||||
|
||||
return nsMsgSearchAdapter::Abort ();
|
||||
}
|
||||
|
||||
/* void OnStartRunningUrl (in nsIURI url); */
|
||||
NS_IMETHODIMP nsMsgSearchOfflineMail::OnStartRunningUrl(nsIURI *url)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void OnStopRunningUrl (in nsIURI url, in nsresult aExitCode); */
|
||||
NS_IMETHODIMP nsMsgSearchOfflineMail::OnStopRunningUrl(nsIURI *url, nsresult aExitCode)
|
||||
{
|
||||
nsCOMPtr<nsIMsgSearchSession> searchSession;
|
||||
m_scope->GetSearchSession(getter_AddRefs(searchSession));
|
||||
if (searchSession)
|
||||
searchSession->ResumeSearch();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -35,12 +35,16 @@ class nsMsgMailboxParser;
|
|||
class nsIMsgSearchScopeTerm;
|
||||
class nsIMsgFolder;
|
||||
|
||||
class nsMsgSearchOfflineMail : public nsMsgSearchAdapter
|
||||
class nsMsgSearchOfflineMail : public nsMsgSearchAdapter, public nsIUrlListener
|
||||
{
|
||||
public:
|
||||
nsMsgSearchOfflineMail (nsIMsgSearchScopeTerm*, nsISupportsArray *);
|
||||
virtual ~nsMsgSearchOfflineMail ();
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
|
||||
NS_DECL_NSIURLLISTENER;
|
||||
|
||||
NS_IMETHOD ValidateTerms ();
|
||||
NS_IMETHOD Search (PRBool *aDone);
|
||||
NS_IMETHOD Abort ();
|
||||
|
@ -77,15 +81,6 @@ protected:
|
|||
nsIMsgDatabase *m_db;
|
||||
nsCOMPtr<nsISimpleEnumerator> m_listContext;
|
||||
|
||||
enum
|
||||
{
|
||||
kOpenFolderState,
|
||||
kParseMoreState,
|
||||
kCloseFolderState,
|
||||
kDoneState
|
||||
};
|
||||
int m_parserState;
|
||||
nsMsgMailboxParser *m_mailboxParser;
|
||||
void CleanUpScope();
|
||||
};
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@ nsMsgSearchSession::nsMsgSearchSession()
|
|||
// m_calledStartingUpdate = PR_FALSE;
|
||||
m_handlingError = PR_FALSE;
|
||||
m_pSearchParam = nsnull;
|
||||
m_searchPaused = PR_FALSE;
|
||||
|
||||
}
|
||||
|
||||
|
@ -291,6 +292,29 @@ NS_IMETHODIMP nsMsgSearchSession::InterruptSearch()
|
|||
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)
|
||||
{
|
||||
|
@ -315,6 +339,20 @@ 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)
|
||||
{
|
||||
|
@ -456,41 +494,26 @@ nsresult nsMsgSearchSession::AddUrl(const char *url)
|
|||
PRBool done;
|
||||
searchSession->TimeSlice(&done);
|
||||
if (done)
|
||||
{
|
||||
aTimer->Cancel();
|
||||
searchSession->m_backgroundTimer = nsnull;
|
||||
}
|
||||
}
|
||||
|
||||
nsresult nsMsgSearchSession::StartTimer()
|
||||
{
|
||||
nsresult err;
|
||||
PRBool done;
|
||||
|
||||
m_backgroundTimer = do_CreateInstance("component://netscape/timer", &err);
|
||||
m_backgroundTimer->Init(TimerCallback, (void *) this, 0, NS_PRIORITY_NORMAL, NS_TYPE_REPEATING_SLACK);
|
||||
// ### start meteors?
|
||||
return TimeSlice(&done);
|
||||
}
|
||||
|
||||
nsresult nsMsgSearchSession::SearchWOUrls ()
|
||||
{
|
||||
nsresult err = NS_OK;
|
||||
PRBool done;
|
||||
|
||||
m_backgroundTimer = do_CreateInstance("component://netscape/timer", &err);
|
||||
m_backgroundTimer->Init(TimerCallback, (void *) this, 0, NS_PRIORITY_NORMAL, NS_TYPE_REPEATING_SLACK);
|
||||
// ### start meteors?
|
||||
err = TimeSlice(&done);
|
||||
#if 0
|
||||
if (!m_urlStruct)
|
||||
m_urlStruct = NET_CreateURLStruct ("search-libmsg:", NET_DONT_RELOAD);
|
||||
|
||||
if (m_urlStruct)
|
||||
{
|
||||
// Set the internal_url flag so just in case someone else happens to have
|
||||
// a search-libmsg URL, it won't fire my code, and surely crash.
|
||||
m_urlStruct->internal_url = TRUE;
|
||||
|
||||
// Initiate the asynchronous search
|
||||
int getUrlErr = m_pane->GetURL (m_urlStruct, FALSE);
|
||||
if (getUrlErr)
|
||||
err = (MSG_SearchError) -1; //###phil impedance mismatch
|
||||
else
|
||||
if (!XP_STRNCMP(m_urlStruct->address, "news:", 5) || !XP_STRNCMP(m_urlStruct->address, "snews:", 6))
|
||||
BeginCylonMode();
|
||||
}
|
||||
else
|
||||
err = NS_ERROR_OUT_OF_MEMORY;
|
||||
#endif
|
||||
return err;
|
||||
return StartTimer();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgSearchSession::GetRunningAdapter (nsIMsgSearchAdapter **aSearchAdapter)
|
||||
|
|
|
@ -49,6 +49,7 @@ protected:
|
|||
nsCOMPtr <nsIMsgWindow> m_window;
|
||||
|
||||
nsresult Initialize();
|
||||
nsresult StartTimer();
|
||||
nsresult TimeSlice (PRBool *aDone);
|
||||
nsMsgSearchScopeTerm *GetRunningScope();
|
||||
void StopRunning();
|
||||
|
@ -84,6 +85,7 @@ protected:
|
|||
PRBool m_handlingError;
|
||||
nsCStringArray m_urlQueue;
|
||||
nsCOMPtr <nsITimer> m_backgroundTimer;
|
||||
PRBool m_searchPaused;
|
||||
|
||||
|
||||
};
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
*/
|
||||
|
||||
#include "nsISupports.idl"
|
||||
interface nsIMsgWindow;
|
||||
interface nsIUrlListener;
|
||||
|
||||
[scriptable, uuid(27D2DE40-BAF1-11d2-9578-00805F8AC615)]
|
||||
interface nsIMsgLocalMailFolder : nsISupports {
|
||||
|
@ -32,4 +34,5 @@ interface nsIMsgLocalMailFolder : nsISupports {
|
|||
* like MSG_FOLDER_FLAG_INBOX | MSG_FOLDER_FLAG_DRAFTS | etc
|
||||
*/
|
||||
void setFlagsOnDefaultMailboxes(in unsigned long flags);
|
||||
void ParseFolder(in nsIMsgWindow aMsgWindow, in nsIUrlListener listener);
|
||||
};
|
||||
|
|
|
@ -570,9 +570,17 @@ NS_IMETHODIMP nsMsgLocalMailFolder::AddSubfolder(nsAutoString *name,
|
|||
|
||||
|
||||
//run the url to parse the mailbox
|
||||
nsresult nsMsgLocalMailFolder::ParseFolder(nsIMsgWindow *aMsgWindow, nsFileSpec& path)
|
||||
NS_IMETHODIMP nsMsgLocalMailFolder::ParseFolder(nsIMsgWindow *aMsgWindow, nsIUrlListener *listener)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
nsCOMPtr<nsIFileSpec> pathSpec;
|
||||
rv = GetPath(getter_AddRefs(pathSpec));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsFileSpec path;
|
||||
rv = pathSpec->GetFileSpec(&path);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
|
||||
NS_WITH_SERVICE(nsIMailboxService, mailboxService,
|
||||
kMailboxServiceCID, &rv);
|
||||
|
@ -582,7 +590,7 @@ nsresult nsMsgLocalMailFolder::ParseFolder(nsIMsgWindow *aMsgWindow, nsFileSpec&
|
|||
if(!parser)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
rv = mailboxService->ParseMailbox(aMsgWindow, path, parser, this, nsnull);
|
||||
rv = mailboxService->ParseMailbox(aMsgWindow, path, parser, listener, nsnull);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
@ -729,10 +737,6 @@ nsresult nsMsgLocalMailFolder::GetDatabase(nsIMsgWindow *aMsgWindow)
|
|||
rv = GetPath(getter_AddRefs(pathSpec));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsFileSpec path;
|
||||
rv = pathSpec->GetFileSpec(&path);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsresult folderOpen = NS_OK;
|
||||
nsCOMPtr<nsIMsgDatabase> mailDBFactory;
|
||||
|
||||
|
@ -780,7 +784,7 @@ nsresult nsMsgLocalMailFolder::GetDatabase(nsIMsgWindow *aMsgWindow)
|
|||
// if we have to regenerate the folder, run the parser url.
|
||||
if(folderOpen == NS_MSG_ERROR_FOLDER_SUMMARY_MISSING || folderOpen == NS_MSG_ERROR_FOLDER_SUMMARY_OUT_OF_DATE)
|
||||
{
|
||||
if(NS_FAILED(rv = ParseFolder(aMsgWindow, path)))
|
||||
if(NS_FAILED(rv = ParseFolder(aMsgWindow, this)))
|
||||
return rv;
|
||||
else
|
||||
return NS_ERROR_NOT_INITIALIZED;
|
||||
|
@ -971,12 +975,47 @@ nsMsgLocalMailFolder::CreateSubfolder(const PRUnichar *folderName)
|
|||
}
|
||||
return rv;
|
||||
}
|
||||
#ifdef DEBUG_bienvenu
|
||||
nsIMsgSearchSession *saveSearchSession;
|
||||
#endif
|
||||
|
||||
NS_IMETHODIMP nsMsgLocalMailFolder::Compact()
|
||||
{
|
||||
// **** jefft -- needs to provide nsIMsgWindow for the compact status
|
||||
// update; come back later
|
||||
|
||||
#ifdef DEBUG_bienvenu
|
||||
nsCOMPtr<nsIMsgSearchSession> searchSession;
|
||||
nsresult ret = nsComponentManager::CreateInstance(NS_MSGSEARCHSESSION_PROGID,
|
||||
nsnull,
|
||||
NS_GET_IID(nsIMsgSearchSession),
|
||||
getter_AddRefs(searchSession));
|
||||
if (searchSession)
|
||||
{
|
||||
nsCOMPtr <nsIMsgSearchValue> searchValue;
|
||||
nsCOMPtr <nsIMsgSearchTerm> searchTerm;
|
||||
nsCOMPtr<nsISupportsArray> searchTerms;
|
||||
nsString valStr;
|
||||
valStr.AssignWithConversion("test");
|
||||
ret = NS_NewISupportsArray(getter_AddRefs(searchTerms));
|
||||
|
||||
searchSession->CreateSearchTerm(getter_AddRefs(searchTerm));
|
||||
searchTerm->GetValue(getter_AddRefs(searchValue));
|
||||
searchValue->SetStr(valStr.GetUnicode());
|
||||
searchValue->SetAttrib(nsMsgSearchAttrib::Body);
|
||||
searchTerm->SetAttrib(nsMsgSearchAttrib::Body);
|
||||
searchTerm->SetOp(nsMsgSearchOp::Contains);
|
||||
searchTerm->SetBooleanAnd(PR_FALSE);
|
||||
searchTerm->SetValue(searchValue); // I guess this is right...
|
||||
searchTerms->AppendElement(searchTerm);
|
||||
searchSession->AddSearchTermArray(searchTerms);
|
||||
searchSession->AddScopeTerm(nsMsgSearchScope::MailFolder, this);
|
||||
saveSearchSession = searchSession;
|
||||
NS_ADDREF(saveSearchSession);
|
||||
searchSession->Search(nsnull);
|
||||
return NS_OK;
|
||||
}
|
||||
#endif
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
nsCOMPtr<nsIMsgDatabase> db;
|
||||
nsCOMPtr<nsIDBFolderInfo> folderInfo;
|
||||
|
|
|
@ -143,7 +143,6 @@ public:
|
|||
|
||||
|
||||
protected:
|
||||
nsresult ParseFolder(nsIMsgWindow *aMsgWindow, nsFileSpec& path);
|
||||
nsresult CreateSubFolders(nsFileSpec &path);
|
||||
nsresult AddDirectorySeparator(nsFileSpec &path);
|
||||
nsresult GetDatabase(nsIMsgWindow *aMsgWindow);
|
||||
|
|
Загрузка…
Ссылка в новой задаче