Back to index

lightning-sunbird  0.9+nobinonly
nsNewsDownloader.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 2001
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *
00024  * Alternatively, the contents of this file may be used under the terms of
00025  * either of the GNU General Public License Version 2 or later (the "GPL"),
00026  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00027  * in which case the provisions of the GPL or the LGPL are applicable instead
00028  * of those above. If you wish to allow use of your version of this file only
00029  * under the terms of either the GPL or the LGPL, and not to allow others to
00030  * use your version of this file under the terms of the MPL, indicate your
00031  * decision by deleting the provisions above and replace them with the notice
00032  * and other provisions required by the GPL or the LGPL. If you do not delete
00033  * the provisions above, a recipient may use your version of this file under
00034  * the terms of any one of the MPL, the GPL or the LGPL.
00035  *
00036  * ***** END LICENSE BLOCK ***** */
00037 
00038 #include "msgCore.h"
00039 #include "nntpCore.h"
00040 #include "netCore.h"
00041 #include "nsXPIDLString.h"
00042 #include "nsIMsgNewsFolder.h"
00043 #include "nsIStringBundle.h"
00044 #include "nsNewsDownloader.h"
00045 #include "nsINntpService.h"
00046 #include "nsMsgNewsCID.h"
00047 #include "nsIMsgSearchSession.h"
00048 #include "nsIMsgSearchTerm.h"
00049 #include "nsIMsgSearchValidityManager.h"
00050 #include "nsRDFCID.h"
00051 #include "nsIMsgAccountManager.h"
00052 #include "nsMsgFolderFlags.h"
00053 #include "nsIRequestObserver.h"
00054 #include "nsIMsgMailSession.h"
00055 
00056 // This file contains the news article download state machine.
00057 
00058 // if pIds is not null, download the articles whose id's are passed in. Otherwise,
00059 // which articles to download is determined by nsNewsDownloader object,
00060 // or subclasses thereof. News can download marked objects, for example.
00061 nsresult nsNewsDownloader::DownloadArticles(nsIMsgWindow *window, nsIMsgFolder *folder, nsMsgKeyArray *pIds)
00062 {
00063   if (pIds != nsnull)
00064     m_keysToDownload.InsertAt(0, pIds);
00065   
00066   if (m_keysToDownload.GetSize() > 0)
00067     m_downloadFromKeys = PR_TRUE;
00068   
00069   m_folder = folder;
00070   m_window = window;
00071   m_numwrote = 0;
00072   
00073   PRBool headersToDownload = GetNextHdrToRetrieve();
00074   // should we have a special error code for failure here?
00075   return (headersToDownload) ? DownloadNext(PR_TRUE) : NS_ERROR_FAILURE;
00076 }
00077 
00078 /* Saving news messages
00079  */
00080 
00081 NS_IMPL_ISUPPORTS2(nsNewsDownloader, nsIUrlListener, nsIMsgSearchNotify)
00082 
00083 nsNewsDownloader::nsNewsDownloader(nsIMsgWindow *window, nsIMsgDatabase *msgDB, nsIUrlListener *listener)
00084 {
00085   m_numwrote = 0;
00086   m_downloadFromKeys = PR_FALSE;
00087   m_newsDB = msgDB;
00088   m_abort = PR_FALSE;
00089   m_listener = listener;
00090   m_window = window;
00091   m_lastPercent = -1;
00092   LL_I2L(m_lastProgressTime, 0);
00093   // not the perfect place for this, but I think it will work.
00094   if (m_window)
00095     m_window->SetStopped(PR_FALSE);
00096 }
00097 
00098 nsNewsDownloader::~nsNewsDownloader()
00099 {
00100   if (m_listener)
00101     m_listener->OnStopRunningUrl(/* don't have a url */nsnull, m_status);
00102   if (m_newsDB)
00103   {
00104     m_newsDB->Commit(nsMsgDBCommitType::kLargeCommit);
00105     m_newsDB = nsnull;
00106   }
00107 }
00108 
00109 NS_IMETHODIMP nsNewsDownloader::OnStartRunningUrl(nsIURI* url)
00110 {
00111   return NS_OK;
00112 }
00113 
00114 NS_IMETHODIMP nsNewsDownloader::OnStopRunningUrl(nsIURI* url, nsresult exitCode)
00115 {
00116   PRBool stopped = PR_FALSE;
00117   if (m_window)
00118     m_window->GetStopped(&stopped);
00119   if (stopped)
00120     exitCode = NS_BINDING_ABORTED;
00121 
00122  nsresult rv = exitCode;
00123   if (NS_SUCCEEDED(exitCode) || exitCode == NS_MSG_NEWS_ARTICLE_NOT_FOUND)
00124     rv = DownloadNext(PR_FALSE);
00125 
00126   return rv;
00127 }
00128 
00129 nsresult nsNewsDownloader::DownloadNext(PRBool firstTimeP)
00130 {
00131   nsresult rv;
00132   if (!firstTimeP)
00133   {
00134     PRBool moreHeaders = GetNextHdrToRetrieve();
00135     if (!moreHeaders)
00136     {
00137       if (m_listener)
00138         m_listener->OnStopRunningUrl(nsnull, NS_OK);
00139       return NS_OK;
00140     }
00141   }
00142   StartDownload();
00143   m_wroteAnyP = PR_FALSE;
00144   nsCOMPtr <nsINntpService> nntpService = do_GetService(NS_NNTPSERVICE_CONTRACTID,&rv);
00145   NS_ENSURE_SUCCESS(rv, rv);
00146 
00147   return nntpService->FetchMessage(m_folder, m_keyToDownload, m_window, nsnull, this, nsnull);
00148 }
00149 
00150 PRBool DownloadNewsArticlesToOfflineStore::GetNextHdrToRetrieve()
00151 {
00152   nsresult rv;
00153 
00154   if (m_downloadFromKeys)
00155     return nsNewsDownloader::GetNextHdrToRetrieve();
00156 
00157   if (m_headerEnumerator == nsnull)
00158     rv = m_newsDB->EnumerateMessages(getter_AddRefs(m_headerEnumerator));
00159 
00160   PRBool hasMore = PR_FALSE;
00161 
00162   while (NS_SUCCEEDED(rv = m_headerEnumerator->HasMoreElements(&hasMore)) && hasMore) 
00163   {
00164     nsCOMPtr <nsISupports> supports;
00165     rv = m_headerEnumerator->GetNext(getter_AddRefs(supports));
00166     m_newsHeader = do_QueryInterface(supports);
00167     NS_ENSURE_SUCCESS(rv,rv);
00168     PRUint32 hdrFlags;
00169     m_newsHeader->GetFlags(&hdrFlags);
00170     if (hdrFlags & MSG_FLAG_MARKED)
00171     {
00172       m_newsHeader->GetMessageKey(&m_keyToDownload);
00173       break;
00174     }
00175     else
00176     {
00177       m_newsHeader = nsnull;
00178     }
00179   }
00180   return hasMore;
00181 }
00182 
00183 void nsNewsDownloader::Abort() {}
00184 void nsNewsDownloader::Complete() {}
00185 
00186 PRBool nsNewsDownloader::GetNextHdrToRetrieve()
00187 {
00188   nsresult rv;
00189   if (m_downloadFromKeys)
00190   {
00191     if (m_numwrote >= (PRInt32) m_keysToDownload.GetSize())
00192       return PR_FALSE;
00193 
00194     m_keyToDownload = m_keysToDownload.GetAt(m_numwrote++);
00195     PRInt32 percent;
00196     percent = (100 * m_numwrote) / (PRInt32) m_keysToDownload.GetSize();
00197 
00198     PRInt64 nowMS = LL_ZERO;
00199     if (percent < 100)  // always need to do 100%
00200     {
00201       int64 minIntervalBetweenProgress;
00202 
00203       LL_I2L(minIntervalBetweenProgress, 750);
00204       int64 diffSinceLastProgress;
00205       LL_I2L(nowMS, PR_IntervalToMilliseconds(PR_IntervalNow()));
00206       LL_SUB(diffSinceLastProgress, nowMS, m_lastProgressTime); // r = a - b
00207       LL_SUB(diffSinceLastProgress, diffSinceLastProgress, minIntervalBetweenProgress); // r = a - b
00208       if (!LL_GE_ZERO(diffSinceLastProgress))
00209         return PR_TRUE;
00210     }
00211 
00212     m_lastProgressTime = nowMS;
00213     nsCOMPtr <nsIMsgNewsFolder> newsFolder = do_QueryInterface(m_folder);
00214     nsCOMPtr<nsIStringBundleService> bundleService = do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
00215     NS_ENSURE_SUCCESS(rv, rv);
00216     nsCOMPtr<nsIStringBundle> bundle;
00217     rv = bundleService->CreateBundle(NEWS_MSGS_URL, getter_AddRefs(bundle));
00218     NS_ENSURE_SUCCESS(rv, rv);
00219     
00220     nsAutoString firstStr;
00221     firstStr.AppendInt(m_numwrote);
00222     nsAutoString totalStr;
00223     totalStr.AppendInt(m_keysToDownload.GetSize());
00224     nsXPIDLString prettiestName;
00225     nsXPIDLString statusString;
00226     
00227     m_folder->GetPrettiestName(getter_Copies(prettiestName));
00228     
00229     const PRUnichar *formatStrings[3] = { firstStr.get(), totalStr.get(), (const PRUnichar *) prettiestName };
00230     rv = bundle->FormatStringFromName(NS_LITERAL_STRING("downloadingArticlesForOffline").get(), formatStrings, 3, getter_Copies(statusString));
00231     NS_ENSURE_SUCCESS(rv, rv);
00232     ShowProgress(statusString, percent);
00233     return PR_TRUE;
00234   }
00235   NS_ASSERTION(PR_FALSE, "shouldn't get here if we're not downloading from keys.");
00236   return PR_FALSE;   // shouldn't get here if we're not downloading from keys.
00237 }
00238 
00239 nsresult nsNewsDownloader::ShowProgress(const PRUnichar *progressString, PRInt32 percent)
00240 {
00241   if (!m_statusFeedback)
00242   {
00243     if (m_window)
00244       m_window->GetStatusFeedback(getter_AddRefs(m_statusFeedback));
00245   }
00246   if (m_statusFeedback)
00247   {
00248     m_statusFeedback->ShowStatusString(progressString);
00249     if (percent != m_lastPercent)
00250     {
00251       m_statusFeedback->ShowProgress(percent);
00252       m_lastPercent = percent;
00253     }
00254   }
00255   return NS_OK;
00256 }
00257 
00258 NS_IMETHODIMP DownloadNewsArticlesToOfflineStore::OnStartRunningUrl(nsIURI* url)
00259 {
00260   return NS_OK;
00261 }
00262 
00263 
00264 NS_IMETHODIMP DownloadNewsArticlesToOfflineStore::OnStopRunningUrl(nsIURI* url, nsresult exitCode)
00265 {
00266   m_status = exitCode;
00267   if (m_newsHeader != nsnull)
00268   {
00269 #ifdef DEBUG_bienvenu
00270     //        XP_Trace("finished retrieving %ld\n", m_newsHeader->GetMessageKey());
00271 #endif
00272     if (m_newsDB)
00273     {
00274       nsMsgKey msgKey;
00275       m_newsHeader->GetMessageKey(&msgKey);
00276       m_newsDB->MarkMarked(msgKey, PR_FALSE, nsnull);
00277     }
00278   }    
00279   m_newsHeader = nsnull;
00280   return nsNewsDownloader::OnStopRunningUrl(url, exitCode);
00281 }
00282 
00283 int DownloadNewsArticlesToOfflineStore::FinishDownload()
00284 {
00285   return 0;
00286 }
00287 
00288 
00289 NS_IMETHODIMP nsNewsDownloader::OnSearchHit(nsIMsgDBHdr *header, nsIMsgFolder *folder)
00290 {
00291   NS_ENSURE_ARG(header);
00292   
00293   
00294   PRUint32 msgFlags;
00295   header->GetFlags(&msgFlags);
00296   // only need to download articles we don't already have...
00297   if (! (msgFlags & MSG_FLAG_OFFLINE))
00298   {
00299     nsMsgKey key;
00300     header->GetMessageKey(&key);
00301     m_keysToDownload.Add(key);
00302   }
00303   return NS_OK;
00304 }
00305 
00306 NS_IMETHODIMP nsNewsDownloader::OnSearchDone(nsresult status)
00307 {
00308   if (m_keysToDownload.GetSize() == 0)
00309   {
00310     if (m_listener)
00311       return m_listener->OnStopRunningUrl(nsnull, NS_OK);
00312   }
00313   nsresult rv = DownloadArticles(m_window, m_folder, 
00314                   /* we've already set m_keysToDownload, so don't pass it in */ nsnull);
00315   if (NS_FAILED(rv))
00316     if (m_listener)
00317       m_listener->OnStopRunningUrl(nsnull, rv);
00318 
00319   return rv;
00320 }
00321 NS_IMETHODIMP nsNewsDownloader::OnNewSearch()
00322 {
00323   return NS_OK;
00324 }
00325 
00326 int DownloadNewsArticlesToOfflineStore::StartDownload()
00327 {
00328   m_newsDB->GetMsgHdrForKey(m_keyToDownload, getter_AddRefs(m_newsHeader));
00329   return 0;
00330 }
00331 
00332 DownloadNewsArticlesToOfflineStore::DownloadNewsArticlesToOfflineStore(nsIMsgWindow *window, nsIMsgDatabase *db, nsIUrlListener *listener)
00333        : nsNewsDownloader(window, db, listener)
00334 {
00335   m_newsDB = db;
00336 }
00337 
00338 DownloadNewsArticlesToOfflineStore::~DownloadNewsArticlesToOfflineStore()
00339 {
00340 }
00341 
00342 DownloadMatchingNewsArticlesToNewsDB::DownloadMatchingNewsArticlesToNewsDB
00343        (nsIMsgWindow *window, nsIMsgFolder *folder, nsIMsgDatabase *newsDB,
00344         nsIUrlListener *listener) :
00345         DownloadNewsArticlesToOfflineStore(window, newsDB, listener)
00346 {
00347   m_window = window;
00348   m_folder = folder;
00349   m_newsDB = newsDB;
00350   m_downloadFromKeys = PR_TRUE;    // search term matching means downloadFromKeys.
00351 }
00352 
00353 DownloadMatchingNewsArticlesToNewsDB::~DownloadMatchingNewsArticlesToNewsDB()
00354 {
00355 }
00356 
00357 
00358 NS_IMPL_ISUPPORTS1(nsMsgDownloadAllNewsgroups, nsIUrlListener)
00359 
00360 
00361 nsMsgDownloadAllNewsgroups::nsMsgDownloadAllNewsgroups(nsIMsgWindow *window, nsIUrlListener *listener)
00362 {
00363   m_window = window;
00364   m_listener = listener;
00365   m_downloaderForGroup = new DownloadMatchingNewsArticlesToNewsDB(window, nsnull, nsnull, this);
00366   NS_IF_ADDREF(m_downloaderForGroup);
00367   m_downloadedHdrsForCurGroup = PR_FALSE;
00368 }
00369 
00370 nsMsgDownloadAllNewsgroups::~nsMsgDownloadAllNewsgroups()
00371 {
00372   NS_IF_RELEASE(m_downloaderForGroup);
00373 }
00374 
00375 NS_IMETHODIMP nsMsgDownloadAllNewsgroups::OnStartRunningUrl(nsIURI* url)
00376 {
00377     return NS_OK;
00378 }
00379 
00380 NS_IMETHODIMP
00381 nsMsgDownloadAllNewsgroups::OnStopRunningUrl(nsIURI* url, nsresult exitCode)
00382 {
00383   nsresult rv = exitCode;
00384   if (NS_SUCCEEDED(exitCode) || exitCode == NS_MSG_NEWS_ARTICLE_NOT_FOUND)
00385   {
00386     if (m_downloadedHdrsForCurGroup)
00387     {
00388       PRBool savingArticlesOffline = PR_FALSE;
00389       nsCOMPtr <nsIMsgNewsFolder> newsFolder = do_QueryInterface(m_currentFolder);
00390       if (newsFolder)
00391         newsFolder->GetSaveArticleOffline(&savingArticlesOffline);
00392 
00393       m_downloadedHdrsForCurGroup = PR_FALSE;
00394       if (savingArticlesOffline) // skip this group - we're saving to it already
00395         rv = ProcessNextGroup();
00396       else
00397         rv = DownloadMsgsForCurrentGroup();
00398     }
00399     else
00400     {
00401       rv = ProcessNextGroup();
00402     }
00403   }
00404   else if (m_listener)  // notify main observer.
00405     m_listener->OnStopRunningUrl(url, exitCode);
00406    
00407   return rv;
00408 }
00409 
00410 // leaves m_currentServer at the next nntp "server" that
00411 // might have folders to download for offline use. If no more servers,
00412 // m_currentServer will be left at nsnull.
00413 // Also, sets up m_serverEnumerator to enumerate over the server
00414 // If no servers found, m_serverEnumerator will be left at null,
00415 nsresult nsMsgDownloadAllNewsgroups::AdvanceToNextServer(PRBool *done)
00416 {
00417   nsresult rv;
00418 
00419   NS_ENSURE_ARG(done);
00420 
00421   *done = PR_TRUE;
00422   if (!m_allServers)
00423   {
00424     nsCOMPtr<nsIMsgAccountManager> accountManager = 
00425              do_GetService(NS_MSGACCOUNTMANAGER_CONTRACTID, &rv);
00426     NS_ASSERTION(accountManager && NS_SUCCEEDED(rv), "couldn't get account mgr");
00427     if (!accountManager || NS_FAILED(rv)) return rv;
00428 
00429     rv = accountManager->GetAllServers(getter_AddRefs(m_allServers));
00430     NS_ENSURE_SUCCESS(rv, rv);
00431   }
00432   PRUint32 serverIndex = (m_currentServer) ? m_allServers->IndexOf(m_currentServer) + 1 : 0;
00433   m_currentServer = nsnull;
00434   PRUint32 numServers; 
00435   m_allServers->Count(&numServers);
00436   nsCOMPtr <nsIMsgFolder> rootFolder;
00437 
00438   while (serverIndex < numServers)
00439   {
00440     nsCOMPtr<nsIMsgIncomingServer> server = do_QueryElementAt(m_allServers, serverIndex);
00441     serverIndex++;
00442 
00443     nsCOMPtr <nsINntpIncomingServer> newsServer = do_QueryInterface(server);
00444     if (!newsServer) // we're only looking for news servers
00445       continue;
00446     if (server)
00447     {
00448       m_currentServer = server;
00449       server->GetRootFolder(getter_AddRefs(rootFolder));
00450       if (rootFolder)
00451       {
00452         NS_NewISupportsArray(getter_AddRefs(m_allFolders));
00453         rv = rootFolder->ListDescendents(m_allFolders);
00454         if (NS_SUCCEEDED(rv))
00455           m_allFolders->Enumerate(getter_AddRefs(m_serverEnumerator));
00456         if (NS_SUCCEEDED(rv) && m_serverEnumerator)
00457         {
00458           rv = m_serverEnumerator->First();
00459           if (NS_SUCCEEDED(rv))
00460           {
00461             *done = PR_FALSE;
00462             break;
00463           }
00464         }
00465       }
00466     }
00467   }
00468   return rv;
00469 }
00470 
00471 nsresult nsMsgDownloadAllNewsgroups::AdvanceToNextGroup(PRBool *done)
00472 {
00473   nsresult rv;
00474   NS_ENSURE_ARG(done);
00475   *done = PR_TRUE;
00476 
00477   if (m_currentFolder)
00478   {
00479     nsCOMPtr <nsIMsgNewsFolder> newsFolder = do_QueryInterface(m_currentFolder);
00480     if (newsFolder)
00481       newsFolder->SetSaveArticleOffline(PR_FALSE);
00482   
00483     nsCOMPtr<nsIMsgMailSession> session = 
00484              do_GetService(NS_MSGMAILSESSION_CONTRACTID, &rv); 
00485     if (NS_SUCCEEDED(rv) && session) 
00486     {
00487       PRBool folderOpen;
00488       PRUint32 folderFlags;
00489       m_currentFolder->GetFlags(&folderFlags);
00490       session->IsFolderOpenInWindow(m_currentFolder, &folderOpen);
00491       if (!folderOpen && ! (folderFlags & (MSG_FOLDER_FLAG_TRASH | MSG_FOLDER_FLAG_INBOX)))
00492         m_currentFolder->SetMsgDatabase(nsnull);
00493     }
00494     m_currentFolder = nsnull;
00495   }
00496 
00497   *done = PR_FALSE;
00498 
00499   if (!m_currentServer)
00500      rv = AdvanceToNextServer(done);
00501   else
00502     rv = m_serverEnumerator->Next();
00503   if (NS_FAILED(rv))
00504     rv = AdvanceToNextServer(done);
00505 
00506   if (NS_SUCCEEDED(rv) && !*done && m_serverEnumerator)
00507   {
00508     nsCOMPtr <nsISupports> supports;
00509     rv = m_serverEnumerator->CurrentItem(getter_AddRefs(supports));
00510     m_currentFolder = do_QueryInterface(supports);
00511     *done = PR_FALSE;
00512   }
00513   return rv;
00514 }
00515 
00516 nsresult DownloadMatchingNewsArticlesToNewsDB::RunSearch(nsIMsgFolder *folder, nsIMsgDatabase *newsDB, nsIMsgSearchSession *searchSession)
00517 {
00518   m_folder = folder;
00519   m_newsDB = newsDB;
00520   m_searchSession = searchSession;
00521 
00522   m_keysToDownload.RemoveAll();
00523   nsresult rv;
00524   NS_ENSURE_ARG(searchSession);
00525   NS_ENSURE_ARG(folder);
00526 
00527   searchSession->RegisterListener(this);
00528   rv = searchSession->AddScopeTerm(nsMsgSearchScope::localNews, folder);
00529   return searchSession->Search(m_window);
00530 }
00531 
00532 nsresult nsMsgDownloadAllNewsgroups::ProcessNextGroup()
00533 {
00534   nsresult rv = NS_OK;
00535   PRBool done = PR_FALSE;
00536 
00537   while (NS_SUCCEEDED(rv) && !done)
00538   {
00539     rv = AdvanceToNextGroup(&done); 
00540     if (m_currentFolder)
00541     {
00542       PRUint32 folderFlags;
00543       m_currentFolder->GetFlags(&folderFlags);
00544       if (folderFlags & MSG_FOLDER_FLAG_OFFLINE)
00545         break;
00546     }
00547   }
00548   if (NS_FAILED(rv) || done)
00549   {
00550     if (m_listener)
00551       return m_listener->OnStopRunningUrl(nsnull, NS_OK);
00552   }
00553   m_downloadedHdrsForCurGroup = PR_TRUE;
00554   return m_currentFolder->GetNewMessages(m_window, this);
00555 }
00556 
00557 nsresult nsMsgDownloadAllNewsgroups::DownloadMsgsForCurrentGroup()
00558 {
00559   NS_ENSURE_TRUE(m_downloaderForGroup, NS_ERROR_OUT_OF_MEMORY);
00560   nsCOMPtr <nsIMsgDatabase> db;
00561   nsCOMPtr <nsISupportsArray> termList;
00562   nsCOMPtr <nsIMsgDownloadSettings> downloadSettings;
00563   m_currentFolder->GetMsgDatabase(m_window, getter_AddRefs(db));
00564   nsresult rv = m_currentFolder->GetDownloadSettings(getter_AddRefs(downloadSettings));
00565   NS_ENSURE_SUCCESS(rv, rv);
00566 
00567   nsCOMPtr <nsIMsgNewsFolder> newsFolder = do_QueryInterface(m_currentFolder);
00568   if (newsFolder)
00569     newsFolder->SetSaveArticleOffline(PR_TRUE);
00570 
00571   if (!m_termList)
00572   {
00573     rv = NS_NewISupportsArray(getter_AddRefs(m_termList));
00574     NS_ENSURE_SUCCESS(rv, rv);
00575   }
00576 
00577   nsCOMPtr <nsIMsgSearchSession> searchSession = do_CreateInstance(NS_MSGSEARCHSESSION_CONTRACTID, &rv);
00578   NS_ENSURE_SUCCESS(rv, rv);
00579 
00580   PRBool downloadByDate, downloadUnreadOnly;
00581   PRUint32 ageLimitOfMsgsToDownload;
00582 
00583   downloadSettings->GetDownloadByDate(&downloadByDate);
00584   downloadSettings->GetDownloadUnreadOnly(&downloadUnreadOnly);
00585   downloadSettings->GetAgeLimitOfMsgsToDownload(&ageLimitOfMsgsToDownload);
00586 
00587   nsCOMPtr <nsIMsgSearchTerm> term;
00588   nsCOMPtr <nsIMsgSearchValue>    value;
00589 
00590   rv = searchSession->CreateTerm(getter_AddRefs(term));
00591   NS_ENSURE_SUCCESS(rv, rv);
00592   term->GetValue(getter_AddRefs(value));
00593 
00594   if (downloadUnreadOnly)
00595   {
00596     value->SetAttrib(nsMsgSearchAttrib::MsgStatus);
00597     value->SetStatus(MSG_FLAG_READ);
00598     searchSession->AddSearchTerm(nsMsgSearchAttrib::MsgStatus, nsMsgSearchOp::Isnt, value, PR_TRUE, nsnull);
00599   }
00600   if (downloadByDate)
00601   {
00602     value->SetAttrib(nsMsgSearchAttrib::AgeInDays);
00603     value->SetAge(ageLimitOfMsgsToDownload);
00604     searchSession->AddSearchTerm(nsMsgSearchAttrib::AgeInDays, nsMsgSearchOp::IsLessThan, value, nsMsgSearchBooleanOp::BooleanAND, nsnull);
00605   }
00606   value->SetAttrib(nsMsgSearchAttrib::MsgStatus);
00607   value->SetStatus(MSG_FLAG_OFFLINE);
00608   searchSession->AddSearchTerm(nsMsgSearchAttrib::MsgStatus, nsMsgSearchOp::Isnt, value, nsMsgSearchBooleanOp::BooleanAND, nsnull);
00609 
00610   m_downloaderForGroup->RunSearch(m_currentFolder, db, searchSession);
00611   return rv;
00612 }