pjs/mailnews/base/util/nsMsgFolder.cpp

1805 строки
41 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):
*/
#include "msgCore.h" // precompiled header...
#include "nsMsgFolder.h"
#include "nsMsgFolderFlags.h"
#include "nsIMessage.h"
#include "prprf.h"
#include "nsMsgKeyArray.h"
#include "nsMsgDatabase.h"
#include "nsIDBFolderInfo.h"
#include "nsISupportsArray.h"
#include "nsIPref.h"
1999-04-07 06:50:25 +04:00
#include "nsIRDFService.h"
#include "nsIServiceManager.h"
#include "nsRDFCID.h"
#include "nsXPIDLString.h"
1999-05-05 02:34:35 +04:00
#include "nsCOMPtr.h"
1999-05-14 04:45:25 +04:00
#include "nsIMsgMailSession.h"
#include "nsMsgBaseCID.h"
#include "nsIAllocator.h"
#include "nsIURL.h"
static NS_DEFINE_CID(kStandardUrlCID, NS_STANDARDURL_CID);
static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
static NS_DEFINE_CID(kMsgMailSessionCID, NS_MSGMAILSESSION_CID);
nsMsgFolder::nsMsgFolder(void)
: nsRDFResource(),
mFlags(0),
mParent(nsnull),
1999-05-27 03:47:01 +04:00
mNumUnreadMessages(-1),
mNumTotalMessages(-1),
1999-06-12 02:10:42 +04:00
mPrefFlags(0),
1999-08-21 02:41:38 +04:00
mBiffState(nsMsgBiffState_NoMail),
mNumNewBiffMessages(0),
mIsServer(PR_FALSE)
{
// NS_INIT_REFCNT(); done by superclass
mSemaphoreHolder = NULL;
#ifdef HAVE_DB
mLastMessageLoaded = nsMsgKey_None;
#endif
mNumPendingUnreadMessages = 0;
mNumPendingTotalMessages = 0;
1999-05-05 02:34:35 +04:00
NS_NewISupportsArray(getter_AddRefs(mSubFolders));
mIsCachable = PR_TRUE;
1999-05-14 04:45:25 +04:00
mListeners = new nsVoidArray();
m_server = nsnull;
}
nsMsgFolder::~nsMsgFolder(void)
{
if(mSubFolders)
{
PRUint32 count;
nsresult rv = mSubFolders->Count(&count);
NS_ASSERTION(NS_SUCCEEDED(rv), "Count failed");
for (int i = count - 1; i >= 0; i--)
mSubFolders->RemoveElementAt(i);
}
delete mListeners;
}
1999-05-08 00:21:47 +04:00
NS_IMPL_ADDREF_INHERITED(nsMsgFolder, nsRDFResource)
NS_IMPL_RELEASE_INHERITED(nsMsgFolder, nsRDFResource)
NS_IMETHODIMP nsMsgFolder::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
if (!aInstancePtr) return NS_ERROR_NULL_POINTER;
*aInstancePtr = nsnull;
1999-08-21 02:41:38 +04:00
if (aIID.Equals(nsCOMTypeInfo<nsIMsgFolder>::GetIID()) ||
aIID.Equals(nsCOMTypeInfo<nsIFolder>::GetIID()))
1999-05-08 00:21:47 +04:00
{
*aInstancePtr = NS_STATIC_CAST(nsIMsgFolder*, this);
}
if(*aInstancePtr)
{
AddRef();
return NS_OK;
}
return nsRDFResource::QueryInterface(aIID, aInstancePtr);
}
1999-08-21 02:41:38 +04:00
NS_IMETHODIMP
nsMsgFolder::Init(const char* aURI)
{
// for now, just initialize everything during Init()
1999-08-21 02:41:38 +04:00
nsresult rv;
1999-08-21 02:41:38 +04:00
rv = nsRDFResource::Init(aURI);
1999-08-21 02:41:38 +04:00
nsCOMPtr<nsIURL> url;
rv = nsComponentManager::CreateInstance(kStandardUrlCID, nsnull,
NS_GET_IID(nsIURL),
(void **)getter_AddRefs(url));
if (NS_FAILED(rv)) return rv;
rv = url->SetSpec(aURI);
if (NS_FAILED(rv)) return rv;
//
// pull some info out of the URI
//
// empty path tells us it's a server.
nsXPIDLCString path;
rv = url->GetPath(getter_Copies(path));
if (NS_SUCCEEDED(rv)) {
if (!nsCRT::strcmp(path, "/"))
mIsServer = PR_TRUE;
else
mIsServer = PR_FALSE;
}
1999-08-21 02:41:38 +04:00
// mName:
// the name is the trailing directory in the path
nsXPIDLCString fileName;
rv = url->GetFileName(getter_Copies(fileName));
if (NS_SUCCEEDED(rv)) {
// XXX conversion to unicode here? is fileName in UTF8?
mName = fileName;
}
// Get username and hostname so we can get the server
nsXPIDLCString userName;
rv = url->GetPreHost(getter_Copies(userName));
1999-11-03 22:47:17 +03:00
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)
1999-11-03 22:47:17 +03:00
nsUnescape(NS_CONST_CAST(char*,(const char*)hostName));
// turn it back into a server:
NS_WITH_SERVICE(nsIMsgAccountManager, accountManager,
NS_MSGACCOUNTMANAGER_PROGID, &rv);
if (NS_FAILED(rv)) return rv;
nsIMsgIncomingServer *server;
rv = accountManager->FindServer(userName,
hostName,
GetIncomingServerType(),
&server);
// there is a reason we aren't returning rv if NS_FAILED(rv)
// if you feel the need to uncomment the line below, ask alecf@netscape.com
// if NS_FAILED(rv)) return rv;
// keep weak ref to server
m_server = server;
NS_IF_RELEASE(server);
NS_ASSERTION(m_server, "Failed to get server..");
return NS_OK;
1999-08-21 02:41:38 +04:00
}
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)
{
1999-05-05 02:34:35 +04:00
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
1999-06-16 03:18:57 +04:00
nsMsgFolder::FindSubFolder(const char *subFolderName, nsIFolder **aFolder)
{
1999-06-16 03:18:57 +04:00
nsresult rv = NS_OK;
NS_WITH_SERVICE(nsIRDFService, rdf, kRDFServiceCID, &rv);
if(NS_FAILED(rv))
return rv;
// XXX use necko here
nsCAutoString uri;
1999-06-16 03:18:57 +04:00
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;
}
1999-05-12 07:24:36 +04:00
NS_IMETHODIMP
nsMsgFolder::GetHasSubFolders(PRBool *_retval)
{
PRUint32 cnt;
nsresult rv = mSubFolders->Count(&cnt);
if (NS_FAILED(rv)) return rv;
*_retval = (cnt > 0);
1999-05-12 07:24:36 +04:00
return NS_OK;
}
NS_IMETHODIMP nsMsgFolder::AddFolderListener(nsIFolderListener * listener)
{
1999-05-14 04:45:25 +04:00
mListeners->AppendElement(listener);
return NS_OK;
}
NS_IMETHODIMP nsMsgFolder::RemoveFolderListener(nsIFolderListener * listener)
{
1999-05-14 04:45:25 +04:00
mListeners->RemoveElement(listener);
return NS_OK;
}
1999-05-08 00:21:47 +04:00
NS_IMETHODIMP nsMsgFolder::SetParent(nsIFolder *parent)
{
//Don't addref due to ownership issues.
mParent = parent;
return NS_OK;
}
NS_IMETHODIMP nsMsgFolder::GetParent(nsIFolder **parent)
{
if(!parent)
return NS_ERROR_NULL_POINTER;
*parent = mParent;
NS_IF_ADDREF(*parent);
return NS_OK;
}
NS_IMETHODIMP
nsMsgFolder::GetMessages(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;
}
1999-04-07 04:03:26 +04:00
NS_IMETHODIMP
nsMsgFolder::GetThreads(nsISimpleEnumerator ** threadEnumerator)
1999-04-07 04:03:26 +04:00
{
// XXX should this return an empty enumeration?
return NS_ERROR_FAILURE;
}
1999-04-07 06:50:25 +04:00
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;
}
#ifdef HAVE_DB
// this class doesn't have a url
NS_IMETHODIMP nsMsgFolder::BuildUrl(nsMsgDatabase *db, nsMsgKey key, char ** url)
{
if(*url)
{
*url = NULL;
return NS_OK;
}
else
return NS_ERROR_NULL_POINTER;
}
#endif
NS_IMETHODIMP nsMsgFolder::GetServer(nsIMsgIncomingServer ** aServer)
{
NS_ENSURE_ARG_POINTER(aServer);
*aServer = m_server;
NS_IF_ADDREF(*aServer);
return NS_OK;
}
1999-08-21 02:41:38 +04:00
NS_IMETHODIMP
nsMsgFolder::GetIsServer(PRBool *aResult)
{
NS_ENSURE_ARG_POINTER(aResult);
*aResult = mIsServer;
return NS_OK;
}
1999-06-29 01:56:33 +04:00
NS_IMETHODIMP nsMsgFolder::GetPrettyName(PRUnichar ** name)
{
1999-06-29 01:56:33 +04:00
if (!name)
1999-07-07 02:41:19 +04:00
return NS_ERROR_NULL_POINTER;
1999-06-29 01:56:33 +04:00
*name = mName.ToNewUnicode();
return (*name) ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
}
NS_IMETHODIMP nsMsgFolder::SetPrettyName(const PRUnichar *name)
{
mName = name;
return NS_OK;
}
1999-06-29 01:56:33 +04:00
NS_IMETHODIMP nsMsgFolder::GetName(PRUnichar **name)
{
1999-06-29 01:56:33 +04:00
if (!name)
return NS_ERROR_NULL_POINTER;
*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
mName = 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;
for (PRUint32 i = 0; i < count; i++)
{
nsCOMPtr<nsISupports> supports = getter_AddRefs(mSubFolders->ElementAt(i));
folder = do_QueryInterface(supports, &rv);
if(NS_SUCCEEDED(rv))
{
1999-06-29 01:56:33 +04:00
PRUnichar *folderName;
folder->GetName(&folderName);
// case-insensitive compare is probably LCD across OS filesystems
if (folderName && nsCRT::strcasecmp(folderName, name)==0)
{
*aChild = folder;
NS_ADDREF(*aChild);
delete[] folderName;
return NS_OK;
}
1999-07-27 09:15:44 +04:00
delete[] folderName;
}
1999-07-27 09:15:44 +04:00
}
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;
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<nsIRDFResource> folderResource = do_QueryInterface(supports);
nsCOMPtr<nsIMsgFolder> folder = do_QueryInterface(supports);
if(folderResource && folder)
{
char *folderURI;
rv = folderResource->GetValue(&folderURI);
if(NS_FAILED(rv)) return rv;
// case-insensitive compare is probably LCD across OS filesystems
PRBool equal = (folderURI && nsCRT::strcasecmp(folderURI, uri)==0);
nsAllocator::Free(folderURI);
if (equal)
{
*child = folder;
1999-07-27 22:18:52 +04:00
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;
}
}
}
return NS_OK;
}
1999-06-29 01:56:33 +04:00
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;
1999-05-05 02:34:35 +04:00
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 = PR_FALSE;
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::OnCloseFolder ()
{
return NS_OK;
}
NS_IMETHODIMP nsMsgFolder::Delete ()
{
return NS_OK;
}
1999-05-27 03:47:01 +04:00
NS_IMETHODIMP nsMsgFolder::DeleteSubFolders(nsISupportsArray *folders)
{
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::PropagateDelete(nsIMsgFolder *folder, PRBool deleteStorage)
{
nsresult status = NS_OK;
1999-05-05 02:34:35 +04:00
nsCOMPtr<nsIMsgFolder> child;
// first, find the folder we're looking to delete
PRUint32 cnt;
1999-05-27 03:47:01 +04:00
nsresult rv = mSubFolders->Count(&cnt);
if (NS_FAILED(rv)) return rv;
for (PRUint32 i = 0; i < cnt; i++)
{
1999-05-05 02:34:35 +04:00
nsCOMPtr<nsISupports> supports = getter_AddRefs(mSubFolders->ElementAt(i));
child = do_QueryInterface(supports, &status);
if(NS_SUCCEEDED(status))
1999-05-27 03:47:01 +04:00
{
if (folder == child.get())
{
1999-05-27 03:47:01 +04:00
// maybe delete disk storage for it, and its subfolders
status = child->RecursiveDelete(deleteStorage);
1999-05-27 03:47:01 +04:00
if (status == NS_OK)
{
1999-05-27 03:47:01 +04:00
//Remove from list of subfolders.
1999-08-21 02:47:55 +04:00
mSubFolders->RemoveElement(supports);
1999-05-27 03:47:01 +04:00
//Remove self as parent
child->SetParent(nsnull);
nsCOMPtr<nsISupports> childSupports(do_QueryInterface(child));
nsCOMPtr<nsISupports> folderSupports;
rv = QueryInterface(nsCOMTypeInfo<nsISupports>::GetIID(), getter_AddRefs(folderSupports));
if(childSupports && NS_SUCCEEDED(rv))
NotifyItemDeleted(folderSupports, childSupports, "folderView");
1999-05-27 03:47:01 +04:00
break;
}
}
1999-05-27 03:47:01 +04:00
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)
{
1999-05-05 02:34:35 +04:00
nsCOMPtr<nsISupports> supports = getter_AddRefs(mSubFolders->ElementAt(0));
nsCOMPtr<nsIMsgFolder> child(do_QueryInterface(supports, &status));
1999-05-05 02:34:35 +04:00
if(NS_SUCCEEDED(status))
{
status = child->RecursiveDelete(deleteStorage); // recur
mSubFolders->RemoveElement(child); // unlink it from this's child list
1999-05-27 03:47:01 +04:00
child->SetParent(nsnull);
nsCOMPtr<nsISupports> childSupports(do_QueryInterface(child));
nsCOMPtr<nsISupports> folderSupports;
rv = QueryInterface(nsCOMTypeInfo<nsISupports>::GetIID(), getter_AddRefs(folderSupports));
if(childSupports && NS_SUCCEEDED(rv))
NotifyItemDeleted(folderSupports, childSupports, "folderView");
}
1999-05-27 03:47:01 +04:00
cnt--;
}
// now delete the disk storage for _this_
if (deleteStorage && (status == NS_OK))
status = Delete();
return status;
}
1999-04-16 01:12:10 +04:00
NS_IMETHODIMP nsMsgFolder::CreateSubfolder(const char *folderName)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
nsresult nsMsgFolder::AddSubfolder(nsAutoString *folderName,
nsIMsgFolder** newFolder)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsMsgFolder::Compact()
{
1999-08-06 22:24:39 +04:00
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsMsgFolder::EmptyTrash()
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsMsgFolder::Rename(const char *name)
{
nsresult status = NS_OK;
1999-06-29 01:56:33 +04:00
nsAutoString2 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;
}
1999-05-05 02:34:35 +04:00
NS_IMETHODIMP nsMsgFolder::Adopt(nsIMsgFolder *srcFolder, PRUint32* outPos)
{
return NS_OK;
}
NS_IMETHODIMP nsMsgFolder::ContainsChildNamed(const char *name, PRBool* containsChild)
{
1999-05-05 02:34:35 +04:00
nsCOMPtr<nsISupports> child;
if(containsChild)
{
*containsChild = PR_FALSE;
1999-05-05 02:34:35 +04:00
if(NS_SUCCEEDED(GetChildNamed(name, getter_AddRefs(child))))
{
*containsChild = child != nsnull;
}
return NS_OK;
}
else
return NS_ERROR_NULL_POINTER;
}
1999-05-08 00:21:47 +04:00
NS_IMETHODIMP nsMsgFolder::IsAncestorOf(nsIMsgFolder *child, PRBool *isAncestor)
{
1999-05-08 00:21:47 +04:00
if(!isAncestor)
return NS_ERROR_NULL_POINTER;
1999-05-05 02:34:35 +04:00
nsresult rv = NS_OK;
PRUint32 count;
rv = mSubFolders->Count(&count);
if (NS_FAILED(rv)) return rv;
1999-05-05 02:34:35 +04:00
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))
{
1999-05-05 02:34:35 +04:00
if (folder.get() == child )
{
1999-05-08 00:21:47 +04:00
*isAncestor = PR_TRUE;
}
1999-05-08 00:21:47 +04:00
else
folder->IsAncestorOf(child, isAncestor);
}
1999-05-08 00:21:47 +04:00
if(*isAncestor)
return NS_OK;
}
1999-05-08 00:21:47 +04:00
*isAncestor = PR_FALSE;
1999-05-05 02:34:35 +04:00
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);
1999-05-05 02:34:35 +04:00
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;
}
1999-07-18 00:33:15 +04:00
NS_IMETHODIMP nsMsgFolder::UpdateSummaryTotals(PRBool /* force */)
{
//We don't support this
return NS_OK;
}
NS_IMETHODIMP nsMsgFolder::SummaryChanged()
{
1999-07-18 00:33:15 +04:00
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;
1999-05-05 02:34:35 +04:00
nsresult rv;
PRUint32 total = mNumUnreadMessages + mNumPendingUnreadMessages;
1999-05-05 02:34:35 +04:00
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;
1999-05-05 02:34:35 +04:00
nsresult rv;
PRInt32 total = mNumTotalMessages + mNumPendingTotalMessages;
1999-05-05 02:34:35 +04:00
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;
}
#ifdef HAVE_DB
NS_IMETHOD GetTotalMessagesInDB(PRUint32 *totalMessages) const; // How many messages in database.
#endif
PRInt32 nsMsgFolder::GetNumPendingUnread()
{
return mNumPendingUnreadMessages;
}
PRInt32 nsMsgFolder::GetNumPendingTotalMessages()
{
return mNumPendingTotalMessages;
}
void nsMsgFolder::ChangeNumPendingUnread(PRInt32 delta)
{
if (delta)
{
char *oldUnreadMessagesStr = PR_smprintf("%d", mNumUnreadMessages + mNumPendingUnreadMessages);
mNumPendingUnreadMessages += delta;
char *unreadMessagesStr = PR_smprintf("%d",mNumUnreadMessages + mNumPendingUnreadMessages);
NotifyPropertyChanged("TotalUnreadMessages", oldUnreadMessagesStr, unreadMessagesStr);
PR_smprintf_free(unreadMessagesStr);
PR_smprintf_free(oldUnreadMessagesStr);
}
}
void nsMsgFolder::ChangeNumPendingTotalMessages(PRInt32 delta)
{
if (delta)
{
char *oldTotalMessagesStr = PR_smprintf("%d", mNumTotalMessages + mNumPendingTotalMessages);
mNumPendingTotalMessages += delta;
char *totalMessagesStr = PR_smprintf("%d",mNumTotalMessages + mNumPendingTotalMessages);
NotifyPropertyChanged("TotalMessages", oldTotalMessagesStr, totalMessagesStr);
PR_smprintf_free(totalMessagesStr);
PR_smprintf_free(oldTotalMessagesStr);
}
}
#ifdef HAVE_DB
// These functions are used for tricking the front end into thinking that we have more
// messages than are really in the DB. This is usually after and IMAP message copy where
// we don't want to do an expensive select until the user actually opens that folder
// These functions are called when MSG_Master::GetFolderLineById is populating a MSG_FolderLine
// struct used by the FE
NS_IMETHODIMP nsMsgFolder::SetFolderPrefFlags(PRUint32 flags)
{
}
NS_IMETHODIMP nsMsgFolder::GetFolderPrefFlags(PRUint32 *flags)
{
}
NS_IMETHODIMP nsMsgFolder::SetLastMessageLoaded(nsMsgKey lastMessageLoaded)
{
}
NS_IMETHODIMP nsMsgFolder::GetLastMessageLoaded()
{
}
#endif
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)
{
//Still need to implement
return NS_OK;
}
NS_IMETHODIMP nsMsgFolder::GetFlags(PRUint32 *_retval)
{
*_retval = mFlags;
return NS_OK;
}
NS_IMETHODIMP nsMsgFolder::GetFoldersWithFlag(PRUint32 flags, nsIMsgFolder **result,
1999-05-05 02:34:35 +04:00
PRUint32 resultsize, PRUint32 *numFolders)
{
PRUint32 num = 0;
if ((flags & mFlags) == flags) {
if (result && (num < resultsize)) {
result[num] = this;
NS_IF_ADDREF(result[num]);
}
num++;
1999-05-05 02:34:35 +04:00
}
1999-05-05 02:34:35 +04:00
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, NULL, 0, &numSubFolders);
num += numSubFolders;
}
else if (num < resultsize)
{
folder->GetFoldersWithFlag(flags, result + num, resultsize - num, &numSubFolders);
num += numSubFolders;
}
else
{
break;
}
}
}
}
1999-05-05 02:34:35 +04:00
*numFolders = num;
return NS_OK;
}
NS_IMETHODIMP nsMsgFolder::GetExpansionArray(nsISupportsArray *expansionArray)
{
// the application of flags in GetExpansionArray is subtly different
// than in GetFoldersWithFlag
1999-05-05 02:34:35 +04:00
nsresult rv;
PRUint32 cnt;
rv = mSubFolders->Count(&cnt);
if (NS_FAILED(rv)) return rv;
for (PRUint32 i = 0; i < cnt; i++)
{
1999-05-05 02:34:35 +04:00
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::GetExpungedBytesCount(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::GetCanCreateChildren(PRBool *canCreateChildren)
{
if(!canCreateChildren)
return NS_ERROR_NULL_POINTER;
*canCreateChildren = PR_FALSE;
return NS_OK;
}
NS_IMETHODIMP nsMsgFolder::GetCanBeRenamed(PRBool *canBeRenamed)
{
if(!canBeRenamed)
return NS_ERROR_NULL_POINTER;
*canBeRenamed = 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++)
{
1999-05-08 00:21:47 +04:00
PRBool isAncestor;
if(NS_SUCCEEDED(rv = fccFolders[i]->IsAncestorOf(this, &isAncestor)))
{
1999-05-08 00:21:47 +04:00
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)
{
1999-05-05 02:34:35 +04:00
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
#ifdef HAVE_CACHE
NS_IMETHODIMP nsMsgFolder::WriteToCache(XP_File)
{
}
NS_IMETHODIMP nsMsgFolder::ReadFromCache(char *)
{
}
NS_IMETHODIMP nsMsgFolder::IsCachable(PRBool *isCachable)
{
}
NS_IMETHODIMP nsMsgFolder::SkipCacheTokens(char **ppBuf, int numTokens)
{
}
#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);
NS_ASSERTION(m_server, "No server when getting username");
if (!m_server) return NS_ERROR_UNEXPECTED;
m_server->GetUsername(userName);
return NS_OK;
}
NS_IMETHODIMP nsMsgFolder::GetHostname(char **hostName)
{
NS_ENSURE_ARG_POINTER(hostName);
NS_ASSERTION(m_server, "No server when getting hostname");
if (!m_server) return NS_ERROR_UNEXPECTED;
m_server->GetHostName(hostName);
return NS_OK;
}
NS_IMETHODIMP nsMsgFolder::GetNewMessages(nsIMsgWindow *)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
1999-06-12 02:10:42 +04:00
NS_IMETHODIMP nsMsgFolder::GetBiffState(PRUint32 *aBiffState)
{
if(!aBiffState)
return NS_ERROR_NULL_POINTER;
*aBiffState = mBiffState;
return NS_OK;
}
NS_IMETHODIMP nsMsgFolder::SetBiffState(PRUint32 aBiffState)
{
if(mBiffState != aBiffState)
{
PRUint32 oldBiffState = mBiffState;
mBiffState = aBiffState;
nsCOMPtr<nsISupports> supports;
1999-07-01 04:16:39 +04:00
if(NS_SUCCEEDED(QueryInterface(nsCOMTypeInfo<nsISupports>::GetIID(), getter_AddRefs(supports))))
1999-06-12 02:10:42 +04:00
NotifyPropertyFlagChanged(supports, "BiffState", 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;
char *oldNumMessagesStr = PR_smprintf("%d", oldNumMessages);
char *newNumMessagesStr = PR_smprintf("%d",aNumNewMessages);
NotifyPropertyChanged("NumNewBiffMessages", oldNumMessagesStr, newNumMessagesStr);
PR_smprintf_free(oldNumMessagesStr);
PR_smprintf_free(newNumMessagesStr);
}
return NS_OK;
}
NS_IMETHODIMP nsMsgFolder::GetNewMessagesNotificationDescription(PRUnichar * *aDescription)
{
nsresult rv;
nsString description("");
nsCOMPtr<nsIMsgIncomingServer> server;
rv = GetServer(getter_AddRefs(server));
1999-06-12 02:10:42 +04:00
if(NS_SUCCEEDED(rv))
{
1999-08-03 01:33:00 +04:00
if (!(mFlags & MSG_FOLDER_FLAG_INBOX))
{
nsXPIDLString folderName;
rv = GetPrettyName(getter_Copies(folderName));
1999-08-03 01:33:00 +04:00
if (NS_SUCCEEDED(rv) && folderName)
description = folderName;
}
1999-06-12 02:10:42 +04:00
// 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 += " on ";
description += serverName;
}
1999-06-12 02:10:42 +04:00
}
*aDescription = description.ToNewUnicode();
return NS_OK;
}
1999-06-15 02:22:51 +04:00
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;
nsCOMPtr<nsIFolder> aRoot;
rv = server->GetRootFolder(getter_AddRefs(aRoot));
if(NS_FAILED(rv) || !aRoot)
return rv;
1999-07-01 04:16:39 +04:00
return aRoot->QueryInterface(nsCOMTypeInfo<nsIMsgFolder>::GetIID(), (void**)aRootFolder);
1999-06-15 02:22:51 +04:00
}
NS_IMETHODIMP
nsMsgFolder::GetMsgDatabase(nsIMsgDatabase** aMsgDatabase)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
1999-06-25 07:56:02 +04:00
NS_IMETHODIMP
nsMsgFolder::GetPath(nsIFileSpec * *aPath)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
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;
}
1999-08-25 01:47:22 +04:00
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::MarkAllMessagesRead(void)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsMsgFolder::CopyMessages(nsIMsgFolder* srcFolder,
nsISupportsArray *messages,
PRBool isMove,
nsIMsgWindow *window,
nsIMsgCopyServiceListener* listener)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsMsgFolder::CopyFileMessage(nsIFileSpec* fileSpec,
nsIMessage* messageToReplace,
PRBool isDraftOrTemplate,
nsIMsgWindow *window,
nsIMsgCopyServiceListener* listener)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
1999-07-27 09:15:44 +04:00
NS_IMETHODIMP nsMsgFolder::MatchName(nsString *name, PRBool *matches)
{
if (!matches)
return NS_ERROR_NULL_POINTER;
*matches = mName.EqualsIgnoreCase(*name);
return NS_OK;
}
nsresult nsMsgFolder::NotifyPropertyChanged(char *property, char *oldValue, char* newValue)
{
1999-05-05 02:34:35 +04:00
nsCOMPtr<nsISupports> supports;
1999-07-01 04:16:39 +04:00
if(NS_SUCCEEDED(QueryInterface(nsCOMTypeInfo<nsISupports>::GetIID(), getter_AddRefs(supports))))
{
1999-05-05 02:34:35 +04:00
PRInt32 i;
for(i = 0; i < mListeners->Count(); i++)
{
1999-05-05 02:34:35 +04:00
//Folderlistener's aren't refcounted.
nsIFolderListener* listener =(nsIFolderListener*)mListeners->ElementAt(i);
listener->OnItemPropertyChanged(supports, property, oldValue, newValue);
}
1999-05-14 04:45:25 +04:00
//Notify listeners who listen to every folder
nsresult rv;
NS_WITH_SERVICE(nsIMsgMailSession, mailSession, kMsgMailSessionCID, &rv);
if(NS_SUCCEEDED(rv))
mailSession->NotifyFolderItemPropertyChanged(supports, property, oldValue, newValue);
}
return NS_OK;
}
1999-05-14 04:45:25 +04:00
nsresult nsMsgFolder::NotifyPropertyFlagChanged(nsISupports *item, char *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(nsIMsgMailSession, mailSession, kMsgMailSessionCID, &rv);
if(NS_SUCCEEDED(rv))
mailSession->NotifyFolderItemPropertyFlagChanged(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;
1999-05-05 02:34:35 +04:00
PRInt32 i;
for(i = 0; i < mListeners->Count(); i++)
{
1999-05-05 02:34:35 +04:00
//Folderlistener's aren't refcounted.
nsIFolderListener *listener = (nsIFolderListener*)mListeners->ElementAt(i);
listener->OnItemAdded(parentItem, item, viewString);
}
1999-05-14 04:45:25 +04:00
//Notify listeners who listen to every folder
nsresult rv;
NS_WITH_SERVICE(nsIMsgMailSession, mailSession, kMsgMailSessionCID, &rv);
if(NS_SUCCEEDED(rv))
mailSession->NotifyFolderItemAdded(parentItem, item, viewString);
1999-05-14 04:45:25 +04:00
return NS_OK;
}
nsresult nsMsgFolder::NotifyItemDeleted(nsISupports *parentItem, nsISupports *item, const char* viewString)
{
1999-05-05 02:34:35 +04:00
PRInt32 i;
for(i = 0; i < mListeners->Count(); i++)
{
1999-05-05 02:34:35 +04:00
//Folderlistener's aren't refcounted.
nsIFolderListener *listener = (nsIFolderListener*)mListeners->ElementAt(i);
listener->OnItemRemoved(parentItem, item, viewString);
}
1999-05-14 04:45:25 +04:00
//Notify listeners who listen to every folder
nsresult rv;
NS_WITH_SERVICE(nsIMsgMailSession, mailSession, kMsgMailSessionCID, &rv);
if(NS_SUCCEEDED(rv))
mailSession->NotifyFolderItemDeleted(parentItem, item, viewString);
return NS_OK;
}
1999-09-17 01:07:56 +04:00
nsresult nsMsgFolder::NotifyFolderLoaded()
{
PRInt32 i;
for(i = 0; i < mListeners->Count(); i++)
{
//Folderlistener's aren't refcounted.
nsIFolderListener *listener = (nsIFolderListener*)mListeners->ElementAt(i);
listener->OnFolderLoaded(this);
}
//Notify listeners who listen to every folder
nsresult rv;
NS_WITH_SERVICE(nsIMsgMailSession, mailSession, kMsgMailSessionCID, &rv);
if(NS_SUCCEEDED(rv))
mailSession->NotifyFolderLoaded(this);
return NS_OK;
}
nsresult
nsGetMailFolderSeparator(nsString& result)
{
static char* gMailFolderSep = nsnull; // never freed
if (gMailFolderSep == nsnull) {
gMailFolderSep = PR_smprintf(".sbd");
if (gMailFolderSep == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
}
result = gMailFolderSep;
return NS_OK;
}