mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-08 12:37:37 +00:00
128f95aa9b
Revising nsIChannel to allow for overlapped i/o. This consists of three parts: 1. Factoring nsIChannel into a protocol specific part, the nsIChannel, and a socket specific, the nsITransport. 2. Derive the nsIChannel from a nsIRequest. 2. Changes the notification system from necko and the URILoader to pass the nsIRequest interface instead of nsIChannel interface. This goal stems from wanting to be able to have active AsyncRead and AsyncWrite operations on nsSocketTransport. This is desired because it would greatly simplify the task of maintaining persistent/reusable socket connections for FTP, HTTP, and Imap (and potentially other protocols). The problem with the existing nsIChannel interface is that it does not allow one to selectively suspend just one of the read or write operations while keeping the other active. r=darin@netscape.com sr=rpotts@netscape.com
2548 lines
62 KiB
C++
2548 lines
62 KiB
C++
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
*
|
|
* The contents of this file are subject to the Netscape Public
|
|
* License Version 1.1 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.mozilla.org/NPL/
|
|
*
|
|
* Software distributed under the License is distributed on an "AS
|
|
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
|
* implied. See the License for the specific language governing
|
|
* rights and limitations under the License.
|
|
*
|
|
* The Original Code is mozilla.org code.
|
|
*
|
|
* The Initial Developer of the Original Code is Netscape
|
|
* Communications Corporation. Portions created by Netscape are
|
|
* Copyright (C) 1998 Netscape Communications Corporation. All
|
|
* Rights Reserved.
|
|
*
|
|
* Contributor(s):
|
|
* Pierre Phaneuf <pp@ludusdesign.com>
|
|
*/
|
|
|
|
#include "msgCore.h" // precompiled header...
|
|
|
|
#include "prprf.h"
|
|
|
|
#include "nsISupportsArray.h"
|
|
#include "nsIServiceManager.h"
|
|
#include "nsXPIDLString.h"
|
|
#include "nsCOMPtr.h"
|
|
#include "nsAutoLock.h"
|
|
#include "nsMemory.h"
|
|
#include "nsIStringBundle.h"
|
|
|
|
#include "nsMsgFolder.h"
|
|
#include "nsMsgFolderFlags.h"
|
|
#include "nsIMessage.h"
|
|
#include "nsMsgKeyArray.h"
|
|
#include "nsMsgDatabase.h"
|
|
#include "nsIDBFolderInfo.h"
|
|
#include "nsIMsgAccountManager.h"
|
|
#include "nsIMsgIdentity.h"
|
|
#include "nsMsgBaseCID.h"
|
|
#include "nsMsgUtils.h" // for NS_MsgHashIfNecessary()
|
|
#include "nsMsgI18N.h"
|
|
|
|
#include "nsIPref.h"
|
|
|
|
#include "nsIRDFService.h"
|
|
#include "nsRDFCID.h"
|
|
|
|
#include "nsIIOService.h"
|
|
#include "nsIURL.h"
|
|
|
|
static NS_DEFINE_CID(kStandardUrlCID, NS_STANDARDURL_CID);
|
|
static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
|
|
static NS_DEFINE_CID(kMsgFolderListenerManagerCID, NS_MSGMAILSESSION_CID);
|
|
static NS_DEFINE_CID(kIOServiceCID, NS_IOSERVICE_CID);
|
|
static NS_DEFINE_CID(kStringBundleServiceCID, NS_STRINGBUNDLESERVICE_CID);
|
|
|
|
nsrefcnt nsMsgFolder::gInstanceCount = 0;
|
|
|
|
PRUnichar *nsMsgFolder::kInboxName = 0;
|
|
PRUnichar *nsMsgFolder::kTrashName = 0;
|
|
PRUnichar *nsMsgFolder::kSentName = 0;
|
|
PRUnichar *nsMsgFolder::kDraftsName = 0;
|
|
PRUnichar *nsMsgFolder::kTemplatesName = 0;
|
|
PRUnichar *nsMsgFolder::kUnsentName = 0;
|
|
|
|
nsIAtom * nsMsgFolder::kTotalMessagesAtom = nsnull;
|
|
nsIAtom * nsMsgFolder::kBiffStateAtom = nsnull;
|
|
nsIAtom * nsMsgFolder::kNewMessagesAtom = nsnull;
|
|
nsIAtom * nsMsgFolder::kNumNewBiffMessagesAtom = nsnull;
|
|
nsIAtom * nsMsgFolder::kTotalUnreadMessagesAtom = nsnull;
|
|
nsIAtom * nsMsgFolder::kFlaggedAtom = nsnull;
|
|
nsIAtom * nsMsgFolder::kStatusAtom = nsnull;
|
|
nsIAtom * nsMsgFolder::kNameAtom = nsnull;
|
|
|
|
#ifdef MSG_FASTER_URI_PARSING
|
|
nsCOMPtr<nsIURL> nsMsgFolder::mParsingURL;
|
|
PRBool nsMsgFolder::mParsingURLInUse=PR_FALSE;
|
|
#endif
|
|
|
|
nsMsgFolder::nsMsgFolder(void)
|
|
: nsRDFResource(),
|
|
mFlags(0),
|
|
mNumUnreadMessages(-1),
|
|
mNumTotalMessages(-1),
|
|
mNotifyCountChanges(PR_TRUE),
|
|
mExpungedBytes(0),
|
|
mInitializedFromCache(PR_FALSE),
|
|
mBiffState(nsMsgBiffState_NoMail),
|
|
mNumNewBiffMessages(0),
|
|
mHaveParsedURI(PR_FALSE),
|
|
mIsServerIsValid(PR_FALSE),
|
|
mIsServer(PR_FALSE),
|
|
mDeleteIsMoveToTrash(PR_TRUE),
|
|
mBaseMessageURI(nsnull)
|
|
{
|
|
// NS_INIT_REFCNT(); done by superclass
|
|
|
|
mSemaphoreHolder = NULL;
|
|
|
|
mNumPendingUnreadMessages = 0;
|
|
mNumPendingTotalMessages = 0;
|
|
NS_NewISupportsArray(getter_AddRefs(mSubFolders));
|
|
|
|
mIsCachable = PR_TRUE;
|
|
|
|
mListeners = new nsVoidArray();
|
|
|
|
if (gInstanceCount == 0) {
|
|
kBiffStateAtom = NS_NewAtom("BiffState");
|
|
kNewMessagesAtom = NS_NewAtom("NewMessages");
|
|
kNumNewBiffMessagesAtom = NS_NewAtom("NumNewBiffMessages");
|
|
kNameAtom = NS_NewAtom("Name");
|
|
kTotalUnreadMessagesAtom = NS_NewAtom("TotalUnreadMessages");
|
|
kTotalMessagesAtom = NS_NewAtom("TotalMessages");
|
|
kStatusAtom = NS_NewAtom("Status");
|
|
kFlaggedAtom = NS_NewAtom("Flagged");
|
|
|
|
initializeStrings();
|
|
|
|
#ifdef MSG_FASTER_URI_PARSING
|
|
mParsingURL = do_CreateInstance(kStandardUrlCID);
|
|
#endif
|
|
}
|
|
|
|
gInstanceCount++;
|
|
}
|
|
|
|
nsMsgFolder::~nsMsgFolder(void)
|
|
{
|
|
nsresult rv;
|
|
|
|
if(mSubFolders)
|
|
{
|
|
PRUint32 count;
|
|
rv = mSubFolders->Count(&count);
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "Count failed");
|
|
|
|
for (int i = count - 1; i >= 0; i--)
|
|
mSubFolders->RemoveElementAt(i);
|
|
}
|
|
|
|
delete mListeners;
|
|
|
|
if(mBaseMessageURI)
|
|
nsCRT::free(mBaseMessageURI);
|
|
|
|
gInstanceCount--;
|
|
if (gInstanceCount <= 0) {
|
|
NS_IF_RELEASE(kTotalMessagesAtom);
|
|
NS_IF_RELEASE(kBiffStateAtom);
|
|
NS_IF_RELEASE(kNewMessagesAtom);
|
|
NS_IF_RELEASE(kNumNewBiffMessagesAtom);
|
|
NS_IF_RELEASE(kTotalUnreadMessagesAtom);
|
|
NS_IF_RELEASE(kFlaggedAtom);
|
|
NS_IF_RELEASE(kStatusAtom);
|
|
NS_IF_RELEASE(kNameAtom);
|
|
|
|
CRTFREEIF(kInboxName);
|
|
CRTFREEIF(kTrashName);
|
|
CRTFREEIF(kSentName);
|
|
CRTFREEIF(kDraftsName);
|
|
CRTFREEIF(kTemplatesName);
|
|
CRTFREEIF(kUnsentName);
|
|
|
|
#ifdef MSG_FASTER_URI_PARSING
|
|
mParsingURL = nsnull;
|
|
#endif
|
|
}
|
|
}
|
|
|
|
NS_IMPL_ISUPPORTS_INHERITED3(nsMsgFolder, nsRDFResource,
|
|
nsIMsgFolder,
|
|
nsIFolder,
|
|
nsISupportsWeakReference)
|
|
|
|
nsresult
|
|
nsMsgFolder::initializeStrings()
|
|
{
|
|
nsresult rv;
|
|
nsCOMPtr<nsIStringBundleService> bundleService =
|
|
do_GetService(kStringBundleServiceCID, &rv);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
nsCOMPtr<nsIStringBundle> bundle;
|
|
rv = bundleService->CreateBundle("chrome://messenger/locale/messenger.properties",
|
|
nsnull,
|
|
getter_AddRefs(bundle));
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
bundle->GetStringFromName(NS_ConvertASCIItoUCS2("inboxFolderName").GetUnicode(),
|
|
&kInboxName);
|
|
bundle->GetStringFromName(NS_ConvertASCIItoUCS2("trashFolderName").GetUnicode(),
|
|
&kTrashName);
|
|
bundle->GetStringFromName(NS_ConvertASCIItoUCS2("sentFolderName").GetUnicode(),
|
|
&kSentName);
|
|
bundle->GetStringFromName(NS_ConvertASCIItoUCS2("draftsFolderName").GetUnicode(),
|
|
&kDraftsName);
|
|
bundle->GetStringFromName(NS_ConvertASCIItoUCS2("templatesFolderName").GetUnicode(),
|
|
&kTemplatesName);
|
|
bundle->GetStringFromName(NS_ConvertASCIItoUCS2("unsentFolderName").GetUnicode(),
|
|
&kUnsentName);
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsMsgFolder::Init(const char* aURI)
|
|
{
|
|
// for now, just initialize everything during Init()
|
|
|
|
nsresult rv;
|
|
|
|
rv = nsRDFResource::Init(aURI);
|
|
if(NS_FAILED(rv))
|
|
return rv;
|
|
|
|
rv = CreateBaseMessageURI(aURI);
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult nsMsgFolder::CreateBaseMessageURI(const char *aURI)
|
|
{
|
|
//Each folder needs to implement this.
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsMsgFolder::Shutdown(PRBool shutdownChildren)
|
|
{
|
|
return NS_OK;
|
|
}
|
|
|
|
// nsICollection methods:
|
|
NS_IMETHODIMP
|
|
nsMsgFolder::Count(PRUint32 *result) {
|
|
return mSubFolders->Count(result);
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsMsgFolder::GetElementAt(PRUint32 i, nsISupports* *result) {
|
|
return mSubFolders->GetElementAt(i, result);
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsMsgFolder::QueryElementAt(PRUint32 i, const nsIID & iid, void * *result) {
|
|
return mSubFolders->QueryElementAt(i, iid, result);
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsMsgFolder::SetElementAt(PRUint32 i, nsISupports* value) {
|
|
return mSubFolders->SetElementAt(i, value);
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsMsgFolder::AppendElement(nsISupports *aElement) {
|
|
return mSubFolders->AppendElement(aElement);
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsMsgFolder::RemoveElement(nsISupports *aElement) {
|
|
return mSubFolders->RemoveElement(aElement);
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsMsgFolder::Enumerate(nsIEnumerator* *result) {
|
|
// nsMsgFolders only have subfolders, no message elements
|
|
return mSubFolders->Enumerate(result);
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsMsgFolder::Clear(void) {
|
|
return mSubFolders->Clear();
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsMsgFolder::GetURI(char* *name) {
|
|
return nsRDFResource::GetValue(name);
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
typedef PRBool
|
|
(*nsArrayFilter)(nsISupports* element, void* data);
|
|
|
|
static nsresult
|
|
nsFilterBy(nsISupportsArray* array, nsArrayFilter filter, void* data,
|
|
nsISupportsArray* *result)
|
|
{
|
|
nsCOMPtr<nsISupportsArray> f;
|
|
nsresult rv = NS_NewISupportsArray(getter_AddRefs(f));
|
|
if (NS_FAILED(rv)) return rv;
|
|
PRUint32 cnt;
|
|
rv = array->Count(&cnt);
|
|
if (NS_FAILED(rv)) return rv;
|
|
for (PRUint32 i = 0; i < cnt; i++) {
|
|
nsCOMPtr<nsISupports> element = getter_AddRefs(array->ElementAt(i));
|
|
if (filter(element, data)) {
|
|
rv = f->AppendElement(element);
|
|
if (NS_FAILED(rv)) {
|
|
return rv;
|
|
}
|
|
}
|
|
}
|
|
*result = f;
|
|
return NS_OK;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
NS_IMETHODIMP
|
|
nsMsgFolder::AddUnique(nsISupports* element)
|
|
{
|
|
// XXX fix this
|
|
return mSubFolders->AppendElement(element);
|
|
}
|
|
|
|
// I'm assuming this means "Replace Subfolder"?
|
|
NS_IMETHODIMP
|
|
nsMsgFolder::ReplaceElement(nsISupports* element, nsISupports* newElement)
|
|
{
|
|
PRBool success=PR_FALSE;
|
|
PRInt32 location = mSubFolders->IndexOf(element);
|
|
if (location>0)
|
|
success = mSubFolders->ReplaceElementAt(newElement, location);
|
|
|
|
return success ? NS_OK : NS_ERROR_UNEXPECTED;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsMsgFolder::GetSubFolders(nsIEnumerator* *result)
|
|
{
|
|
return mSubFolders->Enumerate(result);
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsMsgFolder::FindSubFolder(const char *subFolderName, nsIFolder **aFolder)
|
|
{
|
|
nsresult rv = NS_OK;
|
|
NS_WITH_SERVICE(nsIRDFService, rdf, kRDFServiceCID, &rv);
|
|
|
|
if(NS_FAILED(rv))
|
|
return rv;
|
|
|
|
// XXX use necko here
|
|
nsCAutoString uri;
|
|
uri.Append(mURI);
|
|
uri.Append('/');
|
|
|
|
uri.Append(subFolderName);
|
|
|
|
nsCOMPtr<nsIRDFResource> res;
|
|
rv = rdf->GetResource(uri.GetBuffer(), getter_AddRefs(res));
|
|
if (NS_FAILED(rv))
|
|
return rv;
|
|
|
|
nsCOMPtr<nsIFolder> folder(do_QueryInterface(res, &rv));
|
|
if (NS_FAILED(rv))
|
|
return rv;
|
|
if (aFolder)
|
|
{
|
|
*aFolder = folder;
|
|
NS_ADDREF(*aFolder);
|
|
return NS_OK;
|
|
}
|
|
else
|
|
return NS_ERROR_NULL_POINTER;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsMsgFolder::GetHasSubFolders(PRBool *_retval)
|
|
{
|
|
PRUint32 cnt;
|
|
nsresult rv = mSubFolders->Count(&cnt);
|
|
if (NS_FAILED(rv)) return rv;
|
|
*_retval = (cnt > 0);
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsMsgFolder::AddFolderListener(nsIFolderListener * listener)
|
|
{
|
|
mListeners->AppendElement(listener);
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
NS_IMETHODIMP nsMsgFolder::RemoveFolderListener(nsIFolderListener * listener)
|
|
{
|
|
|
|
mListeners->RemoveElement(listener);
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
NS_IMETHODIMP nsMsgFolder::SetParent(nsIFolder *aParent)
|
|
{
|
|
mParent = getter_AddRefs(NS_GetWeakReference(aParent));
|
|
|
|
if (aParent) {
|
|
nsresult rv;
|
|
nsCOMPtr<nsIMsgFolder> parentMsgFolder =
|
|
do_QueryInterface(aParent, &rv);
|
|
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
// servers do not have parents, so we must not be a server
|
|
mIsServer = PR_FALSE;
|
|
mIsServerIsValid = PR_TRUE;
|
|
|
|
// also set the server itself while we're here.
|
|
|
|
nsCOMPtr<nsIMsgIncomingServer> server;
|
|
rv = parentMsgFolder->GetServer(getter_AddRefs(server));
|
|
if (NS_SUCCEEDED(rv) && server)
|
|
mServer = getter_AddRefs(NS_GetWeakReference(server));
|
|
}
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP nsMsgFolder::GetParent(nsIFolder **aParent)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(aParent);
|
|
|
|
nsCOMPtr<nsIFolder> parent = do_QueryReferent(mParent);
|
|
|
|
*aParent = parent;
|
|
NS_IF_ADDREF(*aParent);
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsMsgFolder::HasMessagesOfType(nsIMsgWindow *aMsgWindow, PRUint32 type, PRBool *hasMessages)
|
|
{
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsMsgFolder::GetMessages(nsIMsgWindow *aMsgWindow, nsISimpleEnumerator* *result)
|
|
{
|
|
// XXX should this return an empty enumeration?
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
NS_IMETHODIMP nsMsgFolder::StartFolderLoading(void)
|
|
{
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsMsgFolder::EndFolderLoading(void)
|
|
{
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsMsgFolder::UpdateFolder(nsIMsgWindow *)
|
|
{
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsMsgFolder::HasThreads(nsIMsgWindow *aMsgWindow, PRBool *hasThreads)
|
|
{
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsMsgFolder::GetThreadsOfType(nsIMsgWindow *aMsgWindow, PRUint32 viewType, nsISimpleEnumerator ** threadEnumerator)
|
|
{
|
|
// XXX should this return an empty enumeration?
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsMsgFolder::GetThreadForMessage(nsIMessage *message, nsIMsgThread **thread)
|
|
{
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsMsgFolder::HasMessage(nsIMessage *message, PRBool *hasMessage)
|
|
{
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
NS_IMETHODIMP nsMsgFolder::GetFolderURL(char **url)
|
|
{
|
|
if(*url)
|
|
{
|
|
*url = NULL;
|
|
return NS_OK;
|
|
}
|
|
else
|
|
return NS_ERROR_NULL_POINTER;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP nsMsgFolder::GetServer(nsIMsgIncomingServer ** aServer)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(aServer);
|
|
|
|
nsresult rv;
|
|
|
|
// short circut the server if we have it.
|
|
nsCOMPtr<nsIMsgIncomingServer> server = do_QueryReferent(mServer, &rv);
|
|
if (NS_FAILED(rv) || !server) {
|
|
// try again after parsing the URI
|
|
rv = parseURI(PR_TRUE);
|
|
server = do_QueryReferent(mServer);
|
|
}
|
|
|
|
*aServer = server;
|
|
NS_IF_ADDREF(*aServer);
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
#ifdef MSG_FASTER_URI_PARSING
|
|
class nsMsgAutoBool {
|
|
public:
|
|
nsMsgAutoBool() : mValue(nsnull) {}
|
|
void autoReset(PRBool *aValue) { mValue = aValue; }
|
|
~nsMsgAutoBool() { if (mValue) *mValue = PR_FALSE; }
|
|
private:
|
|
PRBool *mValue;
|
|
};
|
|
#endif
|
|
|
|
nsresult
|
|
nsMsgFolder::parseURI(PRBool needServer)
|
|
{
|
|
nsresult rv;
|
|
nsCOMPtr<nsIURL> url;
|
|
|
|
#ifdef MSG_FASTER_URI_PARSING
|
|
nsMsgAutoBool parsingUrlState;
|
|
if (mParsingURLInUse) {
|
|
url = do_CreateInstance(kStandardUrlCID, &rv);
|
|
}
|
|
|
|
else {
|
|
url = mParsingURL;
|
|
mParsingURLInUse = PR_TRUE;
|
|
parsingUrlState.autoReset(&mParsingURLInUse);
|
|
}
|
|
|
|
#else
|
|
rv = nsComponentManager::CreateInstance(kStandardUrlCID, nsnull,
|
|
NS_GET_IID(nsIURL),
|
|
(void **)getter_AddRefs(url));
|
|
if (NS_FAILED(rv)) return rv;
|
|
#endif
|
|
|
|
rv = url->SetSpec(mURI);
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
NS_WITH_SERVICE(nsIIOService, ioServ, kIOServiceCID, &rv);
|
|
|
|
//
|
|
// pull some info out of the URI
|
|
//
|
|
|
|
// empty path tells us it's a server.
|
|
if (!mIsServerIsValid) {
|
|
nsXPIDLCString path;
|
|
rv = url->GetPath(getter_Copies(path));
|
|
if (NS_SUCCEEDED(rv)) {
|
|
if (!nsCRT::strcmp(path, "/"))
|
|
mIsServer = PR_TRUE;
|
|
else
|
|
mIsServer = PR_FALSE;
|
|
}
|
|
mIsServerIsValid = PR_TRUE;
|
|
}
|
|
|
|
// grab the name off the leaf of the server
|
|
if (mName.IsEmpty()) {
|
|
// mName:
|
|
// the name is the trailing directory in the path
|
|
nsXPIDLCString fileName;
|
|
rv = url->GetFileName(getter_Copies(fileName));
|
|
if (NS_SUCCEEDED(rv) && (const char*)fileName != nsnull) {
|
|
// XXX conversion to unicode here? is fileName in UTF8?
|
|
// yes, let's say it is in utf8
|
|
|
|
nsXPIDLCString result;
|
|
rv = ioServ->Unescape(fileName, getter_Copies(result));
|
|
mName.AssignWithConversion(result);
|
|
}
|
|
}
|
|
|
|
// grab the server by parsing the URI and looking it up
|
|
// in the account manager...
|
|
// But avoid this extra work by first asking the parent, if any
|
|
|
|
nsCOMPtr<nsIMsgIncomingServer> server = do_QueryReferent(mServer, &rv);
|
|
if (NS_FAILED(rv) || !server) {
|
|
|
|
// first try asking the parent instead of the URI
|
|
nsCOMPtr<nsIFolder> parent;
|
|
rv = GetParent(getter_AddRefs(parent));
|
|
|
|
if (NS_SUCCEEDED(rv) && parent) {
|
|
nsCOMPtr<nsIMsgFolder> parentMsgFolder =
|
|
do_QueryInterface(parent, &rv);
|
|
|
|
if (NS_SUCCEEDED(rv))
|
|
rv = parentMsgFolder->GetServer(getter_AddRefs(server));
|
|
}
|
|
|
|
// no parent. do the extra work of asking
|
|
if (!server && needServer) {
|
|
// Get username and hostname so we can get the server
|
|
nsXPIDLCString userName;
|
|
rv = url->GetPreHost(getter_Copies(userName));
|
|
if (NS_SUCCEEDED(rv) && (const char*)userName)
|
|
nsUnescape(NS_CONST_CAST(char*,(const char*)userName));
|
|
|
|
nsXPIDLCString hostName;
|
|
rv = url->GetHost(getter_Copies(hostName));
|
|
if (NS_SUCCEEDED(rv) && (const char*)hostName)
|
|
nsUnescape(NS_CONST_CAST(char*,(const char*)hostName));
|
|
|
|
// turn it back into a server:
|
|
|
|
NS_WITH_SERVICE(nsIMsgAccountManager, accountManager,
|
|
NS_MSGACCOUNTMANAGER_CONTRACTID, &rv);
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
#ifdef DEBUG_alecf
|
|
// this is a failing case, and it would be nice if this
|
|
// was never called
|
|
// (we should ALWAYS handle this case, but try to design
|
|
// the code so we have a parent wherever possible)
|
|
printf("No parent->");
|
|
#endif
|
|
rv = accountManager->FindServer(userName,
|
|
hostName,
|
|
GetIncomingServerType(),
|
|
getter_AddRefs(server));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
}
|
|
|
|
mServer = getter_AddRefs(NS_GetWeakReference(server));
|
|
|
|
} /* !mServer */
|
|
|
|
// now try to find the local path for this folder
|
|
if (server) {
|
|
|
|
nsXPIDLCString urlPath;
|
|
url->GetFilePath(getter_Copies(urlPath));
|
|
|
|
nsXPIDLCString result;
|
|
rv = ioServ->Unescape(urlPath, getter_Copies(result));
|
|
|
|
// transform the filepath from the URI, such as
|
|
// "/folder1/folder2/foldern"
|
|
// to
|
|
// "folder1.sbd/folder2.sbd/foldern"
|
|
// (remove leading / and add .sbd to first n-1 folders)
|
|
// to be appended onto the server's path
|
|
|
|
nsCAutoString newPath;
|
|
NS_MsgCreatePathStringFromFolderURI(result, newPath);
|
|
|
|
// now append munged path onto server path
|
|
nsCOMPtr<nsIFileSpec> serverPath;
|
|
rv = server->GetLocalPath(getter_AddRefs(serverPath));
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
if (serverPath) {
|
|
rv = serverPath->AppendRelativeUnixPath(newPath.GetBuffer());
|
|
NS_ASSERTION(NS_SUCCEEDED(rv),"failed to append to the serverPath");
|
|
if (NS_FAILED(rv)) {
|
|
mPath = null_nsCOMPtr();
|
|
return rv;
|
|
}
|
|
mPath = serverPath;
|
|
}
|
|
|
|
// URI is completely parsed when we've attempted to get the server
|
|
mHaveParsedURI=PR_TRUE;
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsMsgFolder::GetIsServer(PRBool *aResult)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(aResult);
|
|
|
|
// make sure we've parsed the URI
|
|
if (!mIsServerIsValid) {
|
|
nsresult rv = parseURI();
|
|
if (NS_FAILED(rv) || !mIsServerIsValid)
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
*aResult = mIsServer;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsMsgFolder::GetNoSelect(PRBool *aResult)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(aResult);
|
|
*aResult = PR_FALSE;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsMsgFolder::GetCanSubscribe(PRBool *aResult)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(aResult);
|
|
// by default, you can't subscribe.
|
|
// if otherwise, override it.
|
|
*aResult = PR_FALSE;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsMsgFolder::GetCanFileMessages(PRBool *aResult)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(aResult);
|
|
|
|
//varada - checking folder flag to see if it is the "Unsent Messages"
|
|
//and if so return FALSE
|
|
if (mFlags & MSG_FOLDER_FLAG_QUEUE)
|
|
{
|
|
*aResult = PR_FALSE;
|
|
return NS_OK;
|
|
}
|
|
|
|
PRBool isServer = PR_FALSE;
|
|
nsresult rv = GetIsServer(&isServer);
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
// by default, you can't file messages into servers, only to folders
|
|
// if otherwise, override it.
|
|
*aResult = !isServer;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsMsgFolder::GetCanCreateSubfolders(PRBool *aResult)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(aResult);
|
|
|
|
//Checking folder flag to see if it is the "Unsent Messages" or "Inbox"
|
|
//and if so return FALSE
|
|
if ((mFlags & MSG_FOLDER_FLAG_QUEUE) || (mFlags & MSG_FOLDER_FLAG_INBOX))
|
|
{
|
|
*aResult = PR_FALSE;
|
|
return NS_OK;
|
|
}
|
|
|
|
// by default, you can create subfolders on server and folders
|
|
// if otherwise, override it.
|
|
*aResult = PR_TRUE;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsMsgFolder::GetCanRename(PRBool *aResult)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(aResult);
|
|
|
|
PRBool isServer = PR_FALSE;
|
|
nsresult rv = GetIsServer(&isServer);
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
// by default, you can't rename servers, only folders
|
|
// if otherwise, override it.
|
|
if (isServer) {
|
|
*aResult = PR_FALSE;
|
|
}
|
|
// old comment, from the 4.x code base:
|
|
// Here's a weird case necessitated because we don't have a separate
|
|
// preference for any folder name except the FCC folder (Sent). Others
|
|
// are known by name, and as such, can't be renamed. I guess.
|
|
//
|
|
// new comment:
|
|
// we have prefs for drafts and templates now, can we remove those
|
|
// parts of this case?
|
|
else if (mFlags & MSG_FOLDER_FLAG_TRASH ||
|
|
mFlags & MSG_FOLDER_FLAG_DRAFTS ||
|
|
mFlags & MSG_FOLDER_FLAG_QUEUE ||
|
|
mFlags & MSG_FOLDER_FLAG_INBOX ||
|
|
mFlags & MSG_FOLDER_FLAG_TEMPLATES) {
|
|
*aResult = PR_FALSE;
|
|
}
|
|
else {
|
|
*aResult = PR_TRUE;
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsMsgFolder::GetCanCompact(PRBool *aResult)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(aResult);
|
|
|
|
PRBool isServer = PR_FALSE;
|
|
nsresult rv = GetIsServer(&isServer);
|
|
NS_ENSURE_SUCCESS(rv,rv);
|
|
*aResult = !isServer; //servers cannot be compacted --> 4.x
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP nsMsgFolder::GetPrettyName(PRUnichar ** name)
|
|
{
|
|
return GetName(name);
|
|
}
|
|
|
|
NS_IMETHODIMP nsMsgFolder::SetPrettyName(const PRUnichar *name)
|
|
{
|
|
return SetName(name);
|
|
}
|
|
|
|
NS_IMETHODIMP nsMsgFolder::GetName(PRUnichar **name)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(name);
|
|
|
|
nsresult rv;
|
|
if (!mHaveParsedURI && mName.IsEmpty()) {
|
|
rv = parseURI();
|
|
if (NS_FAILED(rv)) return rv;
|
|
}
|
|
|
|
// if it's a server, just forward the call
|
|
if (mIsServer) {
|
|
nsCOMPtr<nsIMsgIncomingServer> server;
|
|
rv = GetServer(getter_AddRefs(server));
|
|
if (NS_SUCCEEDED(rv) && server)
|
|
return server->GetPrettyName(name);
|
|
}
|
|
|
|
*name = mName.ToNewUnicode();
|
|
|
|
if (!(*name)) return NS_ERROR_OUT_OF_MEMORY;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsMsgFolder::SetName(const PRUnichar * name)
|
|
{
|
|
// override the URI-generated name
|
|
if (!mName.EqualsWithConversion(name))
|
|
{
|
|
mName = name;
|
|
|
|
// old/new value doesn't matter here
|
|
NotifyUnicharPropertyChanged(kNameAtom, name, name);
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
//For default, just return name
|
|
NS_IMETHODIMP nsMsgFolder::GetAbbreviatedName(PRUnichar * *aAbbreviatedName)
|
|
{
|
|
return GetName(aAbbreviatedName);
|
|
}
|
|
|
|
NS_IMETHODIMP nsMsgFolder::GetChildNamed(const char *name, nsISupports ** aChild)
|
|
{
|
|
NS_ASSERTION(aChild, "NULL child");
|
|
nsresult rv;
|
|
// will return nsnull if we can't find it
|
|
*aChild = nsnull;
|
|
|
|
nsCOMPtr<nsIMsgFolder> folder;
|
|
|
|
PRUint32 count;
|
|
rv = mSubFolders->Count(&count);
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
nsString uniName;
|
|
ConvertToUnicode(nsMsgI18NFileSystemCharset(), name, uniName);
|
|
|
|
for (PRUint32 i = 0; i < count; i++)
|
|
{
|
|
nsCOMPtr<nsISupports> supports = getter_AddRefs(mSubFolders->ElementAt(i));
|
|
folder = do_QueryInterface(supports, &rv);
|
|
if(NS_SUCCEEDED(rv))
|
|
{
|
|
nsXPIDLString folderName;
|
|
|
|
rv = folder->GetName(getter_Copies(folderName));
|
|
// case-insensitive compare is probably LCD across OS filesystems
|
|
if (NS_SUCCEEDED(rv) && nsCRT::strcasecmp(folderName, uniName.GetUnicode()) == 0)
|
|
{
|
|
*aChild = folder;
|
|
NS_ADDREF(*aChild);
|
|
return NS_OK;
|
|
}
|
|
}
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsMsgFolder::GetChildWithURI(const char *uri, PRBool deep, nsIMsgFolder ** child)
|
|
{
|
|
NS_ASSERTION(child, "NULL child");
|
|
nsresult rv;
|
|
// will return nsnull if we can't find it
|
|
*child = nsnull;
|
|
|
|
nsCOMPtr <nsIEnumerator> aEnumerator;
|
|
|
|
rv = GetSubFolders(getter_AddRefs(aEnumerator));
|
|
if(NS_FAILED(rv))
|
|
return rv;
|
|
|
|
nsCOMPtr<nsISupports> aItem;
|
|
|
|
rv = aEnumerator->First();
|
|
if (!NS_SUCCEEDED(rv))
|
|
return NS_OK; // it's OK, there are no sub-folders.
|
|
|
|
while(NS_SUCCEEDED(rv))
|
|
{
|
|
rv = aEnumerator->CurrentItem(getter_AddRefs(aItem));
|
|
if (NS_FAILED(rv)) break;
|
|
nsCOMPtr<nsIRDFResource> folderResource = do_QueryInterface(aItem);
|
|
nsCOMPtr<nsIMsgFolder> folder = do_QueryInterface(aItem);
|
|
if(folderResource && folder)
|
|
{
|
|
char *folderURI =nsnull;
|
|
rv = folderResource->GetValue(&folderURI);
|
|
if(NS_FAILED(rv)) return rv;
|
|
|
|
PRBool equal = (folderURI && nsCRT::strcmp(folderURI, uri)==0);
|
|
nsMemory::Free(folderURI);
|
|
if (equal)
|
|
{
|
|
*child = folder;
|
|
NS_ADDREF(*child);
|
|
return NS_OK;
|
|
}
|
|
else if(deep)
|
|
{
|
|
rv = folder->GetChildWithURI(uri, deep, child);
|
|
if(NS_FAILED(rv))
|
|
return rv;
|
|
|
|
if(*child)
|
|
return NS_OK;
|
|
}
|
|
}
|
|
rv = aEnumerator->Next();
|
|
if (!NS_SUCCEEDED(rv))
|
|
{
|
|
rv = NS_OK;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsMsgFolder::GetPrettiestName(PRUnichar **name)
|
|
{
|
|
if (NS_SUCCEEDED(GetPrettyName(name)))
|
|
return NS_OK;
|
|
return GetName(name);
|
|
}
|
|
|
|
static PRBool
|
|
nsCanBeInFolderPane(nsISupports* element, void* data)
|
|
{
|
|
#ifdef HAVE_PANE
|
|
nsIMsgFolder* subFolder = NS_STATIC_CAST(nsIMsgFolder*, element);
|
|
return subFolder->CanBeInFolderPane();
|
|
#else
|
|
return PR_TRUE;
|
|
#endif
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsMsgFolder::GetVisibleSubFolders(nsIEnumerator* *result)
|
|
{
|
|
nsresult rv;
|
|
nsCOMPtr<nsISupportsArray> vFolders;
|
|
rv = nsFilterBy(mSubFolders, nsCanBeInFolderPane, nsnull, getter_AddRefs(vFolders));
|
|
if (NS_FAILED(rv)) return rv;
|
|
rv = vFolders->Enumerate(result);
|
|
return rv;
|
|
}
|
|
|
|
#ifdef HAVE_ADMINURL
|
|
NS_IMETHODIMP nsMsgFolder::GetAdminUrl(MWContext *context, MSG_AdminURLType type)
|
|
{
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsMsgFolder::HaveAdminUrl(MSG_AdminURLType type, PRBool *haveAdminUrl)
|
|
{
|
|
if(haveAdminUrl)
|
|
{
|
|
*haveAdminUrl = PR_FALSE;
|
|
return NS_OK;
|
|
}
|
|
return
|
|
NS_ERROR_NULL_POINTER;
|
|
}
|
|
#endif
|
|
|
|
NS_IMETHODIMP nsMsgFolder::GetDeleteIsMoveToTrash(PRBool *deleteIsMoveToTrash)
|
|
{
|
|
if(deleteIsMoveToTrash)
|
|
{
|
|
*deleteIsMoveToTrash = mDeleteIsMoveToTrash;
|
|
return NS_OK;
|
|
}
|
|
return
|
|
NS_ERROR_NULL_POINTER;
|
|
}
|
|
|
|
NS_IMETHODIMP nsMsgFolder::GetShowDeletedMessages(PRBool *showDeletedMessages)
|
|
{
|
|
if(showDeletedMessages)
|
|
{
|
|
*showDeletedMessages = PR_FALSE;
|
|
return NS_OK;
|
|
}
|
|
return
|
|
NS_ERROR_NULL_POINTER;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP nsMsgFolder::ForceDBClosed ()
|
|
{
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsMsgFolder::Delete ()
|
|
{
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsMsgFolder::DeleteSubFolders(nsISupportsArray *folders,
|
|
nsIMsgWindow *msgWindow)
|
|
{
|
|
nsresult rv;
|
|
|
|
PRUint32 count;
|
|
rv = folders->Count(&count);
|
|
nsCOMPtr<nsIMsgFolder> folder;
|
|
for(PRUint32 i = 0; i < count; i++)
|
|
{
|
|
nsCOMPtr<nsISupports> supports = getter_AddRefs(folders->ElementAt(i));
|
|
folder = do_QueryInterface(supports);
|
|
if(folder)
|
|
PropagateDelete(folder, PR_TRUE);
|
|
}
|
|
return rv;
|
|
|
|
}
|
|
|
|
NS_IMETHODIMP nsMsgFolder::CreateStorageIfMissing(nsIUrlListener* /* urlListener */)
|
|
{
|
|
NS_ASSERTION(PR_FALSE, "needs to be overridden");
|
|
nsresult status = NS_OK;
|
|
|
|
return status;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP nsMsgFolder::PropagateDelete(nsIMsgFolder *folder, PRBool deleteStorage)
|
|
{
|
|
nsresult status = NS_OK;
|
|
|
|
nsCOMPtr<nsIMsgFolder> child;
|
|
|
|
// first, find the folder we're looking to delete
|
|
PRUint32 cnt;
|
|
nsresult rv = mSubFolders->Count(&cnt);
|
|
if (NS_FAILED(rv)) return rv;
|
|
for (PRUint32 i = 0; i < cnt; i++)
|
|
{
|
|
nsCOMPtr<nsISupports> supports = getter_AddRefs(mSubFolders->ElementAt(i));
|
|
child = do_QueryInterface(supports, &status);
|
|
if(NS_SUCCEEDED(status))
|
|
{
|
|
if (folder == child.get())
|
|
{
|
|
//Remove self as parent
|
|
child->SetParent(nsnull);
|
|
// maybe delete disk storage for it, and its subfolders
|
|
status = child->RecursiveDelete(deleteStorage);
|
|
|
|
if (status == NS_OK)
|
|
{
|
|
|
|
//Remove from list of subfolders.
|
|
mSubFolders->RemoveElement(supports);
|
|
nsCOMPtr<nsISupports> childSupports(do_QueryInterface(child));
|
|
nsCOMPtr<nsISupports> folderSupports;
|
|
rv = QueryInterface(NS_GET_IID(nsISupports), getter_AddRefs(folderSupports));
|
|
if(childSupports && NS_SUCCEEDED(rv))
|
|
NotifyItemDeleted(folderSupports, childSupports, "folderView");
|
|
break;
|
|
}
|
|
else
|
|
{ // setting parent back if we failed
|
|
child->SetParent(this);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
status = child->PropagateDelete (folder, deleteStorage);
|
|
}
|
|
}
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
NS_IMETHODIMP nsMsgFolder::RecursiveDelete(PRBool deleteStorage)
|
|
{
|
|
// If deleteStorage is PR_TRUE, recursively deletes disk storage for this folder
|
|
// and all its subfolders.
|
|
// Regardless of deleteStorage, always unlinks them from the children lists and
|
|
// frees memory for the subfolders but NOT for _this_
|
|
|
|
nsresult status = NS_OK;
|
|
|
|
PRUint32 cnt;
|
|
nsresult rv = mSubFolders->Count(&cnt);
|
|
if (NS_FAILED(rv)) return rv;
|
|
while (cnt > 0)
|
|
{
|
|
nsCOMPtr<nsISupports> supports = getter_AddRefs(mSubFolders->ElementAt(0));
|
|
nsCOMPtr<nsIMsgFolder> child(do_QueryInterface(supports, &status));
|
|
|
|
if(NS_SUCCEEDED(status))
|
|
{
|
|
child->SetParent(nsnull);
|
|
status = child->RecursiveDelete(deleteStorage); // recur
|
|
if (NS_SUCCEEDED(status))
|
|
{
|
|
mSubFolders->RemoveElement(supports); // unlink it from this's child list
|
|
nsCOMPtr<nsISupports> childSupports(do_QueryInterface(child));
|
|
nsCOMPtr<nsISupports> folderSupports;
|
|
rv = QueryInterface(NS_GET_IID(nsISupports), getter_AddRefs(folderSupports));
|
|
if(childSupports && NS_SUCCEEDED(rv))
|
|
NotifyItemDeleted(folderSupports, childSupports, "folderView");
|
|
}
|
|
else
|
|
{ // setting parent back if we failed for some reason
|
|
child->SetParent(this);
|
|
}
|
|
}
|
|
cnt--;
|
|
}
|
|
|
|
// now delete the disk storage for _this_
|
|
if (deleteStorage && (status == NS_OK))
|
|
status = Delete();
|
|
|
|
return status;
|
|
}
|
|
|
|
NS_IMETHODIMP nsMsgFolder::CreateSubfolder(const PRUnichar *folderName, nsIMsgWindow *msgWindow )
|
|
{
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
nsresult nsMsgFolder::AddSubfolder(nsAutoString *folderName,
|
|
nsIMsgFolder** newFolder)
|
|
{
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
NS_IMETHODIMP nsMsgFolder::Compact(nsIUrlListener *aListener)
|
|
{
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
NS_IMETHODIMP nsMsgFolder::CompactAll(nsIUrlListener *aListener)
|
|
{
|
|
NS_ASSERTION(PR_FALSE, "should be overridden by child class");
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
NS_IMETHODIMP nsMsgFolder::EmptyTrash(nsIMsgWindow *msgWindow, nsIUrlListener *aListener)
|
|
{
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
NS_IMETHODIMP nsMsgFolder::Rename(const PRUnichar *name, nsIMsgWindow *msgWindow)
|
|
{
|
|
nsresult status = NS_OK;
|
|
nsAutoString unicharString(name);
|
|
status = SetName((PRUnichar *) unicharString.GetUnicode());
|
|
//After doing a SetName we need to make sure that broadcasting this message causes a
|
|
//new sort to happen.
|
|
#ifdef HAVE_MASTER
|
|
if (m_master)
|
|
m_master->BroadcastFolderChanged(this);
|
|
#endif
|
|
return status;
|
|
|
|
}
|
|
|
|
NS_IMETHODIMP nsMsgFolder::Adopt(nsIMsgFolder *srcFolder, PRUint32* outPos)
|
|
{
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
NS_IMETHODIMP nsMsgFolder::ContainsChildNamed(const char *name, PRBool* containsChild)
|
|
{
|
|
nsCOMPtr<nsISupports> child;
|
|
|
|
if(containsChild)
|
|
{
|
|
*containsChild = PR_FALSE;
|
|
if(NS_SUCCEEDED(GetChildNamed(name, getter_AddRefs(child))))
|
|
{
|
|
*containsChild = child != nsnull;
|
|
}
|
|
return NS_OK;
|
|
}
|
|
else
|
|
return NS_ERROR_NULL_POINTER;
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP nsMsgFolder::IsAncestorOf(nsIMsgFolder *child, PRBool *isAncestor)
|
|
{
|
|
if(!isAncestor)
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
nsresult rv = NS_OK;
|
|
|
|
PRUint32 count;
|
|
rv = mSubFolders->Count(&count);
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
for (PRUint32 i = 0; i < count; i++)
|
|
{
|
|
nsCOMPtr<nsISupports> supports = getter_AddRefs(mSubFolders->ElementAt(i));
|
|
nsCOMPtr<nsIMsgFolder> folder(do_QueryInterface(supports, &rv));
|
|
if(NS_SUCCEEDED(rv))
|
|
{
|
|
if (folder.get() == child )
|
|
{
|
|
*isAncestor = PR_TRUE;
|
|
}
|
|
else
|
|
folder->IsAncestorOf(child, isAncestor);
|
|
|
|
}
|
|
if(*isAncestor)
|
|
return NS_OK;
|
|
}
|
|
*isAncestor = PR_FALSE;
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP nsMsgFolder::GenerateUniqueSubfolderName(const char *prefix, nsIMsgFolder *otherFolder,
|
|
char **name)
|
|
{
|
|
if(!name)
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
/* only try 256 times */
|
|
for (int count = 0; (count < 256); count++)
|
|
{
|
|
PRUint32 prefixSize = PL_strlen(prefix);
|
|
|
|
//allocate string big enough for prefix, 256, and '\0'
|
|
char *uniqueName = (char*)PR_MALLOC(prefixSize + 4);
|
|
if(!uniqueName)
|
|
return NS_ERROR_OUT_OF_MEMORY;
|
|
PR_snprintf(uniqueName, prefixSize + 4, "%s%d",prefix,count);
|
|
PRBool containsChild;
|
|
PRBool otherContainsChild = PR_FALSE;
|
|
|
|
ContainsChildNamed(uniqueName, &containsChild);
|
|
if(otherFolder)
|
|
{
|
|
((nsIMsgFolder*)otherFolder)->ContainsChildNamed(uniqueName, &otherContainsChild);
|
|
}
|
|
|
|
if (!containsChild && !otherContainsChild)
|
|
{
|
|
*name = uniqueName;
|
|
return NS_OK;
|
|
}
|
|
else
|
|
PR_FREEIF(uniqueName);
|
|
}
|
|
*name = nsnull;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsMsgFolder::UpdateSummaryTotals(PRBool /* force */)
|
|
{
|
|
//We don't support this
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsMsgFolder::SummaryChanged()
|
|
{
|
|
UpdateSummaryTotals(PR_FALSE);
|
|
#ifdef HAVE_MASTER
|
|
if (mMaster)
|
|
mMaster->BroadcastFolderChanged(this);
|
|
#endif
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsMsgFolder::GetNumUnread(PRBool deep, PRInt32 *numUnread)
|
|
{
|
|
if(!numUnread)
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
nsresult rv;
|
|
PRUint32 total = mNumUnreadMessages + mNumPendingUnreadMessages;
|
|
if (deep)
|
|
{
|
|
nsCOMPtr<nsIMsgFolder> folder;
|
|
PRUint32 count;
|
|
rv = mSubFolders->Count(&count);
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
for (PRUint32 i = 0; i < count; i++)
|
|
{
|
|
nsCOMPtr<nsISupports> supports = getter_AddRefs(mSubFolders->ElementAt(i));
|
|
folder = do_QueryInterface(supports, &rv);
|
|
if(NS_SUCCEEDED(rv))
|
|
{
|
|
PRInt32 num;
|
|
folder->GetNumUnread(deep, &num);
|
|
if (num >= 0) // it's legal for counts to be negative if we don't know
|
|
total += num;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
*numUnread = total;
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
NS_IMETHODIMP nsMsgFolder::GetTotalMessages(PRBool deep, PRInt32 *totalMessages)
|
|
{
|
|
if(!totalMessages)
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
nsresult rv;
|
|
PRInt32 total = mNumTotalMessages + mNumPendingTotalMessages;
|
|
if (deep)
|
|
{
|
|
nsCOMPtr<nsIMsgFolder> folder;
|
|
PRUint32 count;
|
|
rv = mSubFolders->Count(&count);
|
|
if (NS_SUCCEEDED(rv)) {
|
|
|
|
for (PRUint32 i = 0; i < count; i++)
|
|
{
|
|
nsCOMPtr<nsISupports> supports = getter_AddRefs(mSubFolders->ElementAt(i));
|
|
folder = do_QueryInterface(supports, &rv);
|
|
if(NS_SUCCEEDED(rv))
|
|
{
|
|
PRInt32 num;
|
|
folder->GetTotalMessages (deep, &num);
|
|
if (num >= 0) // it's legal for counts to be negative if we don't know
|
|
total += num;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
*totalMessages = total;
|
|
return NS_OK;
|
|
}
|
|
|
|
PRInt32 nsMsgFolder::GetNumPendingUnread()
|
|
{
|
|
return mNumPendingUnreadMessages;
|
|
}
|
|
|
|
PRInt32 nsMsgFolder::GetNumPendingTotalMessages()
|
|
{
|
|
return mNumPendingTotalMessages;
|
|
}
|
|
|
|
NS_IMETHODIMP nsMsgFolder::GetHasNewMessages(PRBool *hasNewMessages)
|
|
{
|
|
//we don't support this
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsMsgFolder::SetHasNewMessages(PRBool hasNewMessages)
|
|
{
|
|
//we don't support this
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsMsgFolder::GetFirstNewMessage(nsIMessage **firstNewMessage)
|
|
{
|
|
//we don't support this
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsMsgFolder::ClearNewMessages()
|
|
{
|
|
//we don't support this
|
|
return NS_OK;
|
|
}
|
|
|
|
void nsMsgFolder::ChangeNumPendingUnread(PRInt32 delta)
|
|
{
|
|
if(delta)
|
|
{
|
|
PRInt32 oldUnreadMessages = mNumUnreadMessages + mNumPendingUnreadMessages;
|
|
mNumPendingUnreadMessages += delta;
|
|
PRInt32 newUnreadMessages = mNumUnreadMessages + mNumPendingUnreadMessages;
|
|
nsCOMPtr<nsIMsgDatabase> db;
|
|
nsCOMPtr<nsIDBFolderInfo> folderInfo;
|
|
nsresult rv = GetDBFolderInfoAndDB(getter_AddRefs(folderInfo), getter_AddRefs(db));
|
|
if (NS_SUCCEEDED(rv) && folderInfo)
|
|
folderInfo->SetImapUnreadPendingMessages(mNumPendingUnreadMessages);
|
|
|
|
NotifyIntPropertyChanged(kTotalUnreadMessagesAtom, oldUnreadMessages, newUnreadMessages);
|
|
}
|
|
}
|
|
|
|
void nsMsgFolder::ChangeNumPendingTotalMessages(PRInt32 delta)
|
|
{
|
|
if(delta)
|
|
{
|
|
PRInt32 oldTotalMessages = mNumTotalMessages + mNumPendingTotalMessages;
|
|
mNumPendingTotalMessages += delta;
|
|
PRInt32 newTotalMessages = mNumTotalMessages + mNumPendingTotalMessages;
|
|
|
|
nsCOMPtr<nsIMsgDatabase> db;
|
|
nsCOMPtr<nsIDBFolderInfo> folderInfo;
|
|
nsresult rv = GetDBFolderInfoAndDB(getter_AddRefs(folderInfo), getter_AddRefs(db));
|
|
if (NS_SUCCEEDED(rv) && folderInfo)
|
|
folderInfo->SetImapTotalPendingMessages(mNumPendingTotalMessages);
|
|
NotifyIntPropertyChanged(kTotalMessagesAtom, oldTotalMessages, newTotalMessages);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP nsMsgFolder::SetPrefFlag()
|
|
{
|
|
// *** Note: this method should only be called when we done with the folder
|
|
// discovery. GetResource() may return a node which is not in the folder
|
|
// tree hierarchy but in the rdf cache in case of the non-existing default
|
|
// Sent, Drafts, and Templates folders. The resouce will be eventually
|
|
// released when rdf service shutting downs. When we create the defaul
|
|
// folders later on on the imap server, the subsequent GetResouce() of the
|
|
// same uri will get us the cached rdf resouce which should have the folder
|
|
// flag set appropriately.
|
|
nsresult rv = NS_OK;
|
|
NS_WITH_SERVICE(nsIMsgAccountManager, accountManager,
|
|
NS_MSGACCOUNTMANAGER_CONTRACTID, &rv);
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
NS_WITH_SERVICE(nsIRDFService, rdf, kRDFServiceCID, &rv);
|
|
|
|
if(NS_FAILED(rv)) return rv;
|
|
|
|
nsCOMPtr<nsIMsgIncomingServer> server;
|
|
rv = GetServer(getter_AddRefs(server));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
nsCOMPtr<nsISupportsArray> identities;
|
|
rv = accountManager->GetIdentitiesForServer(server,
|
|
getter_AddRefs(identities));
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
nsCOMPtr<nsIMsgIdentity> identity;
|
|
|
|
rv = identities->QueryElementAt(0, NS_GET_IID(nsIMsgIdentity),
|
|
(void **)getter_AddRefs(identity));
|
|
|
|
if (NS_SUCCEEDED(rv) && identity)
|
|
{
|
|
nsXPIDLCString folderUri;
|
|
nsCOMPtr<nsIRDFResource> res;
|
|
nsCOMPtr<nsIMsgFolder> folder;
|
|
identity->GetFccFolder(getter_Copies(folderUri));
|
|
if (folderUri && NS_SUCCEEDED(rdf->GetResource(folderUri, getter_AddRefs(res))))
|
|
{
|
|
folder = do_QueryInterface(res, &rv);
|
|
if (NS_SUCCEEDED(rv))
|
|
rv = folder->SetFlag(MSG_FOLDER_FLAG_SENTMAIL);
|
|
}
|
|
identity->GetDraftFolder(getter_Copies(folderUri));
|
|
if (folderUri && NS_SUCCEEDED(rdf->GetResource(folderUri, getter_AddRefs(res))))
|
|
{
|
|
folder = do_QueryInterface(res, &rv);
|
|
if (NS_SUCCEEDED(rv))
|
|
rv = folder->SetFlag(MSG_FOLDER_FLAG_DRAFTS);
|
|
}
|
|
identity->GetStationeryFolder(getter_Copies(folderUri));
|
|
if (folderUri && NS_SUCCEEDED(rdf->GetResource(folderUri, getter_AddRefs(res))))
|
|
{
|
|
folder = do_QueryInterface(res, &rv);
|
|
if (NS_SUCCEEDED(rv))
|
|
rv = folder->SetFlag(MSG_FOLDER_FLAG_TEMPLATES);
|
|
}
|
|
}
|
|
return rv;
|
|
}
|
|
|
|
NS_IMETHODIMP nsMsgFolder::SetFlag(PRUint32 flag)
|
|
{
|
|
// OnFlagChange can be expensive, so don't call it if we don't need to
|
|
PRBool flagSet;
|
|
nsresult rv;
|
|
|
|
if(!NS_SUCCEEDED(rv = GetFlag(flag, &flagSet)))
|
|
return rv;
|
|
|
|
if (!flagSet)
|
|
{
|
|
mFlags |= flag;
|
|
OnFlagChange(flag);
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsMsgFolder::ClearFlag(PRUint32 flag)
|
|
{
|
|
// OnFlagChange can be expensive, so don't call it if we don't need to
|
|
PRBool flagSet;
|
|
nsresult rv;
|
|
|
|
if(!NS_SUCCEEDED(rv = GetFlag(flag, &flagSet)))
|
|
return rv;
|
|
|
|
if (flagSet)
|
|
{
|
|
mFlags &= ~flag;
|
|
OnFlagChange (flag);
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsMsgFolder::GetFlag(PRUint32 flag, PRBool *_retval)
|
|
{
|
|
*_retval = ((mFlags & flag) != 0);
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsMsgFolder::ToggleFlag(PRUint32 flag)
|
|
{
|
|
mFlags ^= flag;
|
|
OnFlagChange (flag);
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsMsgFolder::OnFlagChange(PRUint32 flag)
|
|
{
|
|
nsresult rv = NS_OK;
|
|
nsCOMPtr<nsIMsgDatabase> db;
|
|
nsCOMPtr<nsIDBFolderInfo> folderInfo;
|
|
rv = GetDBFolderInfoAndDB(getter_AddRefs(folderInfo), getter_AddRefs(db));
|
|
if (NS_SUCCEEDED(rv) && folderInfo)
|
|
{
|
|
#ifdef DEBUG_bienvenu
|
|
nsXPIDLString name;
|
|
rv = GetName(getter_Copies(name));
|
|
NS_ASSERTION(nsCRT::strcmp(name, "Trash") || (mFlags & MSG_FOLDER_FLAG_TRASH), "lost trash flag");
|
|
#endif
|
|
folderInfo->SetFlags((PRInt32) mFlags);
|
|
if (db)
|
|
db->Commit(nsMsgDBCommitType::kLargeCommit);
|
|
}
|
|
folderInfo = null_nsCOMPtr();
|
|
return rv;
|
|
}
|
|
|
|
NS_IMETHODIMP nsMsgFolder::SetFlags(PRUint32 aFlags)
|
|
{
|
|
if (mFlags != aFlags)
|
|
{
|
|
mFlags = aFlags;
|
|
OnFlagChange(mFlags);
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsMsgFolder::GetFoldersWithFlag(PRUint32 flags, PRUint32 resultsize, PRUint32 *numFolders, nsIMsgFolder **result)
|
|
{
|
|
PRUint32 num = 0;
|
|
if ((flags & mFlags) == flags) {
|
|
if (result && (num < resultsize)) {
|
|
result[num] = this;
|
|
NS_IF_ADDREF(result[num]);
|
|
}
|
|
num++;
|
|
}
|
|
|
|
nsresult rv;
|
|
nsCOMPtr<nsIMsgFolder> folder;
|
|
PRUint32 cnt;
|
|
rv = mSubFolders->Count(&cnt);
|
|
if (NS_SUCCEEDED(rv)) {
|
|
for (PRUint32 i=0; i < cnt; i++)
|
|
{
|
|
nsCOMPtr<nsISupports> supports = getter_AddRefs(mSubFolders->ElementAt(i));
|
|
folder = do_QueryInterface(supports, &rv);
|
|
if(NS_SUCCEEDED(rv) && folder)
|
|
{
|
|
// CAREFUL! if NULL is passed in for result then the caller
|
|
// still wants the full count! Otherwise, the result should be at most the
|
|
// number that the caller asked for.
|
|
PRUint32 numSubFolders;
|
|
|
|
if (!result)
|
|
{
|
|
folder->GetFoldersWithFlag(flags, 0, &numSubFolders, NULL);
|
|
num += numSubFolders;
|
|
}
|
|
else if (num < resultsize)
|
|
{
|
|
folder->GetFoldersWithFlag(flags, resultsize - num, &numSubFolders, result+num);
|
|
num += numSubFolders;
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
*numFolders = num;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsMsgFolder::GetExpansionArray(nsISupportsArray *expansionArray)
|
|
{
|
|
// the application of flags in GetExpansionArray is subtly different
|
|
// than in GetFoldersWithFlag
|
|
|
|
nsresult rv;
|
|
PRUint32 cnt;
|
|
rv = mSubFolders->Count(&cnt);
|
|
if (NS_FAILED(rv)) return rv;
|
|
for (PRUint32 i = 0; i < cnt; i++)
|
|
{
|
|
nsCOMPtr<nsISupports> supports = getter_AddRefs(mSubFolders->ElementAt(i));
|
|
nsCOMPtr<nsIMsgFolder> folder = do_QueryInterface(supports, &rv);
|
|
if(NS_SUCCEEDED(rv))
|
|
{
|
|
PRUint32 cnt2;
|
|
rv = expansionArray->Count(&cnt2);
|
|
if (NS_SUCCEEDED(rv)) {
|
|
expansionArray->InsertElementAt(folder, cnt2);
|
|
PRUint32 flags;
|
|
folder->GetFlags(&flags);
|
|
if (!(flags & MSG_FOLDER_FLAG_ELIDED))
|
|
folder->GetExpansionArray(expansionArray);
|
|
}
|
|
}
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
#ifdef HAVE_PANE
|
|
NS_IMETHODIMP nsMsgFolder::SetFlagInAllFolderPanes(PRUInt32 which)
|
|
{
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
#ifdef HAVE_NET
|
|
NS_IMETHODIMP nsMsgFolder::EscapeMessageId(const char *messageId, const char **escapeMessageID)
|
|
{
|
|
|
|
}
|
|
#endif
|
|
|
|
NS_IMETHODIMP nsMsgFolder::GetExpungedBytes(PRUint32 *count)
|
|
{
|
|
if(!count)
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
*count = 0;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsMsgFolder::GetDeletable(PRBool *deletable)
|
|
{
|
|
|
|
if(!deletable)
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
*deletable = PR_FALSE;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsMsgFolder::GetRequiresCleanup(PRBool *requiredCleanup)
|
|
{
|
|
if(!requiredCleanup)
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
*requiredCleanup = PR_FALSE;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsMsgFolder::ClearRequiresCleanup()
|
|
{
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsMsgFolder::ManyHeadersToDownload(PRBool *_retval)
|
|
{
|
|
if (!_retval)
|
|
return NS_ERROR_NULL_POINTER;
|
|
*_retval = PR_FALSE;
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP nsMsgFolder::GetKnowsSearchNntpExtension(PRBool *knowsExtension)
|
|
{
|
|
if(!knowsExtension)
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
*knowsExtension = PR_FALSE;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsMsgFolder::GetAllowsPosting(PRBool *allowsPosting)
|
|
{
|
|
if(!allowsPosting)
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
*allowsPosting = PR_TRUE;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsMsgFolder::GetDisplayRecipients(PRBool *displayRecipients)
|
|
{
|
|
nsresult rv;
|
|
|
|
*displayRecipients = PR_FALSE;
|
|
|
|
if (mFlags & MSG_FOLDER_FLAG_SENTMAIL && !(mFlags & MSG_FOLDER_FLAG_INBOX))
|
|
*displayRecipients = PR_TRUE;
|
|
else if (mFlags & MSG_FOLDER_FLAG_QUEUE)
|
|
*displayRecipients = PR_TRUE;
|
|
else
|
|
{
|
|
// Only mail folders can be FCC folders
|
|
if (mFlags & MSG_FOLDER_FLAG_MAIL || mFlags & MSG_FOLDER_FLAG_IMAPBOX)
|
|
{
|
|
// There's one FCC folder for sent mail, and one for sent news
|
|
nsIMsgFolder *fccFolders[2];
|
|
int numFccFolders = 0;
|
|
#ifdef HAVE_MASTER
|
|
m_master->GetFolderTree()->GetFoldersWithFlag (MSG_FOLDER_FLAG_SENTMAIL, fccFolders, 2, &numFccFolders);
|
|
#endif
|
|
for (int i = 0; i < numFccFolders; i++)
|
|
{
|
|
PRBool isAncestor;
|
|
if(NS_SUCCEEDED(rv = fccFolders[i]->IsAncestorOf(this, &isAncestor)))
|
|
{
|
|
if (isAncestor)
|
|
*displayRecipients = PR_TRUE;
|
|
}
|
|
NS_RELEASE(fccFolders[i]);
|
|
}
|
|
}
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP nsMsgFolder::AcquireSemaphore(nsISupports *semHolder)
|
|
{
|
|
nsresult rv = NS_OK;
|
|
|
|
if (mSemaphoreHolder == NULL)
|
|
{
|
|
mSemaphoreHolder = semHolder; //Don't AddRef due to ownership issues.
|
|
}
|
|
else
|
|
rv = NS_MSG_FOLDER_BUSY;
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
NS_IMETHODIMP nsMsgFolder::ReleaseSemaphore(nsISupports *semHolder)
|
|
{
|
|
if (!mSemaphoreHolder || mSemaphoreHolder == semHolder)
|
|
{
|
|
mSemaphoreHolder = NULL;
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsMsgFolder::TestSemaphore(nsISupports *semHolder, PRBool *result)
|
|
{
|
|
if(!result)
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
*result = (mSemaphoreHolder == semHolder);
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsMsgFolder::GetLocked(PRBool *isLocked)
|
|
{
|
|
*isLocked = mSemaphoreHolder != NULL;
|
|
return NS_OK;
|
|
}
|
|
|
|
#ifdef HAVE_PANE
|
|
MWContext *GetFolderPaneContext();
|
|
#endif
|
|
|
|
#ifdef HAVE_MASTER
|
|
MSG_Master *GetMaster() {return m_master;}
|
|
#endif
|
|
|
|
NS_IMETHODIMP nsMsgFolder::GetRelativePathName(char **pathName)
|
|
{
|
|
if(!pathName)
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
*pathName = nsnull;
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP nsMsgFolder::GetSizeOnDisk(PRUint32 *size)
|
|
{
|
|
if(!size)
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
*size = 0;
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
#ifdef HAVE_NET
|
|
NS_IMETHODIMP nsMsgFolder::ShouldPerformOperationOffline(PRBool *performOffline)
|
|
{
|
|
|
|
}
|
|
#endif
|
|
|
|
|
|
#ifdef DOES_FOLDEROPERATIONS
|
|
NS_IMETHODIMP nsMsgFolder::DownloadToTempFileAndUpload(MessageCopyInfo *copyInfo,
|
|
nsMsgKeyArray &keysToSave,
|
|
MSG_FolderInfo *dstFolder,
|
|
nsMsgDatabase *sourceDB)
|
|
{
|
|
|
|
}
|
|
|
|
NS_IMETHODIMP nsMsgFolder::UpdateMoveCopyStatus(MWContext *context, PRBool isMove, int32 curMsgCount, int32 totMessages)
|
|
{
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
NS_IMETHODIMP nsMsgFolder::RememberPassword(const char *password)
|
|
{
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsMsgFolder::GetRememberedPassword(char ** password)
|
|
{
|
|
|
|
if(!password)
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
*password = nsnull;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsMsgFolder::UserNeedsToAuthenticateForFolder(PRBool displayOnly, PRBool *needsAuthenticate)
|
|
{
|
|
if(!needsAuthenticate)
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
*needsAuthenticate = PR_FALSE;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsMsgFolder::GetUsername(char **userName)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(userName);
|
|
nsresult rv;
|
|
nsCOMPtr <nsIMsgIncomingServer> server;
|
|
|
|
rv = GetServer(getter_AddRefs(server));
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
if (server)
|
|
return server->GetUsername(userName);
|
|
|
|
return NS_ERROR_UNEXPECTED;
|
|
}
|
|
|
|
NS_IMETHODIMP nsMsgFolder::GetHostname(char **hostName)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(hostName);
|
|
|
|
nsresult rv;
|
|
|
|
nsCOMPtr<nsIMsgIncomingServer> server;
|
|
rv = GetServer(getter_AddRefs(server));
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
if (server)
|
|
return server->GetHostName(hostName);
|
|
|
|
return NS_ERROR_UNEXPECTED;
|
|
}
|
|
|
|
NS_IMETHODIMP nsMsgFolder::GetNewMessages(nsIMsgWindow *)
|
|
{
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
NS_IMETHODIMP nsMsgFolder::GetBiffState(PRUint32 *aBiffState)
|
|
{
|
|
if(!aBiffState)
|
|
return NS_ERROR_NULL_POINTER;
|
|
*aBiffState = mBiffState;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsMsgFolder::SetBiffState(PRUint32 aBiffState)
|
|
{
|
|
nsresult rv;
|
|
|
|
// this optimization isn't working with filters...
|
|
// so commenting out the optimization
|
|
// need to figure out why and fix it !!!
|
|
|
|
//if(mBiffState != aBiffState)
|
|
//{
|
|
PRUint32 oldBiffState = mBiffState;
|
|
mBiffState = aBiffState;
|
|
nsCOMPtr<nsISupports> supports;
|
|
|
|
// Get the server and notify it and not inbox.
|
|
nsCOMPtr<nsIMsgIncomingServer> aServer;
|
|
nsCOMPtr<nsIFolder> aRootFolder;
|
|
|
|
rv = GetServer(getter_AddRefs(aServer));
|
|
rv = aServer->GetRootFolder(getter_AddRefs(aRootFolder));
|
|
if(NS_FAILED(rv))
|
|
return rv;
|
|
|
|
if(NS_SUCCEEDED(aRootFolder->QueryInterface(NS_GET_IID(nsISupports), getter_AddRefs(supports))))
|
|
(aRootFolder)->NotifyPropertyFlagChanged(supports, kBiffStateAtom, oldBiffState, mBiffState);
|
|
//}
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsMsgFolder::GetNumNewMessages(PRInt32 *aNumNewMessages)
|
|
{
|
|
if(!aNumNewMessages)
|
|
return NS_ERROR_NULL_POINTER;
|
|
|
|
*aNumNewMessages = mNumNewBiffMessages;
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsMsgFolder::SetNumNewMessages(PRInt32 aNumNewMessages)
|
|
{
|
|
if(aNumNewMessages != mNumNewBiffMessages)
|
|
{
|
|
PRInt32 oldNumMessages = mNumNewBiffMessages;
|
|
mNumNewBiffMessages = aNumNewMessages;
|
|
|
|
nsCAutoString oldNumMessagesStr;
|
|
oldNumMessagesStr.AppendInt(oldNumMessages);
|
|
nsCAutoString newNumMessagesStr;
|
|
newNumMessagesStr.AppendInt(aNumNewMessages);
|
|
NotifyPropertyChanged(kNumNewBiffMessagesAtom, oldNumMessagesStr, newNumMessagesStr);
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsMsgFolder::GetNewMessagesNotificationDescription(PRUnichar * *aDescription)
|
|
{
|
|
nsresult rv;
|
|
nsAutoString description;
|
|
nsCOMPtr<nsIMsgIncomingServer> server;
|
|
rv = GetServer(getter_AddRefs(server));
|
|
|
|
if(NS_SUCCEEDED(rv))
|
|
{
|
|
if (!(mFlags & MSG_FOLDER_FLAG_INBOX))
|
|
{
|
|
nsXPIDLString folderName;
|
|
rv = GetPrettyName(getter_Copies(folderName));
|
|
if (NS_SUCCEEDED(rv) && folderName)
|
|
description.Assign(folderName);
|
|
}
|
|
|
|
// append the server name
|
|
nsXPIDLString serverName;
|
|
rv = server->GetPrettyName(getter_Copies(serverName));
|
|
if(NS_SUCCEEDED(rv)) {
|
|
// put this test here because we don't want to just put "folder name on"
|
|
// in case the above failed
|
|
if (!(mFlags & MSG_FOLDER_FLAG_INBOX))
|
|
description.AppendWithConversion(" on ");
|
|
description.Append(serverName);
|
|
}
|
|
}
|
|
*aDescription = description.ToNewUnicode();
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP nsMsgFolder::GetRootFolder(nsIMsgFolder * *aRootFolder)
|
|
{
|
|
if (!aRootFolder) return NS_ERROR_NULL_POINTER;
|
|
|
|
nsresult rv;
|
|
nsCOMPtr<nsIMsgIncomingServer> server;
|
|
rv = GetServer(getter_AddRefs(server));
|
|
if (NS_FAILED(rv)) return rv;
|
|
NS_ASSERTION(server, "server is null");
|
|
// if this happens, bail.
|
|
if (!server) return NS_ERROR_NULL_POINTER;
|
|
|
|
nsCOMPtr<nsIFolder> aRoot;
|
|
rv = server->GetRootFolder(getter_AddRefs(aRoot));
|
|
|
|
if (NS_FAILED(rv)) return rv;
|
|
if (!aRoot) return NS_ERROR_NULL_POINTER;
|
|
|
|
return aRoot->QueryInterface(NS_GET_IID(nsIMsgFolder), (void**)aRootFolder);
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsMsgFolder::GetMsgDatabase(nsIMsgWindow *aMsgWindow,
|
|
nsIMsgDatabase** aMsgDatabase)
|
|
{
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsMsgFolder::GetPath(nsIFileSpec * *aPath)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(aPath);
|
|
nsresult rv=NS_OK;
|
|
|
|
if (!mPath)
|
|
rv = parseURI(PR_TRUE);
|
|
|
|
*aPath = mPath;
|
|
NS_IF_ADDREF(*aPath);
|
|
|
|
return rv;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsMsgFolder::SetPath(nsIFileSpec *aPath)
|
|
{
|
|
// XXX - make a local copy!
|
|
mPath = aPath;
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsMsgFolder::MarkMessagesRead(nsISupportsArray *messages, PRBool markRead)
|
|
{
|
|
PRUint32 count;
|
|
nsresult rv;
|
|
|
|
rv = messages->Count(&count);
|
|
if(NS_FAILED(rv))
|
|
return rv;
|
|
|
|
for(PRUint32 i = 0; i < count; i++)
|
|
{
|
|
nsCOMPtr<nsISupports> msgSupports = getter_AddRefs(messages->ElementAt(i));
|
|
nsCOMPtr<nsIMessage> message = do_QueryInterface(msgSupports);
|
|
|
|
if(message)
|
|
rv = message->MarkRead(markRead);
|
|
|
|
if(NS_FAILED(rv))
|
|
return rv;
|
|
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsMsgFolder::MarkMessagesFlagged(nsISupportsArray *messages, PRBool markFlagged)
|
|
{
|
|
PRUint32 count;
|
|
nsresult rv;
|
|
|
|
rv = messages->Count(&count);
|
|
if(NS_FAILED(rv))
|
|
return rv;
|
|
|
|
for(PRUint32 i = 0; i < count; i++)
|
|
{
|
|
nsCOMPtr<nsISupports> msgSupports = getter_AddRefs(messages->ElementAt(i));
|
|
nsCOMPtr<nsIMessage> message = do_QueryInterface(msgSupports);
|
|
|
|
if(message)
|
|
rv = message->MarkFlagged(markFlagged);
|
|
|
|
if(NS_FAILED(rv))
|
|
return rv;
|
|
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsMsgFolder::AddMessageDispositionState(nsIMessage *aMessage, nsMsgDispositionState aDispositionFlag)
|
|
{
|
|
// most folders don't do anything for this...
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsMsgFolder::MarkAllMessagesRead(void)
|
|
{
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsMsgFolder::MarkThreadRead(nsIMsgThread *thread)
|
|
{
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsMsgFolder::CopyMessages(nsIMsgFolder* srcFolder,
|
|
nsISupportsArray *messages,
|
|
PRBool isMove,
|
|
nsIMsgWindow *window,
|
|
nsIMsgCopyServiceListener* listener,
|
|
PRBool isFolder)
|
|
{
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsMsgFolder::CopyFolder(nsIMsgFolder* srcFolder,
|
|
PRBool isMoveFolder,
|
|
nsIMsgWindow *window,
|
|
nsIMsgCopyServiceListener* listener)
|
|
{
|
|
NS_ASSERTION(PR_FALSE, "should be overridden by child class");
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsMsgFolder::CopyFileMessage(nsIFileSpec* fileSpec,
|
|
nsIMessage* messageToReplace,
|
|
PRBool isDraftOrTemplate,
|
|
nsIMsgWindow *window,
|
|
nsIMsgCopyServiceListener* listener)
|
|
{
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
NS_IMETHODIMP nsMsgFolder::MatchName(nsString *name, PRBool *matches)
|
|
{
|
|
if (!matches)
|
|
return NS_ERROR_NULL_POINTER;
|
|
*matches = mName.EqualsIgnoreCase(*name);
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsMsgFolder::SetDeleteIsMoveToTrash(PRBool bVal)
|
|
{
|
|
mDeleteIsMoveToTrash = bVal;
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult
|
|
nsMsgFolder::NotifyPropertyChanged(nsIAtom *property,
|
|
const char *oldValue, const char* newValue)
|
|
{
|
|
nsCOMPtr<nsISupports> supports;
|
|
if(NS_SUCCEEDED(QueryInterface(NS_GET_IID(nsISupports), getter_AddRefs(supports))))
|
|
{
|
|
PRInt32 i;
|
|
for(i = 0; i < mListeners->Count(); i++)
|
|
{
|
|
//Folderlistener's aren't refcounted.
|
|
nsIFolderListener* listener =(nsIFolderListener*)mListeners->ElementAt(i);
|
|
listener->OnItemPropertyChanged(supports, property, oldValue, newValue);
|
|
}
|
|
|
|
//Notify listeners who listen to every folder
|
|
nsresult rv;
|
|
NS_WITH_SERVICE(nsIFolderListener, folderListenerManager, kMsgFolderListenerManagerCID, &rv);
|
|
if(NS_SUCCEEDED(rv))
|
|
folderListenerManager->OnItemPropertyChanged(supports, property, oldValue, newValue);
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
nsresult
|
|
nsMsgFolder::NotifyUnicharPropertyChanged(nsIAtom *property,
|
|
const PRUnichar* oldValue,
|
|
const PRUnichar *newValue)
|
|
{
|
|
nsresult rv;
|
|
nsCOMPtr<nsISupports> supports;
|
|
rv = QueryInterface(NS_GET_IID(nsISupports),
|
|
(void **)getter_AddRefs(supports));
|
|
if (NS_FAILED(rv)) return rv;
|
|
|
|
PRInt32 i;
|
|
for (i=0; i<mListeners->Count(); i++) {
|
|
// folderlisteners arent refcounted in the array
|
|
nsIFolderListener* listener=(nsIFolderListener*)mListeners->ElementAt(i);
|
|
listener->OnItemUnicharPropertyChanged(supports, property, oldValue, newValue);
|
|
}
|
|
|
|
// Notify listeners who listen to every folder
|
|
NS_WITH_SERVICE(nsIFolderListener, folderListenerManager, kMsgFolderListenerManagerCID, &rv);
|
|
if (NS_SUCCEEDED(rv))
|
|
rv = folderListenerManager->OnItemUnicharPropertyChanged(supports,
|
|
property,
|
|
oldValue,
|
|
newValue);
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult nsMsgFolder::NotifyIntPropertyChanged(nsIAtom *property, PRInt32 oldValue, PRInt32 newValue)
|
|
{
|
|
//Don't send off count notifications if they are turned off.
|
|
if(!mNotifyCountChanges && ((property == kTotalMessagesAtom) ||( property == kTotalUnreadMessagesAtom)))
|
|
return NS_OK;
|
|
|
|
nsCOMPtr<nsISupports> supports;
|
|
if(NS_SUCCEEDED(QueryInterface(NS_GET_IID(nsISupports), getter_AddRefs(supports))))
|
|
{
|
|
PRInt32 i;
|
|
for(i = 0; i < mListeners->Count(); i++)
|
|
{
|
|
//Folderlistener's aren't refcounted.
|
|
nsIFolderListener* listener =(nsIFolderListener*)mListeners->ElementAt(i);
|
|
listener->OnItemIntPropertyChanged(supports, property, oldValue, newValue);
|
|
}
|
|
|
|
//Notify listeners who listen to every folder
|
|
nsresult rv;
|
|
NS_WITH_SERVICE(nsIFolderListener, folderListenerManager, kMsgFolderListenerManagerCID, &rv);
|
|
if(NS_SUCCEEDED(rv))
|
|
folderListenerManager->OnItemIntPropertyChanged(supports, property, oldValue, newValue);
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
nsresult
|
|
nsMsgFolder::NotifyBoolPropertyChanged(nsIAtom* property,
|
|
PRBool oldValue, PRBool newValue)
|
|
{
|
|
nsCOMPtr<nsISupports> supports;
|
|
if(NS_SUCCEEDED(QueryInterface(NS_GET_IID(nsISupports), getter_AddRefs(supports))))
|
|
{
|
|
PRInt32 i;
|
|
for(i = 0; i < mListeners->Count(); i++)
|
|
{
|
|
//Folderlistener's aren't refcounted.
|
|
nsIFolderListener* listener =(nsIFolderListener*)mListeners->ElementAt(i);
|
|
listener->OnItemBoolPropertyChanged(supports, property, oldValue, newValue);
|
|
}
|
|
|
|
//Notify listeners who listen to every folder
|
|
nsresult rv;
|
|
NS_WITH_SERVICE(nsIFolderListener, folderListenerManager, kMsgFolderListenerManagerCID, &rv);
|
|
if(NS_SUCCEEDED(rv))
|
|
folderListenerManager->OnItemBoolPropertyChanged(supports, property, oldValue, newValue);
|
|
|
|
}
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
nsresult
|
|
nsMsgFolder::NotifyPropertyFlagChanged(nsISupports *item, nsIAtom *property,
|
|
PRUint32 oldValue, PRUint32 newValue)
|
|
{
|
|
PRInt32 i;
|
|
for(i = 0; i < mListeners->Count(); i++)
|
|
{
|
|
//Folderlistener's aren't refcounted.
|
|
nsIFolderListener *listener = (nsIFolderListener*)mListeners->ElementAt(i);
|
|
listener->OnItemPropertyFlagChanged(item, property, oldValue, newValue);
|
|
}
|
|
|
|
//Notify listeners who listen to every folder
|
|
nsresult rv;
|
|
NS_WITH_SERVICE(nsIFolderListener, folderListenerManager, kMsgFolderListenerManagerCID, &rv);
|
|
if(NS_SUCCEEDED(rv))
|
|
folderListenerManager->OnItemPropertyFlagChanged(item, property, oldValue, newValue);
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult nsMsgFolder::NotifyItemAdded(nsISupports *parentItem, nsISupports *item, const char* viewString)
|
|
{
|
|
static PRBool notify = PR_TRUE;
|
|
|
|
if (!notify)
|
|
return NS_OK;
|
|
|
|
PRInt32 i;
|
|
for(i = 0; i < mListeners->Count(); i++)
|
|
{
|
|
//Folderlistener's aren't refcounted.
|
|
nsIFolderListener *listener = (nsIFolderListener*)mListeners->ElementAt(i);
|
|
listener->OnItemAdded(parentItem, item, viewString);
|
|
}
|
|
|
|
//Notify listeners who listen to every folder
|
|
nsresult rv;
|
|
NS_WITH_SERVICE(nsIFolderListener, folderListenerManager, kMsgFolderListenerManagerCID, &rv);
|
|
if(NS_SUCCEEDED(rv))
|
|
folderListenerManager->OnItemAdded(parentItem, item, viewString);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
nsresult nsMsgFolder::NotifyItemDeleted(nsISupports *parentItem, nsISupports *item, const char* viewString)
|
|
{
|
|
|
|
PRInt32 i;
|
|
for(i = 0; i < mListeners->Count(); i++)
|
|
{
|
|
//Folderlistener's aren't refcounted.
|
|
nsIFolderListener *listener = (nsIFolderListener*)mListeners->ElementAt(i);
|
|
listener->OnItemRemoved(parentItem, item, viewString);
|
|
}
|
|
//Notify listeners who listen to every folder
|
|
nsresult rv;
|
|
NS_WITH_SERVICE(nsIFolderListener, folderListenerManager, kMsgFolderListenerManagerCID, &rv);
|
|
if(NS_SUCCEEDED(rv))
|
|
folderListenerManager->OnItemRemoved(parentItem, item, viewString);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
nsresult nsMsgFolder::NotifyFolderEvent(nsIAtom* aEvent)
|
|
{
|
|
PRInt32 i;
|
|
for(i = 0; i < mListeners->Count(); i++)
|
|
{
|
|
//Folderlistener's aren't refcounted.
|
|
nsIFolderListener *listener = (nsIFolderListener*)mListeners->ElementAt(i);
|
|
listener->OnItemEvent(this, aEvent);
|
|
}
|
|
//Notify listeners who listen to every folder
|
|
nsresult rv;
|
|
NS_WITH_SERVICE(nsIFolderListener, folderListenerManager, kMsgFolderListenerManagerCID, &rv);
|
|
if(NS_SUCCEEDED(rv))
|
|
folderListenerManager->OnItemEvent(this, aEvent);
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult
|
|
nsGetMailFolderSeparator(nsString& result)
|
|
{
|
|
result.AssignWithConversion(".sbd");
|
|
return NS_OK;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsMsgFolder::RecursiveSetDeleteIsMoveToTrash(PRBool bVal)
|
|
{
|
|
nsresult rv = NS_OK;
|
|
if (mSubFolders)
|
|
{
|
|
PRUint32 cnt = 0, i;
|
|
rv = mSubFolders->Count(&cnt);
|
|
for (i=0; i < cnt; i++)
|
|
{
|
|
nsCOMPtr<nsISupports> aSupport;
|
|
rv = GetElementAt(i, getter_AddRefs(aSupport));
|
|
if (NS_SUCCEEDED(rv))
|
|
{
|
|
nsCOMPtr<nsIMsgFolder> folder;
|
|
folder = do_QueryInterface(aSupport);
|
|
if (folder)
|
|
folder->RecursiveSetDeleteIsMoveToTrash(bVal);
|
|
}
|
|
}
|
|
}
|
|
return SetDeleteIsMoveToTrash(bVal);
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsMsgFolder::GetFilterList(nsIMsgFilterList **aResult)
|
|
{
|
|
nsresult rv;
|
|
|
|
// only get filters for root folders in the base class
|
|
#ifdef NS_DEBUG
|
|
PRBool isServer=PR_FALSE;
|
|
rv = GetIsServer(&isServer);
|
|
NS_ASSERTION(NS_SUCCEEDED(rv), "error getting serverness");
|
|
NS_ASSERTION(isServer, "Getting filter for non-server?");
|
|
#endif
|
|
|
|
nsCOMPtr<nsIMsgIncomingServer> server;
|
|
rv = GetServer(getter_AddRefs(server));
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
NS_ENSURE_TRUE(server, NS_ERROR_FAILURE);
|
|
|
|
return server->GetFilterList(aResult);
|
|
}
|
|
|
|
/* void enableNotifications (in long notificationType, in boolean enable); */
|
|
NS_IMETHODIMP nsMsgFolder::EnableNotifications(PRInt32 notificationType, PRBool enable)
|
|
{
|
|
if(notificationType == nsIMsgFolder::allMessageCountNotifications)
|
|
{
|
|
mNotifyCountChanges = enable;
|
|
// start and stop db batching here. This is under the theory
|
|
// that any time we want to enable and disable notifications,
|
|
// we're probably doing something that should be batched.
|
|
nsCOMPtr <nsIMsgDatabase> database;
|
|
|
|
|
|
nsresult rv = GetMsgDatabase(nsnull, getter_AddRefs(database));
|
|
if(enable)
|
|
{
|
|
if (database)
|
|
database->EndBatch();
|
|
UpdateSummaryTotals(PR_TRUE);
|
|
}
|
|
else if (database)
|
|
database->StartBatch();
|
|
|
|
return NS_OK;
|
|
}
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP nsMsgFolder::GetMessageHeader(nsMsgKey msgKey, nsIMsgDBHdr **aMsgHdr)
|
|
{
|
|
nsresult rv = NS_OK;
|
|
if (aMsgHdr)
|
|
{
|
|
nsCOMPtr <nsIMsgDatabase> database;
|
|
|
|
rv = GetMsgDatabase(nsnull, getter_AddRefs(database));
|
|
if (NS_SUCCEEDED(rv) && database) // did we get a db back?
|
|
rv = database->GetMsgHdrForKey(msgKey, aMsgHdr);
|
|
}
|
|
else
|
|
rv = NS_ERROR_NULL_POINTER;
|
|
|
|
return rv;
|
|
}
|
|
|
|
// this gets the deep sub-folders too, e.g., the children of the children
|
|
NS_IMETHODIMP nsMsgFolder::ListDescendents(nsISupportsArray *descendents)
|
|
{
|
|
NS_ENSURE_ARG(descendents);
|
|
PRUint32 cnt;
|
|
nsresult rv = mSubFolders->Count(&cnt);
|
|
NS_ENSURE_SUCCESS(rv,rv);
|
|
for (PRUint32 index = 0; index < cnt; index++)
|
|
{
|
|
nsresult rv;
|
|
nsCOMPtr<nsISupports> supports = getter_AddRefs(mSubFolders->ElementAt(index));
|
|
nsCOMPtr<nsIMsgFolder> child(do_QueryInterface(supports, &rv));
|
|
|
|
if (NS_SUCCEEDED(rv))
|
|
{
|
|
rv = descendents->AppendElement(supports);
|
|
if(NS_SUCCEEDED(rv))
|
|
{
|
|
rv = child->ListDescendents(descendents); // recurse
|
|
}
|
|
}
|
|
}
|
|
return rv;
|
|
}
|
|
|
|
NS_IMETHODIMP nsMsgFolder::GetBaseMessageURI(char **baseMessageURI)
|
|
{
|
|
NS_ENSURE_ARG_POINTER(baseMessageURI);
|
|
|
|
if (mBaseMessageURI)
|
|
{
|
|
*baseMessageURI = nsCRT::strdup(mBaseMessageURI);
|
|
return NS_OK;
|
|
}
|
|
else
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|