From fe15e59b3cb68cc46eadfec1aa33ddfe317ba3d2 Mon Sep 17 00:00:00 2001 From: "bienvenu%netscape.com" Date: Sat, 26 May 2001 21:49:14 +0000 Subject: [PATCH] add support for counting lines in offline messages so that offline message body search will work, r=naving, sr=sspitzer, a=blizzard 79723 git-svn-id: svn://10.0.0.236/trunk@95968 18797224-902f-48f8-a5cc-f745e15eee43 --- .../base/search/public/nsMsgBodyHandler.h | 137 ++- .../base/search/public/nsMsgSearchScopeTerm.h | 41 +- .../base/search/src/nsMsgBodyHandler.cpp | 365 ++++--- .../base/search/src/nsMsgLocalSearch.cpp | 6 +- .../base/search/src/nsMsgSearchTerm.cpp | 84 +- mozilla/mailnews/base/util/nsMsgDBFolder.cpp | 2 + mozilla/mailnews/base/util/nsMsgDBFolder.h | 71 +- .../mailnews/imap/src/nsImapMailFolder.cpp | 20 +- mozilla/mailnews/news/src/nsNewsFolder.cpp | 988 +++++++++--------- 9 files changed, 858 insertions(+), 856 deletions(-) diff --git a/mozilla/mailnews/base/search/public/nsMsgBodyHandler.h b/mozilla/mailnews/base/search/public/nsMsgBodyHandler.h index d84770097cb..15c145adc04 100644 --- a/mozilla/mailnews/base/search/public/nsMsgBodyHandler.h +++ b/mozilla/mailnews/base/search/public/nsMsgBodyHandler.h @@ -11,76 +11,73 @@ class nsMsgBodyHandler { public: - nsMsgBodyHandler (nsIMsgSearchScopeTerm *, - PRUint32 offset, - PRUint32 length, - nsIMsgDBHdr * msg, - nsIMsgDatabase * db); - - // we can also create a body handler when doing arbitrary header - // filtering...we need the list of headers and the header size as well - // if we are doing filtering...if ForFilters is false, headers and - // headersSize is ignored!!! - nsMsgBodyHandler (nsIMsgSearchScopeTerm *, PRUint32 offset, - PRUint32 length, nsIMsgDBHdr * msg, nsIMsgDatabase * db, - const char * headers /* NULL terminated list of headers */, - PRUint32 headersSize, PRBool ForFilters); - - virtual ~nsMsgBodyHandler(); - - // returns next message line in buf, up to bufSize bytes. - PRInt32 GetNextLine(char * buf, int bufSize); - - // Transformations - void SetStripHtml (PRBool strip) { m_stripHtml = strip; } - void SetStripHeaders (PRBool strip) { m_stripHeaders = strip; } - + nsMsgBodyHandler (nsIMsgSearchScopeTerm *, + PRUint32 offset, + PRUint32 length, + nsIMsgDBHdr * msg, + nsIMsgDatabase * db); + + // we can also create a body handler when doing arbitrary header + // filtering...we need the list of headers and the header size as well + // if we are doing filtering...if ForFilters is false, headers and + // headersSize is ignored!!! + nsMsgBodyHandler (nsIMsgSearchScopeTerm *, PRUint32 offset, + PRUint32 length, nsIMsgDBHdr * msg, nsIMsgDatabase * db, + const char * headers /* NULL terminated list of headers */, + PRUint32 headersSize, PRBool ForFilters); + + virtual ~nsMsgBodyHandler(); + + // returns next message line in buf, up to bufSize bytes. + PRInt32 GetNextLine(char * buf, int bufSize); + + // Transformations + void SetStripHtml (PRBool strip) { m_stripHtml = strip; } + void SetStripHeaders (PRBool strip) { m_stripHeaders = strip; } + protected: - void Initialize(); // common initialization code - - // filter related methods. For filtering we always use the headers - // list instead of the database... - PRBool m_Filtering; - PRInt32 GetNextFilterLine(char * buf, PRUint32 bufSize); - // pointer into the headers list in the original message hdr db... - const char * m_headers; - PRUint32 m_headersSize; - PRUint32 m_headerBytesRead; - - // local / POP related methods - void OpenLocalFolder(); - - // goes through the mail folder - PRInt32 GetNextLocalLine(char * buf, int bufSize); - - nsIMsgSearchScopeTerm *m_scope; - - // local file state -// XP_File *m_localFile; - // need a file stream here, I bet - - // current offset into the mail folder file. - PRInt32 m_localFileOffset; - PRUint32 m_numLocalLines; - - // Offline IMAP related methods & state - - // goes through the MessageDB - PRInt32 GetNextIMAPLine(char * buf, int bufSize); - - nsIMsgDBHdr * m_msgHdr; - nsIMsgDatabase * m_db; - PRInt32 m_IMAPMessageOffset; - - // News related methods & state - PRInt32 m_NewsArticleOffset; - - // Transformations - PRBool m_stripHeaders; // PR_TRUE if we're supposed to strip of message headers - PRBool m_stripHtml; // PR_TRUE if we're supposed to strip off HTML tags - PRBool m_passedHeaders; // PR_TRUE if we've already skipped over the headers - PRBool m_messageIsHtml; // PR_TRUE if the Content-type header claims text/html - PRInt32 ApplyTransformations (char *buf, PRInt32 length, PRBool &returnThisLine); - void StripHtml (char *buf); + void Initialize(); // common initialization code + + // filter related methods. For filtering we always use the headers + // list instead of the database... + PRBool m_Filtering; + PRInt32 GetNextFilterLine(char * buf, PRUint32 bufSize); + // pointer into the headers list in the original message hdr db... + const char * m_headers; + PRUint32 m_headersSize; + PRUint32 m_headerBytesRead; + + // local / POP related methods + void OpenLocalFolder(); + + // goes through the mail folder + PRInt32 GetNextLocalLine(char * buf, int bufSize); + + nsIMsgSearchScopeTerm *m_scope; + nsCOMPtr m_fileSpec; + // local file state + // XP_File *m_localFile; + // need a file stream here, I bet + + // current offset into the mail folder file. + PRInt32 m_localFileOffset; + PRUint32 m_numLocalLines; + + // Offline IMAP related methods & state + + + nsIMsgDBHdr * m_msgHdr; + nsIMsgDatabase * m_db; + + // News related methods & state + PRInt32 m_NewsArticleOffset; + + // Transformations + PRBool m_stripHeaders; // PR_TRUE if we're supposed to strip of message headers + PRBool m_stripHtml; // PR_TRUE if we're supposed to strip off HTML tags + PRBool m_passedHeaders; // PR_TRUE if we've already skipped over the headers + PRBool m_messageIsHtml; // PR_TRUE if the Content-type header claims text/html + PRInt32 ApplyTransformations (char *buf, PRInt32 length, PRBool &returnThisLine); + void StripHtml (char *buf); }; #endif diff --git a/mozilla/mailnews/base/search/public/nsMsgSearchScopeTerm.h b/mozilla/mailnews/base/search/public/nsMsgSearchScopeTerm.h index 21af7ba0776..7a18b113dfb 100644 --- a/mozilla/mailnews/base/search/public/nsMsgSearchScopeTerm.h +++ b/mozilla/mailnews/base/search/public/nsMsgSearchScopeTerm.h @@ -36,29 +36,28 @@ class nsMsgSearchScopeTerm : public nsIMsgSearchScopeTerm { public: - nsMsgSearchScopeTerm (nsIMsgSearchSession *, nsMsgSearchScopeValue, nsIMsgFolder *); - nsMsgSearchScopeTerm (); - virtual ~nsMsgSearchScopeTerm (); - - NS_DECL_ISUPPORTS - NS_DECL_NSIMSGSEARCHSCOPETERM + nsMsgSearchScopeTerm (nsIMsgSearchSession *, nsMsgSearchScopeValue, nsIMsgFolder *); + nsMsgSearchScopeTerm (); + virtual ~nsMsgSearchScopeTerm (); + + NS_DECL_ISUPPORTS + NS_DECL_NSIMSGSEARCHSCOPETERM - PRBool IsOfflineNews(); - PRBool IsOfflineMail (); - PRBool IsOfflineIMAPMail(); // added by mscott - nsresult TimeSlice (PRBool *aDone); - - nsresult InitializeAdapter (nsISupportsArray *termList); - - char *GetStatusBarName (); - - nsMsgSearchScopeValue m_attribute; - char *m_name; - nsCOMPtr m_folder; - nsCOMPtr m_adapter; + PRBool IsOfflineNews(); + PRBool IsOfflineMail (); + nsresult TimeSlice (PRBool *aDone); + + nsresult InitializeAdapter (nsISupportsArray *termList); + + char *GetStatusBarName (); + + nsMsgSearchScopeValue m_attribute; + char *m_name; + nsCOMPtr m_folder; + nsCOMPtr m_adapter; nsCOMPtr m_searchSession; - PRBool m_searchServer; - + PRBool m_searchServer; + }; #endif diff --git a/mozilla/mailnews/base/search/src/nsMsgBodyHandler.cpp b/mozilla/mailnews/base/search/src/nsMsgBodyHandler.cpp index 7bed1366d8a..c7ebd84e689 100644 --- a/mozilla/mailnews/base/search/src/nsMsgBodyHandler.cpp +++ b/mozilla/mailnews/base/search/src/nsMsgBodyHandler.cpp @@ -30,20 +30,20 @@ nsMsgBodyHandler::nsMsgBodyHandler (nsIMsgSearchScopeTerm * scope, PRUint32 offset, PRUint32 numLines, nsIMsgDBHdr* msg, nsIMsgDatabase * db) { - m_scope = scope; - m_localFileOffset = offset; - m_numLocalLines = numLines; - m_msgHdr = msg; - m_db = db; - - // the following are variables used when the body handler is handling stuff from filters....through this constructor, that is not the - // case so we set them to NULL. - m_headers = NULL; - m_headersSize = 0; - m_Filtering = PR_FALSE; // make sure we set this before we call initialize... - - Initialize(); // common initialization stuff - OpenLocalFolder(); + m_scope = scope; + m_localFileOffset = offset; + m_numLocalLines = numLines; + m_msgHdr = msg; + m_db = db; + + // the following are variables used when the body handler is handling stuff from filters....through this constructor, that is not the + // case so we set them to NULL. + m_headers = NULL; + m_headersSize = 0; + m_Filtering = PR_FALSE; // make sure we set this before we call initialize... + + Initialize(); // common initialization stuff + OpenLocalFolder(); } nsMsgBodyHandler::nsMsgBodyHandler(nsIMsgSearchScopeTerm * scope, @@ -52,128 +52,124 @@ nsMsgBodyHandler::nsMsgBodyHandler(nsIMsgSearchScopeTerm * scope, const char * headers, PRUint32 headersSize, PRBool Filtering) { - m_scope = scope; - m_localFileOffset = offset; - m_numLocalLines = numLines; - m_msgHdr = msg; - m_db = db; - m_headersSize = headersSize; - m_Filtering = Filtering; - - Initialize(); - - if (m_Filtering) - m_headers = headers; - else - OpenLocalFolder(); // if nothing else applies, then we must be a POP folder file + m_scope = scope; + m_localFileOffset = offset; + m_numLocalLines = numLines; + m_msgHdr = msg; + m_db = db; + m_headersSize = headersSize; + m_Filtering = Filtering; + + Initialize(); + + if (m_Filtering) + m_headers = headers; + else + OpenLocalFolder(); // if nothing else applies, then we must be a POP folder file } void nsMsgBodyHandler::Initialize() // common initialization code regardless of what body type we are handling... { - // Default transformations for local message search and MAPI access - m_stripHeaders = PR_TRUE; - m_stripHtml = PR_TRUE; - m_messageIsHtml = PR_FALSE; - m_passedHeaders = PR_FALSE; - - // set our offsets to 0 since we haven't handled any bytes yet... - m_IMAPMessageOffset = 0; - m_NewsArticleOffset = 0; - m_headerBytesRead = 0; - + // Default transformations for local message search and MAPI access + m_stripHeaders = PR_TRUE; + m_stripHtml = PR_TRUE; + m_messageIsHtml = PR_FALSE; + m_passedHeaders = PR_FALSE; + + // set our offsets to 0 since we haven't handled any bytes yet... + m_NewsArticleOffset = 0; + m_headerBytesRead = 0; + } nsMsgBodyHandler::~nsMsgBodyHandler() { - nsCOMPtr fileSpec; - nsresult rv = m_scope->GetMailPath(getter_AddRefs(fileSpec)); - PRBool isOpen = PR_FALSE; - if (NS_SUCCEEDED(rv) && fileSpec) - { - fileSpec->IsStreamOpen(&isOpen); - if (isOpen) - fileSpec->CloseStream(); - } + if (m_fileSpec) + { + PRBool isOpen; + m_fileSpec->IsStreamOpen(&isOpen); + if (isOpen) + m_fileSpec->CloseStream(); + } } PRInt32 nsMsgBodyHandler::GetNextLine (char * buf, int bufSize) { - PRInt32 length = 0; - PRBool eatThisLine = PR_FALSE; - - do { - // first, handle the filtering case...this is easy.... - if (m_Filtering) - length = GetNextFilterLine(buf, bufSize); - else - { - // 3 cases: Offline IMAP, POP, or we are dealing with a news message.... - // Offline cases should be same as local mail cases, since we're going - // to store offline messages in berkeley format folders. - if (m_db) - { - length = GetNextLocalLine (buf, bufSize); // (2) POP - } - } - - if (length >= 0) - length = ApplyTransformations (buf, length, eatThisLine); - } while (eatThisLine && length >= 0); // if we hit eof, make sure we break out of this loop. Bug #: - return length; + PRInt32 length = 0; + PRBool eatThisLine = PR_FALSE; + + do { + // first, handle the filtering case...this is easy.... + if (m_Filtering) + length = GetNextFilterLine(buf, bufSize); + else + { + // 3 cases: Offline IMAP, POP, or we are dealing with a news message.... + // Offline cases should be same as local mail cases, since we're going + // to store offline messages in berkeley format folders. + if (m_db) + { + length = GetNextLocalLine (buf, bufSize); // (2) POP + } + } + + if (length >= 0) + length = ApplyTransformations (buf, length, eatThisLine); + } while (eatThisLine && length >= 0); // if we hit eof, make sure we break out of this loop. Bug #: + return length; } void nsMsgBodyHandler::OpenLocalFolder() { - nsCOMPtr fileSpec; - nsresult rv = m_scope->GetMailPath(getter_AddRefs(fileSpec)); - PRBool isOpen = PR_FALSE; - if (NS_SUCCEEDED(rv) && fileSpec) - { - fileSpec->IsStreamOpen(&isOpen); - if (isOpen) return; - fileSpec->OpenStreamForReading(); - fileSpec->Seek(m_localFileOffset); - } - + nsresult rv = m_scope->GetMailPath(getter_AddRefs(m_fileSpec)); + PRBool isOpen = PR_FALSE; + if (NS_SUCCEEDED(rv) && m_fileSpec) + { + m_fileSpec->IsStreamOpen(&isOpen); + if (!isOpen) + m_fileSpec->OpenStreamForReading(); + m_fileSpec->Seek(m_localFileOffset); + } + } PRInt32 nsMsgBodyHandler::GetNextFilterLine(char * buf, PRUint32 bufSize) { - // m_nextHdr always points to the next header in the list....the list is NULL terminated... - PRUint32 numBytesCopied = 0; - if (m_headersSize > 0) - { - // #mscott. Ugly hack! filter headers list have CRs & LFs inside the NULL delimited list of header - // strings. It is possible to have: To NULL CR LF From. We want to skip over these CR/LFs if they start - // at the beginning of what we think is another header. - - while ((m_headers[0] == nsCRT::CR || m_headers[0] == nsCRT::LF || m_headers[0] == ' ' || m_headers[0] == '\0') && m_headersSize > 0) - { - m_headers++; // skip over these chars... - m_headersSize--; - } - - if (m_headersSize > 0) - { - numBytesCopied = nsCRT::strlen(m_headers)+1 /* + 1 to include NULL */ < bufSize ? nsCRT::strlen(m_headers)+1 : (PRInt32) bufSize; - nsCRT::memcpy(buf, m_headers, numBytesCopied); - m_headers += numBytesCopied; - // be careful...m_headersSize is unsigned. Don't let it go negative or we overflow to 2^32....*yikes* - if (m_headersSize < numBytesCopied) - m_headersSize = 0; - else - m_headersSize -= numBytesCopied; // update # bytes we have read from the headers list - - return (PRInt32) numBytesCopied; - } - } - else if (m_headersSize == 0) { - buf[0] = '\0'; - } - return -1; + // m_nextHdr always points to the next header in the list....the list is NULL terminated... + PRUint32 numBytesCopied = 0; + if (m_headersSize > 0) + { + // #mscott. Ugly hack! filter headers list have CRs & LFs inside the NULL delimited list of header + // strings. It is possible to have: To NULL CR LF From. We want to skip over these CR/LFs if they start + // at the beginning of what we think is another header. + + while ((m_headers[0] == nsCRT::CR || m_headers[0] == nsCRT::LF || m_headers[0] == ' ' || m_headers[0] == '\0') && m_headersSize > 0) + { + m_headers++; // skip over these chars... + m_headersSize--; + } + + if (m_headersSize > 0) + { + numBytesCopied = nsCRT::strlen(m_headers)+1 /* + 1 to include NULL */ < bufSize ? nsCRT::strlen(m_headers)+1 : (PRInt32) bufSize; + nsCRT::memcpy(buf, m_headers, numBytesCopied); + m_headers += numBytesCopied; + // be careful...m_headersSize is unsigned. Don't let it go negative or we overflow to 2^32....*yikes* + if (m_headersSize < numBytesCopied) + m_headersSize = 0; + else + m_headersSize -= numBytesCopied; // update # bytes we have read from the headers list + + return (PRInt32) numBytesCopied; + } + } + else if (m_headersSize == 0) { + buf[0] = '\0'; + } + return -1; } // return -1 if no more local lines, length of next line otherwise. @@ -181,90 +177,87 @@ PRInt32 nsMsgBodyHandler::GetNextFilterLine(char * buf, PRUint32 bufSize) PRInt32 nsMsgBodyHandler::GetNextLocalLine(char * buf, int bufSize) // returns number of bytes copied { - if (m_numLocalLines) - { - if (m_passedHeaders) - m_numLocalLines--; // the line count is only for body lines - // do we need to check the return value here? - nsCOMPtr fileSpec; - nsresult rv = m_scope->GetMailPath(getter_AddRefs(fileSpec)); - if (NS_SUCCEEDED(rv) && fileSpec) - { - PRBool isEof = PR_FALSE; - rv = fileSpec->Eof(&isEof); - if (NS_SUCCEEDED(rv) && isEof) - return -1; - - PRBool wasTruncated = PR_FALSE; - rv = fileSpec->ReadLine(&buf, bufSize, &wasTruncated); - if (NS_SUCCEEDED(rv) && !wasTruncated) - return nsCRT::strlen(buf); - } - } - - return -1; + if (m_numLocalLines) + { + m_numLocalLines--; // the line count is for header and body lines + // do we need to check the return value here? + if (m_fileSpec) + { + PRBool isEof = PR_FALSE; + nsresult rv = m_fileSpec->Eof(&isEof); + if (NS_SUCCEEDED(rv) && isEof) + return -1; + + PRBool wasTruncated = PR_FALSE; + rv = m_fileSpec->ReadLine(&buf, bufSize, &wasTruncated); + if (NS_SUCCEEDED(rv) && !wasTruncated) + return nsCRT::strlen(buf); + } + } + + return -1; } PRInt32 nsMsgBodyHandler::ApplyTransformations (char *buf, PRInt32 length, PRBool &eatThisLine) { - PRInt32 newLength = length; - eatThisLine = PR_FALSE; - - if (!m_passedHeaders) // buf is a line from the message headers - { - if (m_stripHeaders) - eatThisLine = PR_TRUE; - - if (!nsCRT::strncasecmp(buf, "Content-Type:", 13) && PL_strcasestr (buf, "text/html")) - m_messageIsHtml = PR_TRUE; - - m_passedHeaders = EMPTY_MESSAGE_LINE(buf); - } - else // buf is a line from the message body - { - if (m_stripHtml && m_messageIsHtml) - { - StripHtml (buf); - newLength = nsCRT::strlen (buf); - } - } - - return newLength; + PRInt32 newLength = length; + eatThisLine = PR_FALSE; + + if (!m_passedHeaders) // buf is a line from the message headers + { + if (m_stripHeaders) + eatThisLine = PR_TRUE; + + if (!nsCRT::strncasecmp(buf, "Content-Type:", 13) && PL_strcasestr (buf, "text/html")) + m_messageIsHtml = PR_TRUE; + + m_passedHeaders = EMPTY_MESSAGE_LINE(buf); + } + else // buf is a line from the message body + { + if (m_stripHtml && m_messageIsHtml) + { + StripHtml (buf); + newLength = nsCRT::strlen (buf); + } + } + + return newLength; } void nsMsgBodyHandler::StripHtml (char *pBufInOut) { - char *pBuf = (char*) PR_Malloc (nsCRT::strlen(pBufInOut) + 1); - if (pBuf) - { - char *pWalk = pBuf; - char *pWalkInOut = pBufInOut; - PRBool inTag = PR_FALSE; - while (*pWalkInOut) // throw away everything inside < > - { - if (!inTag) - if (*pWalkInOut == '<') - inTag = PR_TRUE; - else - *pWalk++ = *pWalkInOut; - else - if (*pWalkInOut == '>') - inTag = PR_FALSE; - pWalkInOut++; - } - *pWalk = 0; // null terminator - - // copy the temp buffer back to the real one - pWalk = pBuf; - pWalkInOut = pBufInOut; - while (*pWalk) - *pWalkInOut++ = *pWalk++; - *pWalkInOut = *pWalk; // null terminator - PR_Free (pBuf); - } + char *pBuf = (char*) PR_Malloc (nsCRT::strlen(pBufInOut) + 1); + if (pBuf) + { + char *pWalk = pBuf; + char *pWalkInOut = pBufInOut; + PRBool inTag = PR_FALSE; + while (*pWalkInOut) // throw away everything inside < > + { + if (!inTag) + if (*pWalkInOut == '<') + inTag = PR_TRUE; + else + *pWalk++ = *pWalkInOut; + else + if (*pWalkInOut == '>') + inTag = PR_FALSE; + pWalkInOut++; + } + *pWalk = 0; // null terminator + + // copy the temp buffer back to the real one + pWalk = pBuf; + pWalkInOut = pBufInOut; + while (*pWalk) + *pWalkInOut++ = *pWalk++; + *pWalkInOut = *pWalk; // null terminator + PR_Free (pBuf); + } } diff --git a/mozilla/mailnews/base/search/src/nsMsgLocalSearch.cpp b/mozilla/mailnews/base/search/src/nsMsgLocalSearch.cpp index 873f324c309..38c01a17f70 100644 --- a/mozilla/mailnews/base/search/src/nsMsgLocalSearch.cpp +++ b/mozilla/mailnews/base/search/src/nsMsgLocalSearch.cpp @@ -578,11 +578,11 @@ nsresult nsMsgSearchOfflineMail::MatchTerms(nsIMsgDBHdr *msgToMatch, break; case nsMsgSearchAttrib::Body: { - nsMsgKey messageKey; + nsMsgKey messageOffset; PRUint32 lineCount; - msgToMatch->GetMessageKey(&messageKey); + msgToMatch->GetMessageOffset(&messageOffset); msgToMatch->GetLineCount(&lineCount); - err = pTerm->MatchBody (scope, messageKey, lineCount, charset, msgToMatch, db, &result); + err = pTerm->MatchBody (scope, messageOffset, lineCount, charset, msgToMatch, db, &result); } break; case nsMsgSearchAttrib::Date: diff --git a/mozilla/mailnews/base/search/src/nsMsgSearchTerm.cpp b/mozilla/mailnews/base/search/src/nsMsgSearchTerm.cpp index fef3e390c20..7f787945831 100644 --- a/mozilla/mailnews/base/search/src/nsMsgSearchTerm.cpp +++ b/mozilla/mailnews/base/search/src/nsMsgSearchTerm.cpp @@ -1314,16 +1314,6 @@ PRBool nsMsgSearchScopeTerm::IsOfflineMail () return PR_TRUE; // if POP or IMAP in offline mode } -PRBool nsMsgSearchScopeTerm::IsOfflineIMAPMail() -{ - // Find out whether "this" mail folder is an offline IMAP folder - NS_ASSERTION(m_folder, "scope doesn't have folder"); - nsCOMPtr imapFolder = do_QueryInterface(m_folder); - if (imapFolder && (nsMsgSearchAdapter::SearchIsOffline() || !m_searchServer)) - return PR_TRUE; - return PR_FALSE; // we are not an IMAP folder that is offline -} - nsresult nsMsgSearchScopeTerm::GetMailPath(nsIFileSpec **aFileSpec) { return (m_folder) ? m_folder->GetPath(aFileSpec) : NS_ERROR_NULL_POINTER; @@ -1337,51 +1327,51 @@ nsresult nsMsgSearchScopeTerm::TimeSlice (PRBool *aDone) nsresult nsMsgSearchScopeTerm::InitializeAdapter (nsISupportsArray *termList) { - if (m_adapter) - return NS_OK; - - nsresult err = NS_OK; - - // mscott: i have added m_searchServer into this switch to take into account the user's preference - // for searching locally or on the server... - switch (m_attribute) - { - case nsMsgSearchScope::MailFolder: + if (m_adapter) + return NS_OK; + + nsresult err = NS_OK; + + // mscott: i have added m_searchServer into this switch to take into account the user's preference + // for searching locally or on the server... + switch (m_attribute) + { + case nsMsgSearchScope::MailFolder: // since we don't support offline, we're either doing an online imap search // or an offline mail search. - if (!IsOfflineMail()) // Online IMAP && searching the server? - m_adapter = new nsMsgSearchOnlineMail (this, termList); - else - m_adapter = new nsMsgSearchOfflineMail (this, termList); - break; - case nsMsgSearchScope::Newsgroup: + if (!IsOfflineMail()) // Online IMAP && searching the server? + m_adapter = new nsMsgSearchOnlineMail (this, termList); + else + m_adapter = new nsMsgSearchOfflineMail (this, termList); + break; + case nsMsgSearchScope::Newsgroup: #ifdef DOING_EXNEWSSEARCH - if (m_folder->KnowsSearchNntpExtension()) - m_adapter = new nsMsgSearchNewsEx (this, termList); - else + if (m_folder->KnowsSearchNntpExtension()) + m_adapter = new nsMsgSearchNewsEx (this, termList); + else #endif - m_adapter = new nsMsgSearchNews (this, termList); - break; + m_adapter = new nsMsgSearchNews (this, termList); + break; #ifdef DOING_EXNEWSSEARCH - case nsMsgSearchScope::AllSearchableGroups: - m_adapter = new msMsgSearchNewsEx (this, termList); - break; + case nsMsgSearchScope::AllSearchableGroups: + m_adapter = new msMsgSearchNewsEx (this, termList); + break; #endif - case nsMsgSearchScope::LdapDirectory: + case nsMsgSearchScope::LdapDirectory: NS_ASSERTION(PR_FALSE, "not supporting LDAP yet"); - break; - case nsMsgSearchScope::OfflineNewsgroup: + break; + case nsMsgSearchScope::OfflineNewsgroup: m_adapter = new nsMsgSearchOfflineNews (this, termList); - break; - default: - NS_ASSERTION(PR_FALSE, "invalid scope"); - err = NS_ERROR_FAILURE; - } - - if (m_adapter) - err = m_adapter->ValidateTerms (); - - return err; + break; + default: + NS_ASSERTION(PR_FALSE, "invalid scope"); + err = NS_ERROR_FAILURE; + } + + if (m_adapter) + err = m_adapter->ValidateTerms (); + + return err; } diff --git a/mozilla/mailnews/base/util/nsMsgDBFolder.cpp b/mozilla/mailnews/base/util/nsMsgDBFolder.cpp index 83a54ecab10..07ce7130724 100644 --- a/mozilla/mailnews/base/util/nsMsgDBFolder.cpp +++ b/mozilla/mailnews/base/util/nsMsgDBFolder.cpp @@ -1295,6 +1295,7 @@ nsresult nsMsgDBFolder::StartNewOfflineMessage() { nsresult rv = GetOfflineStoreOutputStream(getter_AddRefs(m_tempMessageStream)); WriteStartOfNewLocalMessage(); + m_numOfflineMsgLines = 0; return rv; } @@ -1317,6 +1318,7 @@ nsresult nsMsgDBFolder::EndNewOfflineMessage() randomStore->Tell(&curStorePos); m_offlineHeader->GetMessageOffset(&messageOffset); m_offlineHeader->SetOfflineMessageSize(curStorePos - messageOffset); + m_offlineHeader->SetLineCount(m_numOfflineMsgLines); } m_offlineHeader = nsnull; return NS_OK; diff --git a/mozilla/mailnews/base/util/nsMsgDBFolder.h b/mozilla/mailnews/base/util/nsMsgDBFolder.h index 4c1ff99227e..c6a045fb69e 100644 --- a/mozilla/mailnews/base/util/nsMsgDBFolder.h +++ b/mozilla/mailnews/base/util/nsMsgDBFolder.h @@ -45,43 +45,43 @@ class NS_MSG_BASE nsMsgDBFolder: public nsMsgFolder, public nsIUrlListener { public: - nsMsgDBFolder(void); - virtual ~nsMsgDBFolder(void); + nsMsgDBFolder(void); + virtual ~nsMsgDBFolder(void); NS_DECL_NSIDBCHANGELISTENER - NS_IMETHOD StartFolderLoading(void); - NS_IMETHOD EndFolderLoading(void); - NS_IMETHOD GetCharset(PRUnichar * *aCharset); - NS_IMETHOD SetCharset(const PRUnichar * aCharset); - NS_IMETHOD GetCharsetOverride(PRBool *aCharsetOverride); - NS_IMETHOD SetCharsetOverride(PRBool aCharsetOverride); - NS_IMETHOD GetFirstNewMessage(nsIMsgDBHdr **firstNewMessage); - NS_IMETHOD ClearNewMessages(); + NS_IMETHOD StartFolderLoading(void); + NS_IMETHOD EndFolderLoading(void); + NS_IMETHOD GetCharset(PRUnichar * *aCharset); + NS_IMETHOD SetCharset(const PRUnichar * aCharset); + NS_IMETHOD GetCharsetOverride(PRBool *aCharsetOverride); + NS_IMETHOD SetCharsetOverride(PRBool aCharsetOverride); + NS_IMETHOD GetFirstNewMessage(nsIMsgDBHdr **firstNewMessage); + NS_IMETHOD ClearNewMessages(); NS_IMETHOD GetFlags(PRUint32 *aFlags); NS_IMETHOD GetExpungedBytes(PRUint32 *count); NS_IMETHOD GetMsgDatabase(nsIMsgWindow *aMsgWindow, nsIMsgDatabase** aMsgDatabase); - NS_DECL_ISUPPORTS_INHERITED + NS_DECL_ISUPPORTS_INHERITED - NS_DECL_NSIURLLISTENER + NS_DECL_NSIURLLISTENER - NS_IMETHOD WriteToFolderCache(nsIMsgFolderCache *folderCache, PRBool deep); - NS_IMETHOD WriteToFolderCacheElem(nsIMsgFolderCacheElement *element); - NS_IMETHOD ReadFromFolderCacheElem(nsIMsgFolderCacheElement *element); - NS_IMETHOD ManyHeadersToDownload(PRBool *_retval); + NS_IMETHOD WriteToFolderCache(nsIMsgFolderCache *folderCache, PRBool deep); + NS_IMETHOD WriteToFolderCacheElem(nsIMsgFolderCacheElement *element); + NS_IMETHOD ReadFromFolderCacheElem(nsIMsgFolderCacheElement *element); + NS_IMETHOD ManyHeadersToDownload(PRBool *_retval); NS_IMETHOD AddMessageDispositionState(nsIMsgDBHdr *aMessage, nsMsgDispositionState aDispositionFlag); - NS_IMETHOD MarkAllMessagesRead(void); + NS_IMETHOD MarkAllMessagesRead(void); NS_IMETHOD MarkThreadRead(nsIMsgThread *thread); NS_IMETHOD SetFlag(PRUint32 flag); - NS_IMETHOD Shutdown(PRBool shutdownChildren); + NS_IMETHOD Shutdown(PRBool shutdownChildren); NS_IMETHOD ForceDBClosed(); - NS_IMETHOD GetHasNewMessages(PRBool *hasNewMessages); - NS_IMETHOD SetHasNewMessages(PRBool hasNewMessages); + NS_IMETHOD GetHasNewMessages(PRBool *hasNewMessages); + NS_IMETHOD SetHasNewMessages(PRBool hasNewMessages); NS_IMETHOD GetGettingNewMessages(PRBool *gettingNewMessages); NS_IMETHOD SetGettingNewMessages(PRBool gettingNewMessages); @@ -96,17 +96,17 @@ public: NS_IMETHOD SetDownloadSettings(nsIMsgDownloadSettings *settings); protected: - virtual nsresult ReadDBFolderInfo(PRBool force); + virtual nsresult ReadDBFolderInfo(PRBool force); virtual nsresult FlushToFolderCache(); - virtual nsresult GetDatabase(nsIMsgWindow *aMsgWindow) = 0; - virtual nsresult SendFlagNotifications(nsISupports *item, PRUint32 oldFlags, PRUint32 newFlags); - nsresult CheckWithNewMessagesStatus(PRBool messageAdded); - nsresult OnKeyAddedOrDeleted(nsMsgKey aKeyChanged, nsMsgKey aParentKey , PRInt32 aFlags, - nsIDBChangeListener * aInstigator, PRBool added, PRBool doFlat, PRBool doThread); - nsresult CreatePlatformLeafNameForDisk(const char *userLeafName, nsFileSpec &baseDir, char **resultName); + virtual nsresult GetDatabase(nsIMsgWindow *aMsgWindow) = 0; + virtual nsresult SendFlagNotifications(nsISupports *item, PRUint32 oldFlags, PRUint32 newFlags); + nsresult CheckWithNewMessagesStatus(PRBool messageAdded); + nsresult OnKeyAddedOrDeleted(nsMsgKey aKeyChanged, nsMsgKey aParentKey , PRInt32 aFlags, + nsIDBChangeListener * aInstigator, PRBool added, PRBool doFlat, PRBool doThread); + nsresult CreatePlatformLeafNameForDisk(const char *userLeafName, nsFileSpec &baseDir, char **resultName); - nsresult GetFolderCacheKey(nsIFileSpec **aFileSpec); - nsresult GetFolderCacheElemFromFileSpec(nsIFileSpec *fileSpec, nsIMsgFolderCacheElement **cacheElement); + nsresult GetFolderCacheKey(nsIFileSpec **aFileSpec); + nsresult GetFolderCacheElemFromFileSpec(nsIFileSpec *fileSpec, nsIMsgFolderCacheElement **cacheElement); nsresult NotifyStoreClosedAllHeaders(); virtual nsresult GetOfflineStoreInputStream(nsIInputStream **inputStream); @@ -120,16 +120,17 @@ protected: nsresult MsgFitsDownloadCriteria(nsMsgKey msgKey, PRBool *result); protected: - nsCOMPtr mDatabase; - nsString mCharset; - PRBool mCharsetOverride; - PRBool mAddListener; - PRBool mNewMessages; + nsCOMPtr mDatabase; + nsString mCharset; + PRBool mCharsetOverride; + PRBool mAddListener; + PRBool mNewMessages; PRBool mGettingNewMessages; nsCOMPtr m_offlineHeader; + PRInt32 m_numOfflineMsgLines; // this is currently used when we do a save as of an imap or news message.. - nsCOMPtr m_tempMessageStream; + nsCOMPtr m_tempMessageStream; nsCOMPtr m_retentionSettings; nsCOMPtr m_downloadSettings; diff --git a/mozilla/mailnews/imap/src/nsImapMailFolder.cpp b/mozilla/mailnews/imap/src/nsImapMailFolder.cpp index f5a4e53c71c..e43d880fefe 100644 --- a/mozilla/mailnews/imap/src/nsImapMailFolder.cpp +++ b/mozilla/mailnews/imap/src/nsImapMailFolder.cpp @@ -3293,7 +3293,20 @@ nsImapMailFolder::ParseAdoptedMsgLine(const char *adoptedMessageLine, nsMsgKey u GetMessageHeader(uidOfMessage, getter_AddRefs(m_offlineHeader)); rv = StartNewOfflineMessage(); } - + // adoptedMessageLine is actually a string with a lot of message lines, separated by native line terminators + // we need to count the number of MSG_LINEBREAK's to determine how much to increment m_numOfflineMsgLines by. + if (m_downloadMessageForOfflineUse) + { + const char *nextLine = adoptedMessageLine; + do + { + m_numOfflineMsgLines++; + nextLine = PL_strstr(nextLine, MSG_LINEBREAK); + if (nextLine) + nextLine += MSG_LINEBREAK_LEN; + } + while (nextLine && *nextLine); + } if (m_tempMessageStream) { rv = m_tempMessageStream->Write(adoptedMessageLine, @@ -4462,7 +4475,12 @@ nsImapMailFolder::SetUrlState(nsIImapProtocol* aProtocol, nsresult statusCode) { if (!isRunning) + { ProgressStatus(aProtocol, IMAP_DONE, nsnull); + m_urlRunning = PR_FALSE; + m_downloadingFolderForOfflineUse = PR_FALSE; + SetNotifyDownloadedLines(PR_FALSE); + } if (aUrl) return aUrl->SetUrlState(isRunning, statusCode); diff --git a/mozilla/mailnews/news/src/nsNewsFolder.cpp b/mozilla/mailnews/news/src/nsNewsFolder.cpp index ce6f970958c..9a9c3ceb992 100644 --- a/mozilla/mailnews/news/src/nsNewsFolder.cpp +++ b/mozilla/mailnews/news/src/nsNewsFolder.cpp @@ -131,20 +131,20 @@ NS_IMPL_RELEASE_INHERITED(nsMsgNewsFolder, nsMsgDBFolder) NS_IMETHODIMP nsMsgNewsFolder::QueryInterface(REFNSIID aIID, void** aInstancePtr) { - if (!aInstancePtr) return NS_ERROR_NULL_POINTER; - *aInstancePtr = nsnull; - if (aIID.Equals(NS_GET_IID(nsIMsgNewsFolder))) - { - *aInstancePtr = NS_STATIC_CAST(nsIMsgNewsFolder*, this); - } - - if(*aInstancePtr) - { - AddRef(); - return NS_OK; - } - - return nsMsgDBFolder::QueryInterface(aIID, aInstancePtr); + if (!aInstancePtr) return NS_ERROR_NULL_POINTER; + *aInstancePtr = nsnull; + if (aIID.Equals(NS_GET_IID(nsIMsgNewsFolder))) + { + *aInstancePtr = NS_STATIC_CAST(nsIMsgNewsFolder*, this); + } + + if(*aInstancePtr) + { + AddRef(); + return NS_OK; + } + + return nsMsgDBFolder::QueryInterface(aIID, aInstancePtr); } //////////////////////////////////////////////////////////////////////////////// @@ -198,53 +198,53 @@ nsMsgNewsFolder::GetReadSetStr(char **setStr) NS_IMETHODIMP nsMsgNewsFolder::AddNewsgroup(const char *name, const char *setStr, nsIMsgFolder **child) { - nsresult rv = NS_OK; - - NS_ENSURE_ARG_POINTER(child); - NS_ENSURE_ARG_POINTER(setStr); - NS_ENSURE_ARG_POINTER(name); + nsresult rv = NS_OK; - nsCOMPtr rdf = do_GetService(kRDFServiceCID, &rv); - if (NS_FAILED(rv)) return rv; - if (!rdf) return NS_ERROR_FAILURE; - - nsCOMPtr nntpServer; - rv = GetNntpServer(getter_AddRefs(nntpServer)); - if (NS_FAILED(rv)) return rv; - - nsCAutoString uri(mURI); - uri.Append('/'); - // URI should use UTF-8 - // (see RFC2396 Uniform Resource Identifiers (URI): Generic Syntax) - // since we are forcing it to be latin-1 (IS0-8859-1) - // we can just assign with conversion - nsAutoString newsgroupName; - newsgroupName.AssignWithConversion(name); - - nsXPIDLCString escapedName; - rv = NS_MsgEscapeEncodeURLPath(newsgroupName.get(), getter_Copies(escapedName)); - if (NS_FAILED(rv)) return rv; - - rv = nntpServer->AddNewsgroup(escapedName.get()); - if (NS_FAILED(rv)) return rv; - - uri.Append(escapedName.get()); - - nsCOMPtr res; - rv = rdf->GetResource(uri.get(), getter_AddRefs(res)); - if (NS_FAILED(rv)) return rv; + NS_ENSURE_ARG_POINTER(child); + NS_ENSURE_ARG_POINTER(setStr); + NS_ENSURE_ARG_POINTER(name); - nsCOMPtr folder(do_QueryInterface(res, &rv)); - if (NS_FAILED(rv)) return rv; + nsCOMPtr rdf = do_GetService(kRDFServiceCID, &rv); + if (NS_FAILED(rv)) return rv; + if (!rdf) return NS_ERROR_FAILURE; - rv = folder->SetParent(this); - NS_ENSURE_SUCCESS(rv,rv); - - // this what shows up in the UI - rv = folder->SetName(newsgroupName.get()); - NS_ENSURE_SUCCESS(rv,rv); - - rv = folder->SetFlag(MSG_FOLDER_FLAG_NEWSGROUP); + nsCOMPtr nntpServer; + rv = GetNntpServer(getter_AddRefs(nntpServer)); + if (NS_FAILED(rv)) return rv; + + nsCAutoString uri(mURI); + uri.Append('/'); + // URI should use UTF-8 + // (see RFC2396 Uniform Resource Identifiers (URI): Generic Syntax) + // since we are forcing it to be latin-1 (IS0-8859-1) + // we can just assign with conversion + nsAutoString newsgroupName; + newsgroupName.AssignWithConversion(name); + + nsXPIDLCString escapedName; + rv = NS_MsgEscapeEncodeURLPath(newsgroupName.get(), getter_Copies(escapedName)); + if (NS_FAILED(rv)) return rv; + + rv = nntpServer->AddNewsgroup(escapedName.get()); + if (NS_FAILED(rv)) return rv; + + uri.Append(escapedName.get()); + + nsCOMPtr res; + rv = rdf->GetResource(uri.get(), getter_AddRefs(res)); + if (NS_FAILED(rv)) return rv; + + nsCOMPtr folder(do_QueryInterface(res, &rv)); + if (NS_FAILED(rv)) return rv; + + rv = folder->SetParent(this); + NS_ENSURE_SUCCESS(rv,rv); + + // this what shows up in the UI + rv = folder->SetName(newsgroupName.get()); + NS_ENSURE_SUCCESS(rv,rv); + + rv = folder->SetFlag(MSG_FOLDER_FLAG_NEWSGROUP); if (NS_FAILED(rv)) return rv; nsCOMPtr newsFolder(do_QueryInterface(res, &rv)); @@ -327,21 +327,21 @@ nsMsgNewsFolder::AddDirectorySeparator(nsFileSpec &path) NS_IMETHODIMP nsMsgNewsFolder::GetSubFolders(nsIEnumerator* *result) { - nsresult rv; - + nsresult rv; + if (!mInitialized) { // do this first, so we make sure to do it, even on failure. // see bug #70494 mInitialized = PR_TRUE; - - nsCOMPtr pathSpec; - rv = GetPath(getter_AddRefs(pathSpec)); - if (NS_FAILED(rv)) return rv; - - nsFileSpec path; - rv = pathSpec->GetFileSpec(&path); - if (NS_FAILED(rv)) return rv; - + + nsCOMPtr pathSpec; + rv = GetPath(getter_AddRefs(pathSpec)); + if (NS_FAILED(rv)) return rv; + + nsFileSpec path; + rv = pathSpec->GetFileSpec(&path); + if (NS_FAILED(rv)) return rv; + rv = CreateSubFolders(path); if (NS_FAILED(rv)) return rv; @@ -373,42 +373,42 @@ nsMsgNewsFolder::ReplaceElement(nsISupports* element, nsISupports* newElement) //returns NS_OK. Otherwise returns a failure error value. nsresult nsMsgNewsFolder::GetDatabase(nsIMsgWindow *aMsgWindow) { - nsresult rv; - if (!mDatabase) - { - nsCOMPtr pathSpec; - rv = GetPath(getter_AddRefs(pathSpec)); - if (NS_FAILED(rv)) return rv; - - nsresult folderOpen = NS_OK; - nsCOMPtr newsDBFactory; - - rv = nsComponentManager::CreateInstance(kCNewsDB, nsnull, NS_GET_IID(nsIMsgDatabase), getter_AddRefs(newsDBFactory)); - if (NS_SUCCEEDED(rv) && newsDBFactory) { - folderOpen = newsDBFactory->OpenFolderDB(this, PR_TRUE, PR_FALSE, getter_AddRefs(mDatabase)); - } - - if (mDatabase) { - if(mAddListener) - rv = mDatabase->AddListener(this); - - nsCOMPtr db(do_QueryInterface(mDatabase, &rv)); - if (NS_FAILED(rv)) return rv; - - nsXPIDLCString setStr; - - rv = GetCachedNewsrcLine(getter_Copies(setStr)); - if (NS_FAILED(rv)) return rv; - - rv = db->SetReadSetStr((const char *)setStr); - if (NS_FAILED(rv)) return rv; - } - if (NS_FAILED(rv)) return rv; - - rv = UpdateSummaryTotals(PR_TRUE); - if (NS_FAILED(rv)) return rv; - } - return NS_OK; + nsresult rv; + if (!mDatabase) + { + nsCOMPtr pathSpec; + rv = GetPath(getter_AddRefs(pathSpec)); + if (NS_FAILED(rv)) return rv; + + nsresult folderOpen = NS_OK; + nsCOMPtr newsDBFactory; + + rv = nsComponentManager::CreateInstance(kCNewsDB, nsnull, NS_GET_IID(nsIMsgDatabase), getter_AddRefs(newsDBFactory)); + if (NS_SUCCEEDED(rv) && newsDBFactory) { + folderOpen = newsDBFactory->OpenFolderDB(this, PR_TRUE, PR_FALSE, getter_AddRefs(mDatabase)); + } + + if (mDatabase) { + if(mAddListener) + rv = mDatabase->AddListener(this); + + nsCOMPtr db(do_QueryInterface(mDatabase, &rv)); + if (NS_FAILED(rv)) return rv; + + nsXPIDLCString setStr; + + rv = GetCachedNewsrcLine(getter_Copies(setStr)); + if (NS_FAILED(rv)) return rv; + + rv = db->SetReadSetStr((const char *)setStr); + if (NS_FAILED(rv)) return rv; + } + if (NS_FAILED(rv)) return rv; + + rv = UpdateSummaryTotals(PR_TRUE); + if (NS_FAILED(rv)) return rv; + } + return NS_OK; } @@ -537,107 +537,107 @@ NS_IMETHODIMP nsMsgNewsFolder::SetNewsrcHasChanged(PRBool newsrcHasChanged) NS_IMETHODIMP nsMsgNewsFolder::CreateSubfolder(const PRUnichar *uninewsgroupname, nsIMsgWindow *msgWindow) { - nsresult rv = NS_OK; - - NS_ENSURE_ARG_POINTER(uninewsgroupname); - if (nsCRT::strlen(uninewsgroupname) == 0) return NS_ERROR_FAILURE; - - nsCAutoString newsgroupname; - newsgroupname.AssignWithConversion(uninewsgroupname); - - nsFileSpec path; - nsCOMPtr pathSpec; - rv = GetPath(getter_AddRefs(pathSpec)); - if (NS_FAILED(rv)) return rv; - - rv = pathSpec->GetFileSpec(&path); - - nsCOMPtr child; - - // Create an empty database for this mail folder, set its name from the user - nsCOMPtr newsDBFactory; - nsCOMPtr newsDB; - - //Now we have a valid directory or we have returned. - //Make sure the new folder name is valid - - // remember, some file systems (like mac) can't handle long file names - nsCAutoString hashedName = newsgroupname; - rv = NS_MsgHashIfNecessary(hashedName); - path += (const char *) hashedName; - - rv = nsComponentManager::CreateInstance(kCNewsDB, nsnull, NS_GET_IID(nsIMsgDatabase), getter_AddRefs(newsDBFactory)); - if (NS_SUCCEEDED(rv) && newsDBFactory) { - nsCOMPtr dbFileSpec; - NS_NewFileSpecWithSpec(path, getter_AddRefs(dbFileSpec)); - rv = newsDBFactory->Open(dbFileSpec, PR_TRUE, PR_FALSE, getter_AddRefs(newsDB)); - if (NS_SUCCEEDED(rv) && newsDB) { - //Now let's create the actual new folder - rv = AddNewsgroup(newsgroupname, "", getter_AddRefs(child)); - - rv = SetNewsrcHasChanged(PR_TRUE); - - newsDB->SetSummaryValid(PR_TRUE); - newsDB->Close(PR_TRUE); - } - else - { - rv = NS_MSG_CANT_CREATE_FOLDER; - } - } - if(NS_SUCCEEDED(rv) && child) - { - nsCOMPtr childSupports(do_QueryInterface(child)); - nsCOMPtr folderSupports; - rv = QueryInterface(NS_GET_IID(nsISupports), getter_AddRefs(folderSupports)); - if(childSupports && NS_SUCCEEDED(rv)) - { - - NotifyItemAdded(folderSupports, childSupports, "folderView"); - } - } - return rv; + nsresult rv = NS_OK; + + NS_ENSURE_ARG_POINTER(uninewsgroupname); + if (nsCRT::strlen(uninewsgroupname) == 0) return NS_ERROR_FAILURE; + + nsCAutoString newsgroupname; + newsgroupname.AssignWithConversion(uninewsgroupname); + + nsFileSpec path; + nsCOMPtr pathSpec; + rv = GetPath(getter_AddRefs(pathSpec)); + if (NS_FAILED(rv)) return rv; + + rv = pathSpec->GetFileSpec(&path); + + nsCOMPtr child; + + // Create an empty database for this mail folder, set its name from the user + nsCOMPtr newsDBFactory; + nsCOMPtr newsDB; + + //Now we have a valid directory or we have returned. + //Make sure the new folder name is valid + + // remember, some file systems (like mac) can't handle long file names + nsCAutoString hashedName = newsgroupname; + rv = NS_MsgHashIfNecessary(hashedName); + path += (const char *) hashedName; + + rv = nsComponentManager::CreateInstance(kCNewsDB, nsnull, NS_GET_IID(nsIMsgDatabase), getter_AddRefs(newsDBFactory)); + if (NS_SUCCEEDED(rv) && newsDBFactory) { + nsCOMPtr dbFileSpec; + NS_NewFileSpecWithSpec(path, getter_AddRefs(dbFileSpec)); + rv = newsDBFactory->Open(dbFileSpec, PR_TRUE, PR_FALSE, getter_AddRefs(newsDB)); + if (NS_SUCCEEDED(rv) && newsDB) { + //Now let's create the actual new folder + rv = AddNewsgroup(newsgroupname, "", getter_AddRefs(child)); + + rv = SetNewsrcHasChanged(PR_TRUE); + + newsDB->SetSummaryValid(PR_TRUE); + newsDB->Close(PR_TRUE); + } + else + { + rv = NS_MSG_CANT_CREATE_FOLDER; + } + } + if(NS_SUCCEEDED(rv) && child) + { + nsCOMPtr childSupports(do_QueryInterface(child)); + nsCOMPtr folderSupports; + rv = QueryInterface(NS_GET_IID(nsISupports), getter_AddRefs(folderSupports)); + if(childSupports && NS_SUCCEEDED(rv)) + { + + NotifyItemAdded(folderSupports, childSupports, "folderView"); + } + } + return rv; } NS_IMETHODIMP nsMsgNewsFolder::Delete() { - nsresult rv = GetDatabase(nsnull); - - if(NS_SUCCEEDED(rv)) { - mDatabase->ForceClosed(); - mDatabase = nsnull; - } - - nsCOMPtr pathSpec; - rv = GetPath(getter_AddRefs(pathSpec)); - if (NS_FAILED(rv)) return rv; - - nsFileSpec path; - rv = pathSpec->GetFileSpec(&path); - if (NS_FAILED(rv)) return rv; - - // Remove summary file. - nsNewsSummarySpec summarySpec(path); - summarySpec.Delete(PR_FALSE); - - nsCOMPtr nntpServer; - rv = GetNntpServer(getter_AddRefs(nntpServer)); - if (NS_FAILED(rv)) return rv; - - nsXPIDLString name; - rv = GetName(getter_Copies(name)); - NS_ENSURE_SUCCESS(rv,rv); - - nsXPIDLCString escapedName; - rv = NS_MsgEscapeEncodeURLPath(name.get(), getter_Copies(escapedName)); - NS_ENSURE_SUCCESS(rv,rv); - - rv = nntpServer->RemoveNewsgroup(escapedName.get()); - NS_ENSURE_SUCCESS(rv,rv); - - rv = SetNewsrcHasChanged(PR_TRUE); - NS_ENSURE_SUCCESS(rv,rv); - return rv; + nsresult rv = GetDatabase(nsnull); + + if(NS_SUCCEEDED(rv)) { + mDatabase->ForceClosed(); + mDatabase = nsnull; + } + + nsCOMPtr pathSpec; + rv = GetPath(getter_AddRefs(pathSpec)); + if (NS_FAILED(rv)) return rv; + + nsFileSpec path; + rv = pathSpec->GetFileSpec(&path); + if (NS_FAILED(rv)) return rv; + + // Remove summary file. + nsNewsSummarySpec summarySpec(path); + summarySpec.Delete(PR_FALSE); + + nsCOMPtr nntpServer; + rv = GetNntpServer(getter_AddRefs(nntpServer)); + if (NS_FAILED(rv)) return rv; + + nsXPIDLString name; + rv = GetName(getter_Copies(name)); + NS_ENSURE_SUCCESS(rv,rv); + + nsXPIDLCString escapedName; + rv = NS_MsgEscapeEncodeURLPath(name.get(), getter_Copies(escapedName)); + NS_ENSURE_SUCCESS(rv,rv); + + rv = nntpServer->RemoveNewsgroup(escapedName.get()); + NS_ENSURE_SUCCESS(rv,rv); + + rv = SetNewsrcHasChanged(PR_TRUE); + NS_ENSURE_SUCCESS(rv,rv); + return rv; } NS_IMETHODIMP nsMsgNewsFolder::Rename(const PRUnichar *newName, nsIMsgWindow *msgWindow) @@ -662,17 +662,17 @@ NS_IMETHODIMP nsMsgNewsFolder::GetAbbreviatedName(PRUnichar * *aAbbreviatedName) if (NS_FAILED(rv)) return rv; if (!isNewsServer) { - nsCOMPtr nntpServer; - rv = GetNntpServer(getter_AddRefs(nntpServer)); - if (NS_FAILED(rv)) return rv; - - PRBool abbreviate = PR_TRUE; - rv = nntpServer->GetAbbreviate(&abbreviate); - if (NS_FAILED(rv)) return rv; - - if (abbreviate) { - rv = AbbreviatePrettyName(aAbbreviatedName, 1 /* hardcoded for now */); - } + nsCOMPtr nntpServer; + rv = GetNntpServer(getter_AddRefs(nntpServer)); + if (NS_FAILED(rv)) return rv; + + PRBool abbreviate = PR_TRUE; + rv = nntpServer->GetAbbreviate(&abbreviate); + if (NS_FAILED(rv)) return rv; + + if (abbreviate) { + rv = AbbreviatePrettyName(aAbbreviatedName, 1 /* hardcoded for now */); + } } return rv; @@ -694,28 +694,28 @@ NS_IMETHODIMP nsMsgNewsFolder::GetAbbreviatedName(PRUnichar * *aAbbreviatedName) nsresult nsMsgNewsFolder::AbbreviatePrettyName(PRUnichar ** prettyName, PRInt32 fullwords) { if (!prettyName) - return NS_ERROR_NULL_POINTER; + return NS_ERROR_NULL_POINTER; nsAutoString name(*prettyName); PRInt32 totalwords = 0; // total no. of words - + // get the total no. of words PRInt32 pos = 0; while(1) { - pos = name.FindChar('.', PR_FALSE, pos); - if(pos == -1) - { - totalwords++; - break; - } - else - { - totalwords++; - pos++; - } + pos = name.FindChar('.', PR_FALSE, pos); + if(pos == -1) + { + totalwords++; + break; + } + else + { + totalwords++; + pos++; + } } - + // get the no. of words to abbreviate PRInt32 abbrevnum = totalwords - fullwords; if (abbrevnum < 1) @@ -793,121 +793,121 @@ nsMsgNewsFolder::GetDBFolderInfoAndDB(nsIDBFolderInfo **folderInfo, nsIMsgDataba NS_IMETHODIMP nsMsgNewsFolder::UpdateSummaryFromNNTPInfo(PRInt32 oldest, PRInt32 youngest, PRInt32 total) { - nsresult rv = NS_OK; - PRBool newsrcHasChanged = PR_FALSE; - PRInt32 oldUnreadMessages = mNumUnreadMessages; - PRInt32 oldTotalMessages = mNumTotalMessages; - - nsMsgKeySet *set = nsnull; - if (mDatabase) { - nsCOMPtr db(do_QueryInterface(mDatabase, &rv)); - if (NS_FAILED(rv)) return rv; - - rv = db->GetReadSet(&set); - if (NS_FAILED(rv)) return rv; - } - else { - nsXPIDLCString cachedNewsrcLine; + nsresult rv = NS_OK; + PRBool newsrcHasChanged = PR_FALSE; + PRInt32 oldUnreadMessages = mNumUnreadMessages; + PRInt32 oldTotalMessages = mNumTotalMessages; + + nsMsgKeySet *set = nsnull; + if (mDatabase) { + nsCOMPtr db(do_QueryInterface(mDatabase, &rv)); + if (NS_FAILED(rv)) return rv; + + rv = db->GetReadSet(&set); + if (NS_FAILED(rv)) return rv; + } + else { + nsXPIDLCString cachedNewsrcLine; rv = GetCachedNewsrcLine(getter_Copies(cachedNewsrcLine)); - if (NS_FAILED(rv)) return rv; - - set = nsMsgKeySet::Create((const char *)cachedNewsrcLine); - } - - if (!set) return NS_ERROR_FAILURE; - + if (NS_FAILED(rv)) return rv; + + set = nsMsgKeySet::Create((const char *)cachedNewsrcLine); + } + + if (!set) return NS_ERROR_FAILURE; + char *setStr = nsnull; - /* First, mark all of the articles now known to be expired as read. */ - if (oldest > 1) { + /* First, mark all of the articles now known to be expired as read. */ + if (oldest > 1) { nsXPIDLCString oldSet; set->Output(getter_Copies(oldSet)); - set->AddRange(1, oldest - 1); - rv = set->Output(&setStr); + set->AddRange(1, oldest - 1); + rv = set->Output(&setStr); if (setStr && nsCRT::strcmp(setStr, oldSet)) - newsrcHasChanged = PR_TRUE; - } - - /* Now search the newsrc line and figure out how many of these messages are marked as unread. */ - - /* make sure youngest is a least 1. MSNews seems to return a youngest of 0. */ - if (youngest == 0) { - youngest = 1; - } - - PRInt32 unread = set->CountMissingInRange(oldest, youngest); - NS_ASSERTION(unread >= 0,"CountMissingInRange reported unread < 0"); - if (unread < 0) return NS_ERROR_FAILURE; - if (unread > total) { - /* This can happen when the newsrc file shows more unread than exist in the group (total is not necessarily `end - start'.) */ - unread = total; - PRInt32 deltaInDB = mNumTotalMessages - mNumUnreadMessages; - //PRint32 deltaInDB = m_totalInDB - m_unreadInDB; - /* if we know there are read messages in the db, subtract that from the unread total */ - if (deltaInDB > 0) { - unread -= deltaInDB; - } - } - - mNumUnreadMessages = unread; - mNumTotalMessages = total; + newsrcHasChanged = PR_TRUE; + } + + /* Now search the newsrc line and figure out how many of these messages are marked as unread. */ + + /* make sure youngest is a least 1. MSNews seems to return a youngest of 0. */ + if (youngest == 0) { + youngest = 1; + } + + PRInt32 unread = set->CountMissingInRange(oldest, youngest); + NS_ASSERTION(unread >= 0,"CountMissingInRange reported unread < 0"); + if (unread < 0) return NS_ERROR_FAILURE; + if (unread > total) { + /* This can happen when the newsrc file shows more unread than exist in the group (total is not necessarily `end - start'.) */ + unread = total; + PRInt32 deltaInDB = mNumTotalMessages - mNumUnreadMessages; + //PRint32 deltaInDB = m_totalInDB - m_unreadInDB; + /* if we know there are read messages in the db, subtract that from the unread total */ + if (deltaInDB > 0) { + unread -= deltaInDB; + } + } + + mNumUnreadMessages = unread; + mNumTotalMessages = total; #if 0 - m_nntpHighwater = youngest; - m_nntpTotalArticles = total; + m_nntpHighwater = youngest; + m_nntpTotalArticles = total; #endif - - //Need to notify listeners that total count changed. - if(oldTotalMessages != mNumTotalMessages) { - NotifyIntPropertyChanged(kTotalMessagesAtom, oldTotalMessages, mNumTotalMessages); - } - - if(oldUnreadMessages != mNumUnreadMessages) { - NotifyIntPropertyChanged(kTotalUnreadMessagesAtom, oldUnreadMessages, mNumUnreadMessages); - } - - /* re-cache the newsrc line. */ - if (!mDatabase) { - if (setStr) { - nsCAutoString newsrcLine(setStr); - newsrcLine += MSG_LINEBREAK; - rv = SetCachedNewsrcLine((const char *)newsrcLine); - NS_ASSERTION(NS_SUCCEEDED(rv),"SetCachedNewsrcLine() failed"); - - if (newsrcHasChanged) { - rv = SetNewsrcHasChanged(PR_TRUE); - NS_ASSERTION(NS_SUCCEEDED(rv),"SetNewsrcHasChanged() failed"); - } - } + + //Need to notify listeners that total count changed. + if(oldTotalMessages != mNumTotalMessages) { + NotifyIntPropertyChanged(kTotalMessagesAtom, oldTotalMessages, mNumTotalMessages); + } + + if(oldUnreadMessages != mNumUnreadMessages) { + NotifyIntPropertyChanged(kTotalUnreadMessagesAtom, oldUnreadMessages, mNumUnreadMessages); + } + + /* re-cache the newsrc line. */ + if (!mDatabase) { + if (setStr) { + nsCAutoString newsrcLine(setStr); + newsrcLine += MSG_LINEBREAK; + rv = SetCachedNewsrcLine((const char *)newsrcLine); + NS_ASSERTION(NS_SUCCEEDED(rv),"SetCachedNewsrcLine() failed"); + + if (newsrcHasChanged) { + rv = SetNewsrcHasChanged(PR_TRUE); + NS_ASSERTION(NS_SUCCEEDED(rv),"SetNewsrcHasChanged() failed"); + } + } delete set; // If !mDatabase then we own set, thus we should delete it. - } - nsCRT::free(setStr); - setStr = nsnull; - return rv; + } + nsCRT::free(setStr); + setStr = nsnull; + return rv; } NS_IMETHODIMP nsMsgNewsFolder::UpdateSummaryTotals(PRBool force) { if (!mNotifyCountChanges) return NS_OK; - - PRInt32 oldUnreadMessages = mNumUnreadMessages; - PRInt32 oldTotalMessages = mNumTotalMessages; - //We need to read this info from the database - nsresult ret = ReadDBFolderInfo(force); - - if (NS_SUCCEEDED(ret)) - { - //Need to notify listeners that total count changed. - if(oldTotalMessages != mNumTotalMessages) { - NotifyIntPropertyChanged(kTotalMessagesAtom, oldTotalMessages, mNumTotalMessages); - } - - if(oldUnreadMessages != mNumUnreadMessages) { - NotifyIntPropertyChanged(kTotalUnreadMessagesAtom, oldUnreadMessages, mNumUnreadMessages); - } - - FlushToFolderCache(); + + PRInt32 oldUnreadMessages = mNumUnreadMessages; + PRInt32 oldTotalMessages = mNumTotalMessages; + //We need to read this info from the database + nsresult ret = ReadDBFolderInfo(force); + + if (NS_SUCCEEDED(ret)) + { + //Need to notify listeners that total count changed. + if(oldTotalMessages != mNumTotalMessages) { + NotifyIntPropertyChanged(kTotalMessagesAtom, oldTotalMessages, mNumTotalMessages); } - return ret; + + if(oldUnreadMessages != mNumUnreadMessages) { + NotifyIntPropertyChanged(kTotalUnreadMessagesAtom, oldUnreadMessages, mNumUnreadMessages); + } + + FlushToFolderCache(); + } + return ret; } NS_IMETHODIMP nsMsgNewsFolder::GetExpungedBytesCount(PRUint32 *count) @@ -1104,39 +1104,39 @@ nsMsgNewsFolder::HandleLine(char* line, PRUint32 line_size) PRInt32 nsMsgNewsFolder::HandleNewsrcLine(char* line, PRUint32 line_size) { - nsresult rv; - - /* guard against blank line lossage */ - if (line[0] == '#' || line[0] == nsCRT::CR || line[0] == nsCRT::LF) return 0; - - line[line_size] = 0; - - if ((line[0] == 'o' || line[0] == 'O') && - !PL_strncasecmp (line, "options", 7)) { - return RememberLine(line); - } - - char *s = nsnull; - char *setStr = nsnull; - char *end = line + line_size; - - for (s = line; s < end; s++) - if ((*s == ':') || (*s == '!')) - break; - - if (*s == 0) { - /* What is this?? Well, don't just throw it away... */ - return RememberLine(line); - } - - PRBool subscribed = (*s == ':'); - setStr = s+1; - *s = '\0'; + nsresult rv; - if (*line == '\0') { - return 0; - } - + /* guard against blank line lossage */ + if (line[0] == '#' || line[0] == nsCRT::CR || line[0] == nsCRT::LF) return 0; + + line[line_size] = 0; + + if ((line[0] == 'o' || line[0] == 'O') && + !PL_strncasecmp (line, "options", 7)) { + return RememberLine(line); + } + + char *s = nsnull; + char *setStr = nsnull; + char *end = line + line_size; + + for (s = line; s < end; s++) + if ((*s == ':') || (*s == '!')) + break; + + if (*s == 0) { + /* What is this?? Well, don't just throw it away... */ + return RememberLine(line); + } + + PRBool subscribed = (*s == ':'); + setStr = s+1; + *s = '\0'; + + if (*line == '\0') { + return 0; + } + // previous versions of Communicator poluted the // newsrc files with articles // (this would happen when you clicked on a link like @@ -1181,26 +1181,26 @@ nsMsgNewsFolder::HandleNewsrcLine(char* line, PRUint32 line_size) nsresult nsMsgNewsFolder::RememberUnsubscribedGroup(const char *newsgroup, const char *setStr) { - if (newsgroup) { - mUnsubscribedNewsgroupLines += newsgroup; - mUnsubscribedNewsgroupLines += "! "; - if (setStr) { - mUnsubscribedNewsgroupLines += setStr; - } - else { - mUnsubscribedNewsgroupLines += MSG_LINEBREAK; - } + if (newsgroup) { + mUnsubscribedNewsgroupLines += newsgroup; + mUnsubscribedNewsgroupLines += "! "; + if (setStr) { + mUnsubscribedNewsgroupLines += setStr; } - return NS_OK; + else { + mUnsubscribedNewsgroupLines += MSG_LINEBREAK; + } + } + return NS_OK; } PRInt32 nsMsgNewsFolder::RememberLine(const char* line) { - mOptionLines = line; - mOptionLines += MSG_LINEBREAK; - - return 0; + mOptionLines = line; + mOptionLines += MSG_LINEBREAK; + + return 0; } nsresult nsMsgNewsFolder::ForgetLine() @@ -1211,29 +1211,29 @@ nsresult nsMsgNewsFolder::ForgetLine() NS_IMETHODIMP nsMsgNewsFolder::GetGroupUsername(char **aGroupUsername) { - NS_ENSURE_ARG_POINTER(aGroupUsername); - nsresult rv; - - if (mGroupUsername) { - *aGroupUsername = nsCRT::strdup(mGroupUsername); - rv = NS_OK; - } - else { - rv = NS_ERROR_FAILURE; - } - - return rv; + NS_ENSURE_ARG_POINTER(aGroupUsername); + nsresult rv; + + if (mGroupUsername) { + *aGroupUsername = nsCRT::strdup(mGroupUsername); + rv = NS_OK; + } + else { + rv = NS_ERROR_FAILURE; + } + + return rv; } NS_IMETHODIMP nsMsgNewsFolder::SetGroupUsername(const char *aGroupUsername) { - PR_FREEIF(mGroupUsername); - - if (aGroupUsername) { - mGroupUsername = nsCRT::strdup(aGroupUsername); - } - - return NS_OK; + PR_FREEIF(mGroupUsername); + + if (aGroupUsername) { + mGroupUsername = nsCRT::strdup(aGroupUsername); + } + + return NS_OK; } NS_IMETHODIMP nsMsgNewsFolder::GetGroupPassword(char **aGroupPassword) @@ -1254,13 +1254,13 @@ NS_IMETHODIMP nsMsgNewsFolder::GetGroupPassword(char **aGroupPassword) NS_IMETHODIMP nsMsgNewsFolder::SetGroupPassword(const char *aGroupPassword) { - PR_FREEIF(mGroupPassword); - - if (aGroupPassword) { - mGroupPassword = nsCRT::strdup(aGroupPassword); - } - - return NS_OK; + PR_FREEIF(mGroupPassword); + + if (aGroupPassword) { + mGroupPassword = nsCRT::strdup(aGroupPassword); + } + + return NS_OK; } nsresult nsMsgNewsFolder::CreateNewsgroupUsernameUrlForSignon(const char *inUriStr, char **result) @@ -1376,15 +1376,15 @@ nsMsgNewsFolder::GetGroupPasswordWithUI(const PRUnichar * aPromptMessage, const dialog = do_GetInterface(webShell, &rv); if (NS_FAILED(rv)) return rv; } - else { - nsCOMPtr wwatch(do_GetService("@mozilla.org/embedcomp/window-watcher;1")); - if (wwatch) - wwatch->GetNewAuthPrompter(0, getter_AddRefs(dialog)); + else { + nsCOMPtr wwatch(do_GetService("@mozilla.org/embedcomp/window-watcher;1")); + if (wwatch) + wwatch->GetNewAuthPrompter(0, getter_AddRefs(dialog)); - if (!dialog) return NS_ERROR_FAILURE; - } - - NS_ASSERTION(dialog,"we didn't get a net prompt"); + if (!dialog) return NS_ERROR_FAILURE; + } + + NS_ASSERTION(dialog,"we didn't get a net prompt"); if (dialog) { nsXPIDLString uniGroupPassword; @@ -1422,18 +1422,18 @@ nsMsgNewsFolder::GetGroupUsernameWithUI(const PRUnichar * aPromptMessage, const nsIMsgWindow* aMsgWindow, char **aGroupUsername) { - nsresult rv = NS_ERROR_FAILURE;; - - NS_ENSURE_ARG_POINTER(aGroupUsername); - - if (!mGroupUsername) { - // prompt the user for the username - - nsCOMPtr dialog; + nsresult rv = NS_ERROR_FAILURE;; + + NS_ENSURE_ARG_POINTER(aGroupUsername); + + if (!mGroupUsername) { + // prompt the user for the username + + nsCOMPtr dialog; #ifdef DEBUG_seth - NS_ASSERTION(aMsgWindow,"no msg window"); + NS_ASSERTION(aMsgWindow,"no msg window"); #endif - if (aMsgWindow) { + if (aMsgWindow) { // prompt the user for the password nsCOMPtr docShell; rv = aMsgWindow->GetRootDocShell(getter_AddRefs(docShell)); @@ -1441,96 +1441,96 @@ nsMsgNewsFolder::GetGroupUsernameWithUI(const PRUnichar * aPromptMessage, const nsCOMPtr webShell(do_QueryInterface(docShell, &rv)); if (NS_FAILED(rv)) return rv; dialog = do_GetInterface(webShell, &rv); - if (NS_FAILED(rv)) return rv; + if (NS_FAILED(rv)) return rv; } - else { - nsCOMPtr wwatch(do_GetService("@mozilla.org/embedcomp/window-watcher;1")); - if (wwatch) - wwatch->GetNewAuthPrompter(0, getter_AddRefs(dialog)); - - if (!dialog) return NS_ERROR_FAILURE; - } - - NS_ASSERTION(dialog,"we didn't get a net prompt"); - if (dialog) { - nsXPIDLString uniGroupUsername; - - PRBool okayValue = PR_TRUE; - - nsXPIDLCString signonURL; - rv = CreateNewsgroupUsernameUrlForSignon(mURI, getter_Copies(signonURL)); - if (NS_FAILED(rv)) return rv; - - rv = dialog->Prompt(aPromptTitle, aPromptMessage, NS_ConvertASCIItoUCS2(NS_STATIC_CAST(const char*, signonURL)).get(), - nsIAuthPrompt::SAVE_PASSWORD_PERMANENTLY, nsnull, - getter_Copies(uniGroupUsername), &okayValue); - if (NS_FAILED(rv)) return rv; - - if (!okayValue) // if the user pressed cancel, just return NULL; - { - *aGroupUsername= nsnull; - return rv; - } - - // we got a username back, remember it - nsCAutoString aCStr; aCStr.AssignWithConversion(uniGroupUsername); - rv = SetGroupUsername((const char *) aCStr); - if (NS_FAILED(rv)) return rv; - - } // if we got a prompt dialog - } // if the password is empty - - rv = GetGroupUsername(aGroupUsername); - return rv; + else { + nsCOMPtr wwatch(do_GetService("@mozilla.org/embedcomp/window-watcher;1")); + if (wwatch) + wwatch->GetNewAuthPrompter(0, getter_AddRefs(dialog)); + + if (!dialog) return NS_ERROR_FAILURE; + } + + NS_ASSERTION(dialog,"we didn't get a net prompt"); + if (dialog) { + nsXPIDLString uniGroupUsername; + + PRBool okayValue = PR_TRUE; + + nsXPIDLCString signonURL; + rv = CreateNewsgroupUsernameUrlForSignon(mURI, getter_Copies(signonURL)); + if (NS_FAILED(rv)) return rv; + + rv = dialog->Prompt(aPromptTitle, aPromptMessage, NS_ConvertASCIItoUCS2(NS_STATIC_CAST(const char*, signonURL)).get(), + nsIAuthPrompt::SAVE_PASSWORD_PERMANENTLY, nsnull, + getter_Copies(uniGroupUsername), &okayValue); + if (NS_FAILED(rv)) return rv; + + if (!okayValue) // if the user pressed cancel, just return NULL; + { + *aGroupUsername= nsnull; + return rv; + } + + // we got a username back, remember it + nsCAutoString aCStr; aCStr.AssignWithConversion(uniGroupUsername); + rv = SetGroupUsername((const char *) aCStr); + if (NS_FAILED(rv)) return rv; + + } // if we got a prompt dialog + } // if the password is empty + + rv = GetGroupUsername(aGroupUsername); + return rv; } nsresult nsMsgNewsFolder::CreateBaseMessageURI(const char *aURI) { - nsresult rv; + nsresult rv; - rv = nsCreateNewsBaseMessageURI(aURI, &mBaseMessageURI); - return rv; + rv = nsCreateNewsBaseMessageURI(aURI, &mBaseMessageURI); + return rv; } NS_IMETHODIMP nsMsgNewsFolder::GetNewsrcLine(char **newsrcLine) { - nsresult rv; - - if (!newsrcLine) return NS_ERROR_NULL_POINTER; - - nsXPIDLCString newsgroupname; - rv = GetAsciiName(getter_Copies(newsgroupname)); - if (NS_FAILED(rv)) return rv; - - nsCAutoString newsrcLineStr; - newsrcLineStr = (const char *)newsgroupname; - newsrcLineStr += ":"; - - nsXPIDLCString setStr; - rv = GetReadSetStr(getter_Copies(setStr)); - if (NS_SUCCEEDED(rv)) { - newsrcLineStr += " "; - newsrcLineStr += setStr; - newsrcLineStr += MSG_LINEBREAK; + nsresult rv; + + if (!newsrcLine) return NS_ERROR_NULL_POINTER; + + nsXPIDLCString newsgroupname; + rv = GetAsciiName(getter_Copies(newsgroupname)); + if (NS_FAILED(rv)) return rv; + + nsCAutoString newsrcLineStr; + newsrcLineStr = (const char *)newsgroupname; + newsrcLineStr += ":"; + + nsXPIDLCString setStr; + rv = GetReadSetStr(getter_Copies(setStr)); + if (NS_SUCCEEDED(rv)) { + newsrcLineStr += " "; + newsrcLineStr += setStr; + newsrcLineStr += MSG_LINEBREAK; + } + else { + nsXPIDLCString cachedNewsrcLine; + rv = GetCachedNewsrcLine(getter_Copies(cachedNewsrcLine)); + if (NS_SUCCEEDED(rv) && ((const char *)cachedNewsrcLine) && (PL_strlen((const char *)cachedNewsrcLine))) { + newsrcLineStr += (const char *)cachedNewsrcLine; } else { - nsXPIDLCString cachedNewsrcLine; - rv = GetCachedNewsrcLine(getter_Copies(cachedNewsrcLine)); - if (NS_SUCCEEDED(rv) && ((const char *)cachedNewsrcLine) && (PL_strlen((const char *)cachedNewsrcLine))) { - newsrcLineStr += (const char *)cachedNewsrcLine; - } - else { - newsrcLineStr += " "; - newsrcLineStr += MSG_LINEBREAK; - } + newsrcLineStr += " "; + newsrcLineStr += MSG_LINEBREAK; } - - *newsrcLine = nsCRT::strdup((const char *)newsrcLineStr); - - if (!*newsrcLine) return NS_ERROR_OUT_OF_MEMORY; - - return NS_OK; + } + + *newsrcLine = nsCRT::strdup((const char *)newsrcLineStr); + + if (!*newsrcLine) return NS_ERROR_OUT_OF_MEMORY; + + return NS_OK; } NS_IMETHODIMP @@ -1712,6 +1712,8 @@ NS_IMETHODIMP nsMsgNewsFolder::NotifyDownloadedLine(const char *line, nsMsgKey k rv = StartNewOfflineMessage(); } + m_numOfflineMsgLines++; + if (m_tempMessageStream) { if (line[0] == '.' && line[1] == 0)