Mozilla/mozilla/mailnews/base/src/nsMsgFolderDataSource.cpp
putterman%netscape.com c8e130002e Added MarkAllMessagesRead
git-svn-id: svn://10.0.0.236/trunk@41000 18797224-902f-48f8-a5cc-f745e15eee43
1999-07-24 21:10:53 +00:00

1082 lines
31 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.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1999 Netscape Communications Corporation. All Rights
* Reserved.
*/
#include "msgCore.h" // precompiled header...
#include "nsMsgFolderDataSource.h"
#include "nsMsgFolderFlags.h"
#include "nsMsgFolder.h"
#include "nsMsgRDFUtils.h"
#include "rdf.h"
#include "nsIRDFService.h"
#include "nsRDFCID.h"
#include "nsIRDFNode.h"
#include "nsEnumeratorUtils.h"
#include "nsString.h"
#include "nsCOMPtr.h"
#include "nsXPIDLString.h"
#include "nsIMsgMailSession.h"
#include "nsIMsgCopyService.h"
#include "nsMsgBaseCID.h"
static NS_DEFINE_CID(kRDFServiceCID, NS_RDFSERVICE_CID);
static NS_DEFINE_CID(kMsgMailSessionCID, NS_MSGMAILSESSION_CID);
static NS_DEFINE_CID(kMsgCopyServiceCID, NS_MSGCOPYSERVICE_CID);
nsIRDFResource* nsMsgFolderDataSource::kNC_Child = nsnull;
nsIRDFResource* nsMsgFolderDataSource::kNC_MessageChild = nsnull;
nsIRDFResource* nsMsgFolderDataSource::kNC_Folder= nsnull;
nsIRDFResource* nsMsgFolderDataSource::kNC_Name= nsnull;
nsIRDFResource* nsMsgFolderDataSource::kNC_SpecialFolder= nsnull;
nsIRDFResource* nsMsgFolderDataSource::kNC_TotalMessages= nsnull;
nsIRDFResource* nsMsgFolderDataSource::kNC_TotalUnreadMessages= nsnull;
nsIRDFResource* nsMsgFolderDataSource::kNC_Charset = nsnull;
nsIRDFResource* nsMsgFolderDataSource::kNC_BiffState = nsnull;
// commands
nsIRDFResource* nsMsgFolderDataSource::kNC_Delete= nsnull;
nsIRDFResource* nsMsgFolderDataSource::kNC_NewFolder= nsnull;
nsIRDFResource* nsMsgFolderDataSource::kNC_GetNewMessages= nsnull;
nsIRDFResource* nsMsgFolderDataSource::kNC_Copy= nsnull;
nsIRDFResource* nsMsgFolderDataSource::kNC_Move= nsnull;
nsIRDFResource* nsMsgFolderDataSource::kNC_MarkAllMessagesRead= nsnull;
nsMsgFolderDataSource::nsMsgFolderDataSource():
mInitialized(PR_FALSE),
mRDFService(nsnull)
{
}
nsMsgFolderDataSource::~nsMsgFolderDataSource (void)
{
nsresult rv;
mRDFService->UnregisterDataSource(this);
NS_WITH_SERVICE(nsIMsgMailSession, mailSession, kMsgMailSessionCID, &rv);
if(NS_SUCCEEDED(rv))
mailSession->RemoveFolderListener(this);
nsrefcnt refcnt;
NS_RELEASE2(kNC_Child, refcnt);
NS_RELEASE2(kNC_MessageChild, refcnt);
NS_RELEASE2(kNC_Folder, refcnt);
NS_RELEASE2(kNC_Name, refcnt);
NS_RELEASE2(kNC_SpecialFolder, refcnt);
NS_RELEASE2(kNC_TotalMessages, refcnt);
NS_RELEASE2(kNC_TotalUnreadMessages, refcnt);
NS_RELEASE2(kNC_Charset, refcnt);
NS_RELEASE2(kNC_BiffState, refcnt);
NS_RELEASE2(kNC_Delete, refcnt);
NS_RELEASE2(kNC_NewFolder, refcnt);
NS_RELEASE2(kNC_GetNewMessages, refcnt);
NS_RELEASE2(kNC_Copy, refcnt);
NS_RELEASE2(kNC_Move, refcnt);
NS_RELEASE2(kNC_MarkAllMessagesRead, refcnt);
nsServiceManager::ReleaseService(kRDFServiceCID, mRDFService); // XXX probably need shutdown listener here
mRDFService = nsnull;
}
nsresult nsMsgFolderDataSource::Init()
{
if (mInitialized)
return NS_ERROR_ALREADY_INITIALIZED;
nsresult rv = nsServiceManager::GetService(kRDFServiceCID,
nsCOMTypeInfo<nsIRDFService>::GetIID(),
(nsISupports**) &mRDFService); // XXX probably need shutdown listener here
PR_ASSERT(NS_SUCCEEDED(rv));
if (NS_FAILED(rv)) return rv;
NS_WITH_SERVICE(nsIMsgMailSession, mailSession, kMsgMailSessionCID, &rv);
if(NS_SUCCEEDED(rv))
mailSession->AddFolderListener(this);
mRDFService->RegisterDataSource(this, PR_FALSE);
if (! kNC_Child) {
mRDFService->GetResource(NC_RDF_CHILD, &kNC_Child);
mRDFService->GetResource(NC_RDF_MESSAGECHILD, &kNC_MessageChild);
mRDFService->GetResource(NC_RDF_FOLDER, &kNC_Folder);
mRDFService->GetResource(NC_RDF_NAME, &kNC_Name);
mRDFService->GetResource(NC_RDF_SPECIALFOLDER, &kNC_SpecialFolder);
mRDFService->GetResource(NC_RDF_TOTALMESSAGES, &kNC_TotalMessages);
mRDFService->GetResource(NC_RDF_TOTALUNREADMESSAGES, &kNC_TotalUnreadMessages);
mRDFService->GetResource(NC_RDF_CHARSET, &kNC_Charset);
mRDFService->GetResource(NC_RDF_BIFFSTATE, &kNC_BiffState);
mRDFService->GetResource(NC_RDF_DELETE, &kNC_Delete);
mRDFService->GetResource(NC_RDF_NEWFOLDER, &kNC_NewFolder);
mRDFService->GetResource(NC_RDF_GETNEWMESSAGES, &kNC_GetNewMessages);
mRDFService->GetResource(NC_RDF_COPY, &kNC_Copy);
mRDFService->GetResource(NC_RDF_MOVE, &kNC_Move);
mRDFService->GetResource(NC_RDF_MARKALLMESSAGESREAD, &kNC_MarkAllMessagesRead);
}
mInitialized = PR_TRUE;
return NS_OK;
}
NS_IMPL_ADDREF_INHERITED(nsMsgFolderDataSource, nsMsgRDFDataSource)
NS_IMPL_RELEASE_INHERITED(nsMsgFolderDataSource, nsMsgRDFDataSource)
NS_IMETHODIMP
nsMsgFolderDataSource::QueryInterface(REFNSIID iid, void** result)
{
if (! result)
return NS_ERROR_NULL_POINTER;
*result = nsnull;
if(iid.Equals(nsCOMTypeInfo<nsIFolderListener>::GetIID()))
{
*result = NS_STATIC_CAST(nsIFolderListener*, this);
NS_ADDREF(this);
return NS_OK;
}
else
return nsMsgRDFDataSource::QueryInterface(iid, result);
}
// nsIRDFDataSource methods
NS_IMETHODIMP nsMsgFolderDataSource::GetURI(char* *uri)
{
if ((*uri = nsXPIDLCString::Copy("rdf:mailnewsfolders")) == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
else
return NS_OK;
}
NS_IMETHODIMP nsMsgFolderDataSource::GetSource(nsIRDFResource* property,
nsIRDFNode* target,
PRBool tv,
nsIRDFResource** source /* out */)
{
PR_ASSERT(0);
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsMsgFolderDataSource::GetTarget(nsIRDFResource* source,
nsIRDFResource* property,
PRBool tv,
nsIRDFNode** target)
{
nsresult rv = NS_RDF_NO_VALUE;
// we only have positive assertions in the mail data source.
if (! tv)
return NS_RDF_NO_VALUE;
nsCOMPtr<nsIMsgFolder> folder(do_QueryInterface(source));
if (folder) {
rv = createFolderNode(folder, property, target);
#if 0
nsXPIDLCString srcval;
nsXPIDLCString propval;
nsXPIDLCString targetval;
source->GetValue(getter_Copies(srcval));
property->GetValue(getter_Copies(propval));
// (*target)->GetValue(getter_Copies(targetval));
printf("nsMsgFolderDataSource::GetTarget(%s, %s, %s, (%s))\n",
(const char*)srcval,
(const char*)propval, tv ? "TRUE" : "FALSE",
(const char*)"");
#endif
}
else
return NS_RDF_NO_VALUE;
return rv;
}
NS_IMETHODIMP nsMsgFolderDataSource::GetSources(nsIRDFResource* property,
nsIRDFNode* target,
PRBool tv,
nsISimpleEnumerator** sources)
{
PR_ASSERT(0);
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsMsgFolderDataSource::GetTargets(nsIRDFResource* source,
nsIRDFResource* property,
PRBool tv,
nsISimpleEnumerator** targets)
{
nsresult rv = NS_RDF_NO_VALUE;
if(!targets)
return NS_ERROR_NULL_POINTER;
#if 0
nsXPIDLCString srcval;
nsXPIDLCString propval;
nsXPIDLCString targetval;
source->GetValue(getter_Copies(srcval));
property->GetValue(getter_Copies(propval));
// (*target)->GetValue(getter_Copies(targetval));
printf("nsMsgFolderDataSource::GetTargets(%s, %s, %s, (%s))\n",
(const char*)srcval,
(const char*)propval, tv ? "TRUE" : "FALSE",
(const char*)"");
#endif
*targets = nsnull;
nsCOMPtr<nsIMsgFolder> folder(do_QueryInterface(source, &rv));
if (NS_SUCCEEDED(rv))
{
if ((kNC_Child == property))
{
nsCOMPtr<nsIEnumerator> subFolders;
rv = folder->GetSubFolders(getter_AddRefs(subFolders));
if (NS_SUCCEEDED(rv))
{
nsAdapterEnumerator* cursor =
new nsAdapterEnumerator(subFolders);
if (cursor == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(cursor);
*targets = cursor;
rv = NS_OK;
}
}
else if ((kNC_MessageChild == property))
{
nsCOMPtr<nsIEnumerator> messages;
rv = folder->GetMessages(getter_AddRefs(messages));
if (NS_SUCCEEDED(rv))
{
nsAdapterEnumerator* cursor =
new nsAdapterEnumerator(messages);
if (cursor == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(cursor);
*targets = cursor;
rv = NS_OK;
}
}
else if((kNC_Name == property) || (kNC_SpecialFolder == property))
{
nsSingletonEnumerator* cursor =
new nsSingletonEnumerator(property);
if (cursor == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(cursor);
*targets = cursor;
rv = NS_OK;
}
}
if(!*targets)
{
//create empty cursor
nsCOMPtr<nsISupportsArray> assertions;
NS_NewISupportsArray(getter_AddRefs(assertions));
nsArrayEnumerator* cursor =
new nsArrayEnumerator(assertions);
if(cursor == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(cursor);
*targets = cursor;
rv = NS_OK;
}
return rv;
}
NS_IMETHODIMP nsMsgFolderDataSource::Assert(nsIRDFResource* source,
nsIRDFResource* property,
nsIRDFNode* target,
PRBool tv)
{
nsresult rv;
nsCOMPtr<nsIMsgFolder> folder(do_QueryInterface(source, &rv));
//We don't handle tv = PR_FALSE at the moment.
if(NS_SUCCEEDED(rv) && tv)
return DoFolderAssert(folder, property, target);
else
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP nsMsgFolderDataSource::Unassert(nsIRDFResource* source,
nsIRDFResource* property,
nsIRDFNode* target)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP nsMsgFolderDataSource::HasAssertion(nsIRDFResource* source,
nsIRDFResource* property,
nsIRDFNode* target,
PRBool tv,
PRBool* hasAssertion)
{
nsresult rv;
nsCOMPtr<nsIMsgFolder> folder(do_QueryInterface(source, &rv));
if(NS_SUCCEEDED(rv))
return DoFolderHasAssertion(folder, property, target, tv, hasAssertion);
else
*hasAssertion = PR_FALSE;
return NS_OK;
}
NS_IMETHODIMP nsMsgFolderDataSource::ArcLabelsIn(nsIRDFNode* node,
nsISimpleEnumerator** labels)
{
return nsMsgRDFDataSource::ArcLabelsIn(node, labels);
}
NS_IMETHODIMP nsMsgFolderDataSource::ArcLabelsOut(nsIRDFResource* source,
nsISimpleEnumerator** labels)
{
nsCOMPtr<nsISupportsArray> arcs;
nsresult rv = NS_RDF_NO_VALUE;
nsCOMPtr<nsIMsgFolder> folder(do_QueryInterface(source, &rv));
if (NS_SUCCEEDED(rv)) {
fflush(stdout);
rv = getFolderArcLabelsOut(folder, getter_AddRefs(arcs));
#if 0
nsXPIDLCString srcval;
source->GetValue(getter_Copies(srcval));
printf("nsMsgFolderDataSource::ArcLabelsOut(%s)\n", (const char*)srcval);
#endif
}
else {
// how to return an empty cursor?
// for now return a 0-length nsISupportsArray
NS_NewISupportsArray(getter_AddRefs(arcs));
}
nsArrayEnumerator* cursor =
new nsArrayEnumerator(arcs);
if (cursor == nsnull)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(cursor);
*labels = cursor;
return NS_OK;
}
nsresult
nsMsgFolderDataSource::getFolderArcLabelsOut(nsIMsgFolder *folder,
nsISupportsArray **arcs)
{
nsresult rv;
rv = NS_NewISupportsArray(arcs);
if(NS_FAILED(rv))
return rv;
(*arcs)->AppendElement(kNC_Name);
(*arcs)->AppendElement(kNC_SpecialFolder);
(*arcs)->AppendElement(kNC_TotalMessages);
(*arcs)->AppendElement(kNC_TotalUnreadMessages);
(*arcs)->AppendElement(kNC_Charset);
(*arcs)->AppendElement(kNC_BiffState);
(*arcs)->AppendElement(kNC_Child);
(*arcs)->AppendElement(kNC_MessageChild);
return NS_OK;
}
NS_IMETHODIMP
nsMsgFolderDataSource::GetAllResources(nsISimpleEnumerator** aCursor)
{
NS_NOTYETIMPLEMENTED("sorry!");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsMsgFolderDataSource::GetAllCommands(nsIRDFResource* source,
nsIEnumerator/*<nsIRDFResource>*/** commands)
{
nsresult rv;
nsCOMPtr<nsISupportsArray> cmds;
nsCOMPtr<nsIMsgFolder> folder(do_QueryInterface(source, &rv));
if (NS_SUCCEEDED(rv)) {
rv = NS_NewISupportsArray(getter_AddRefs(cmds));
if (NS_FAILED(rv)) return rv;
cmds->AppendElement(kNC_Delete);
cmds->AppendElement(kNC_NewFolder);
cmds->AppendElement(kNC_GetNewMessages);
cmds->AppendElement(kNC_Copy);
cmds->AppendElement(kNC_Move);
cmds->AppendElement(kNC_MarkAllMessagesRead);
}
if (cmds != nsnull)
return cmds->Enumerate(commands);
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsMsgFolderDataSource::GetAllCmds(nsIRDFResource* source,
nsISimpleEnumerator/*<nsIRDFResource>*/** commands)
{
NS_NOTYETIMPLEMENTED("sorry!");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsMsgFolderDataSource::IsCommandEnabled(nsISupportsArray/*<nsIRDFResource>*/* aSources,
nsIRDFResource* aCommand,
nsISupportsArray/*<nsIRDFResource>*/* aArguments,
PRBool* aResult)
{
nsresult rv;
nsCOMPtr<nsIMsgFolder> folder;
PRUint32 cnt;
rv = aSources->Count(&cnt);
if (NS_FAILED(rv)) return rv;
for (PRUint32 i = 0; i < cnt; i++) {
nsCOMPtr<nsISupports> source = getter_AddRefs(aSources->ElementAt(i));
folder = do_QueryInterface(source, &rv);
if (NS_SUCCEEDED(rv)) {
// we don't care about the arguments -- folder commands are always enabled
if (!((aCommand == kNC_Delete) ||
(aCommand == kNC_NewFolder) ||
(aCommand == kNC_Copy) ||
(aCommand == kNC_Move) ||
(aCommand == kNC_GetNewMessages) ||
(aCommand == kNC_MarkAllMessagesRead))) {
*aResult = PR_FALSE;
return NS_OK;
}
}
}
*aResult = PR_TRUE;
return NS_OK; // succeeded for all sources
}
NS_IMETHODIMP
nsMsgFolderDataSource::DoCommand(nsISupportsArray/*<nsIRDFResource>*/* aSources,
nsIRDFResource* aCommand,
nsISupportsArray/*<nsIRDFResource>*/* aArguments)
{
nsresult rv = NS_OK;
nsCOMPtr<nsITransactionManager> transactionManager;
nsCOMPtr<nsISupports> supports;
// XXX need to handle batching of command applied to all sources
PRUint32 cnt;
PRUint32 i = 0;
rv = aSources->Count(&cnt);
if (NS_FAILED(rv)) return rv;
if (cnt > 1)
{
supports = getter_AddRefs(aSources->ElementAt(0));
transactionManager = do_QueryInterface(supports, &rv);
if (NS_SUCCEEDED(rv) && transactionManager)
{
aSources->RemoveElementAt(0);
cnt--;
}
}
for ( ; i < cnt; i++) {
supports = getter_AddRefs(aSources->ElementAt(i));
nsCOMPtr<nsIMsgFolder> folder = do_QueryInterface(supports, &rv);
if (NS_SUCCEEDED(rv)) {
if ((aCommand == kNC_Delete))
{
rv = DoDeleteFromFolder(folder, aArguments, transactionManager);
}
else if((aCommand == kNC_NewFolder))
{
rv = DoNewFolder(folder, aArguments);
}
else if((aCommand == kNC_GetNewMessages))
{
rv = folder->GetNewMessages();
}
else if((aCommand == kNC_Copy))
{
rv = DoCopyToFolder(folder, aArguments, transactionManager, PR_FALSE);
}
else if((aCommand == kNC_Move))
{
rv = DoCopyToFolder(folder, aArguments, transactionManager, PR_TRUE);
}
else if((aCommand == kNC_MarkAllMessagesRead))
{
rv = folder->MarkAllMessagesRead();
}
}
}
//for the moment return NS_OK, because failure stops entire DoCommand process.
return NS_OK;
}
NS_IMETHODIMP nsMsgFolderDataSource::OnItemAdded(nsIFolder *parentFolder, nsISupports *item)
{
nsresult rv;
nsCOMPtr<nsIMessage> message;
nsCOMPtr<nsIMsgFolder> folder;
nsCOMPtr<nsIRDFResource> parentResource;
if(NS_SUCCEEDED(parentFolder->QueryInterface(nsCOMTypeInfo<nsIRDFResource>::GetIID(), getter_AddRefs(parentResource))))
{
//If we are adding a message
if(NS_SUCCEEDED(item->QueryInterface(nsCOMTypeInfo<nsIMessage>::GetIID(), getter_AddRefs(message))))
{
nsCOMPtr<nsIRDFNode> itemNode(do_QueryInterface(item, &rv));
if(NS_SUCCEEDED(rv))
{
//Notify folders that a message was added.
NotifyObservers(parentResource, kNC_MessageChild, itemNode, PR_TRUE);
}
}
//If we are adding a folder
else if(NS_SUCCEEDED(item->QueryInterface(nsCOMTypeInfo<nsIMsgFolder>::GetIID(), getter_AddRefs(folder))))
{
nsCOMPtr<nsIRDFNode> itemNode(do_QueryInterface(item, &rv));
if(NS_SUCCEEDED(rv))
{
//Notify folders that a message was added.
NotifyObservers(parentResource, kNC_Child, itemNode, PR_TRUE);
}
}
}
return NS_OK;
}
NS_IMETHODIMP nsMsgFolderDataSource::OnItemRemoved(nsIFolder *parentFolder, nsISupports *item)
{
nsresult rv;
nsCOMPtr<nsIMessage> message;
nsCOMPtr<nsIMsgFolder> folder;
nsCOMPtr<nsIRDFResource> parentResource;
if(NS_SUCCEEDED(parentFolder->QueryInterface(nsCOMTypeInfo<nsIRDFResource>::GetIID(), getter_AddRefs(parentResource))))
{
//If we are removing a message
if(NS_SUCCEEDED(item->QueryInterface(nsCOMTypeInfo<nsIMessage>::GetIID(), getter_AddRefs(message))))
{
nsCOMPtr<nsIRDFNode> itemNode(do_QueryInterface(item, &rv));
if(NS_SUCCEEDED(rv))
{
//Notify folders that a message was deleted.
NotifyObservers(parentResource, kNC_MessageChild, itemNode, PR_FALSE);
}
}
//If we are removing a folder
else if(NS_SUCCEEDED(item->QueryInterface(nsCOMTypeInfo<nsIMsgFolder>::GetIID(), getter_AddRefs(folder))))
{
nsCOMPtr<nsIRDFNode> itemNode(do_QueryInterface(item, &rv));
if(NS_SUCCEEDED(rv))
{
//Notify folders that a message was deleted.
NotifyObservers(parentResource, kNC_Child, itemNode, PR_FALSE);
}
}
}
return NS_OK;
}
NS_IMETHODIMP nsMsgFolderDataSource::OnItemPropertyChanged(nsISupports *item, const char *property,
const char *oldValue, const char *newValue)
{
nsresult rv;
nsCOMPtr<nsIRDFResource> resource(do_QueryInterface(item, &rv));
if(NS_SUCCEEDED(rv))
{
if(PL_strcmp("TotalMessages", property) == 0)
{
NotifyPropertyChanged(resource, kNC_TotalMessages, oldValue, newValue);
}
else if(PL_strcmp("TotalUnreadMessages", property) == 0)
{
NotifyPropertyChanged(resource, kNC_TotalUnreadMessages, oldValue, newValue);
}
}
return NS_OK;
}
NS_IMETHODIMP nsMsgFolderDataSource::OnItemPropertyFlagChanged(nsISupports *item, const char *property,
PRUint32 oldFlag, PRUint32 newFlag)
{
nsresult rv;
nsCOMPtr<nsIMsgFolder> folder(do_QueryInterface(item));
if(folder)
{
nsCOMPtr<nsIRDFResource> resource(do_QueryInterface(item));
if(resource)
{
if(PL_strcmp("BiffState", property) == 0)
{
nsAutoString oldBiffStateStr((const char *)"",eOneByte), newBiffStateStr ((const char *)"", eOneByte);
rv = GetBiffStateString(oldFlag, oldBiffStateStr);
if(NS_FAILED(rv))
return rv;
rv = GetBiffStateString(newFlag, newBiffStateStr);
if(NS_FAILED(rv))
return rv;
NotifyPropertyChanged(resource, kNC_BiffState, oldBiffStateStr.GetBuffer(), newBiffStateStr.GetBuffer());
}
}
}
return NS_OK;
}
nsresult nsMsgFolderDataSource::NotifyPropertyChanged(nsIRDFResource *resource,
nsIRDFResource *propertyResource,
const char *oldValue, const char *newValue)
{
nsCOMPtr<nsIRDFNode> oldValueNode, newValueNode;
nsString oldValueStr = oldValue;
nsString newValueStr = newValue;
createNode(oldValueStr,getter_AddRefs(oldValueNode));
createNode(newValueStr, getter_AddRefs(newValueNode));
NotifyObservers(resource, propertyResource, oldValueNode, PR_FALSE);
NotifyObservers(resource, propertyResource, newValueNode, PR_TRUE);
return NS_OK;
}
nsresult nsMsgFolderDataSource::createFolderNode(nsIMsgFolder* folder,
nsIRDFResource* property,
nsIRDFNode** target)
{
nsresult rv = NS_RDF_NO_VALUE;
if ((kNC_Name == property))
rv = createFolderNameNode(folder, target);
else if ((kNC_SpecialFolder == property))
rv = createFolderSpecialNode(folder,target);
else if ((kNC_TotalMessages == property))
rv = createTotalMessagesNode(folder, target);
else if ((kNC_TotalUnreadMessages == property))
rv = createUnreadMessagesNode(folder, target);
else if ((kNC_Charset == property))
rv = createCharsetNode(folder, target);
else if ((kNC_BiffState == property))
rv = createBiffStateNode(folder, target);
else if ((kNC_Child == property))
rv = createFolderChildNode(folder, target);
else if ((kNC_MessageChild == property))
rv = createFolderMessageNode(folder, target);
return rv;
}
nsresult nsMsgFolderDataSource::createFolderNameNode(nsIMsgFolder *folder,
nsIRDFNode **target)
{
PRUnichar *name;
nsresult rv = folder->GetName(&name);
if (NS_FAILED(rv)) return rv;
nsString nameString(name);
createNode(nameString, target);
delete[] name;
return NS_OK;
}
nsresult
nsMsgFolderDataSource::createFolderSpecialNode(nsIMsgFolder *folder,
nsIRDFNode **target)
{
PRUint32 flags;
nsresult rv = folder->GetFlags(&flags);
if(NS_FAILED(rv)) return rv;
nsString specialFolderString;
if(flags & MSG_FOLDER_FLAG_INBOX)
specialFolderString = "Inbox";
else if(flags & MSG_FOLDER_FLAG_TRASH)
specialFolderString = "Trash";
else if(flags & MSG_FOLDER_FLAG_QUEUE)
specialFolderString = "Unsent Messages";
else if(flags & MSG_FOLDER_FLAG_SENTMAIL)
specialFolderString = "Sent";
else if(flags & MSG_FOLDER_FLAG_DRAFTS)
specialFolderString = "Drafts";
else if(flags & MSG_FOLDER_FLAG_TEMPLATES)
specialFolderString = "Templates";
else
specialFolderString = "none";
createNode(specialFolderString, target);
return NS_OK;
}
nsresult
nsMsgFolderDataSource::createTotalMessagesNode(nsIMsgFolder *folder,
nsIRDFNode **target)
{
nsresult rv;
PRInt32 totalMessages;
rv = folder->GetTotalMessages(PR_FALSE, &totalMessages);
if(NS_SUCCEEDED(rv))
{
if(totalMessages >= 0)
rv = createNode(totalMessages, target);
else if(totalMessages == -1)
{
nsString unknownMessages("???");
createNode(unknownMessages, target);
}
else if(totalMessages == -2)
{
nsString unknownMessages("");
createNode(unknownMessages, target);
}
}
return rv;
}
nsresult
nsMsgFolderDataSource::createCharsetNode(nsIMsgFolder *folder, nsIRDFNode **target)
{
PRUnichar *charset;
nsString charsetStr;
nsresult rv = folder->GetCharset(&charset);
//We always need to return a value
if(NS_SUCCEEDED(rv))
charsetStr = charset;
else
charsetStr ="";
createNode(charsetStr, target);
return NS_OK;
}
nsresult
nsMsgFolderDataSource::createBiffStateNode(nsIMsgFolder *folder, nsIRDFNode **target)
{
nsresult rv;
PRUint32 biffState;
rv = folder->GetBiffState(&biffState);
if(NS_FAILED(rv)) return rv;
nsString biffString;
GetBiffStateString(biffState, biffString);
createNode(biffString, target);
return NS_OK;
}
nsresult
nsMsgFolderDataSource::GetBiffStateString(PRUint32 biffState, nsString& biffStateStr)
{
if(biffState == nsMsgBiffState_NewMail)
biffStateStr = "NewMail";
else if(biffState == nsMsgBiffState_NoMail)
biffStateStr = "NoMail";
else
biffStateStr = "UnknownMail";
return NS_OK;
}
nsresult
nsMsgFolderDataSource::createUnreadMessagesNode(nsIMsgFolder *folder,
nsIRDFNode **target)
{
nsresult rv;
PRInt32 totalUnreadMessages;
rv = folder->GetNumUnread(PR_FALSE, &totalUnreadMessages);
if(NS_SUCCEEDED(rv))
{
if(totalUnreadMessages >=0)
rv = createNode(totalUnreadMessages, target);
else if(totalUnreadMessages == -1)
{
nsString unknownMessages("???");
createNode(unknownMessages, target);
}
else if(totalUnreadMessages == -2)
{
nsString unknownMessages("");
createNode(unknownMessages, target);
}
}
return NS_OK;
}
nsresult
nsMsgFolderDataSource::createFolderChildNode(nsIMsgFolder *folder,
nsIRDFNode **target)
{
nsCOMPtr<nsIEnumerator> subFolders;
nsresult rv = folder->GetSubFolders(getter_AddRefs(subFolders));
if (NS_FAILED(rv))
return NS_RDF_NO_VALUE;
rv = subFolders->First();
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsISupports> firstFolder;
rv = subFolders->CurrentItem(getter_AddRefs(firstFolder));
if (NS_SUCCEEDED(rv)) {
firstFolder->QueryInterface(nsCOMTypeInfo<nsIRDFResource>::GetIID(), (void**)target);
}
}
return NS_FAILED(rv) ? NS_RDF_NO_VALUE : rv;
}
nsresult
nsMsgFolderDataSource::createFolderMessageNode(nsIMsgFolder *folder,
nsIRDFNode **target)
{
nsCOMPtr<nsIEnumerator> messages;
nsresult rv = folder->GetMessages(getter_AddRefs(messages));
if (NS_SUCCEEDED(rv) && rv != NS_RDF_CURSOR_EMPTY) {
rv = messages->First();
if (NS_SUCCEEDED(rv)) {
nsCOMPtr<nsISupports> firstMessage;
rv = messages->CurrentItem(getter_AddRefs(firstMessage));
if (NS_SUCCEEDED(rv)) {
rv = firstMessage->QueryInterface(nsCOMTypeInfo<nsIRDFNode>::GetIID(), (void**)target);
}
}
}
return rv == NS_OK ? NS_OK : NS_RDF_NO_VALUE;
}
nsresult nsMsgFolderDataSource::DoCopyToFolder(nsIMsgFolder *dstFolder, nsISupportsArray *arguments,
nsITransactionManager *txnMgr, PRBool isMove)
{
nsresult rv;
PRUint32 itemCount;
rv = arguments->Count(&itemCount);
if (NS_FAILED(rv)) return rv;
//need source folder and at least one item to copy
if(itemCount < 2)
return NS_ERROR_FAILURE;
nsCOMPtr<nsISupports> srcFolderSupports = getter_AddRefs(arguments->ElementAt(0));
nsCOMPtr<nsIMsgFolder> srcFolder(do_QueryInterface(srcFolderSupports));
if(!srcFolder)
return NS_ERROR_FAILURE;
arguments->RemoveElementAt(0);
itemCount--;
nsCOMPtr<nsISupportsArray> messageArray;
NS_NewISupportsArray(getter_AddRefs(messageArray));
for(PRUint32 i = 0; i < itemCount; i++)
{
nsCOMPtr<nsISupports> supports = getter_AddRefs(arguments->ElementAt(i));
nsCOMPtr<nsIMessage> message(do_QueryInterface(supports));
if (message)
{
messageArray->AppendElement(supports);
}
}
//Call copyservice with dstFolder, srcFolder, messages, isMove, and txnManager
NS_WITH_SERVICE(nsIMsgCopyService, copyService, kMsgCopyServiceCID, &rv);
if(NS_SUCCEEDED(rv))
{
copyService->CopyMessages(srcFolder, messageArray, dstFolder, isMove,
nsnull, txnMgr);
}
return NS_OK;
}
nsresult nsMsgFolderDataSource::DoDeleteFromFolder(
nsIMsgFolder *folder, nsISupportsArray *arguments,
nsITransactionManager* txnMgr)
{
nsresult rv = NS_OK;
PRUint32 itemCount;
rv = arguments->Count(&itemCount);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsISupportsArray> messageArray, folderArray;
NS_NewISupportsArray(getter_AddRefs(messageArray));
NS_NewISupportsArray(getter_AddRefs(folderArray));
//Split up deleted items into different type arrays to be passed to the folder
//for deletion.
for(PRUint32 item = 0; item < itemCount; item++)
{
nsCOMPtr<nsISupports> supports = getter_AddRefs(arguments->ElementAt(item));
nsCOMPtr<nsIMessage> deletedMessage(do_QueryInterface(supports));
nsCOMPtr<nsIMsgFolder> deletedFolder(do_QueryInterface(supports));
if (deletedMessage)
{
messageArray->AppendElement(supports);
}
else if(deletedFolder)
{
folderArray->AppendElement(supports);
}
}
PRUint32 cnt;
rv = messageArray->Count(&cnt);
if (NS_FAILED(rv)) return rv;
if (cnt > 0)
rv = folder->DeleteMessages(messageArray, txnMgr, PR_FALSE);
rv = folderArray->Count(&cnt);
if (NS_FAILED(rv)) return rv;
if (cnt > 0)
rv = folder->DeleteSubFolders(folderArray);
return rv;
}
nsresult nsMsgFolderDataSource::DoNewFolder(nsIMsgFolder *folder, nsISupportsArray *arguments)
{
nsresult rv = NS_OK;
nsCOMPtr<nsISupports> elem = getter_AddRefs(arguments->ElementAt(0));
nsCOMPtr<nsIRDFLiteral> literal = do_QueryInterface(elem, &rv);
if(NS_SUCCEEDED(rv))
{
PRUnichar *name;
literal->GetValue(&name);
nsString tempStr = name;
nsAutoCString nameStr(tempStr);
rv = folder->CreateSubfolder(nameStr);
}
return rv;
}
nsresult nsMsgFolderDataSource::DoFolderAssert(nsIMsgFolder *folder, nsIRDFResource *property, nsIRDFNode *target)
{
nsresult rv = NS_ERROR_FAILURE;
if((kNC_Charset == property))
{
nsCOMPtr<nsIRDFLiteral> literal(do_QueryInterface(target));
if(literal)
{
PRUnichar *value;
rv = literal->GetValue(&value);
if(NS_SUCCEEDED(rv))
{
rv = folder->SetCharset(value);
delete[] value;
}
}
else
rv = NS_ERROR_FAILURE;
}
return rv;
}
nsresult nsMsgFolderDataSource::DoFolderHasAssertion(nsIMsgFolder *folder, nsIRDFResource *property, nsIRDFNode *target,
PRBool tv, PRBool *hasAssertion)
{
nsresult rv = NS_OK;
if(!hasAssertion)
return NS_ERROR_NULL_POINTER;
//We're not keeping track of negative assertions on folders.
if(!tv)
{
*hasAssertion = PR_FALSE;
return NS_OK;
}
if((kNC_Child == property))
{
nsCOMPtr<nsIFolder> childFolder(do_QueryInterface(target, &rv));
if(NS_SUCCEEDED(rv))
{
nsCOMPtr<nsIFolder> folderasFolder(do_QueryInterface(folder));
nsCOMPtr<nsIFolder> childsParent;
rv = childFolder->GetParent(getter_AddRefs(childsParent));
*hasAssertion = (NS_SUCCEEDED(rv) && childsParent && folderasFolder
&& (childsParent.get() == folderasFolder.get()));
}
}
else if((kNC_MessageChild == property))
{
nsCOMPtr<nsIMessage> message(do_QueryInterface(target, &rv));
if(NS_SUCCEEDED(rv))
rv = folder->HasMessage(message, hasAssertion);
}
else if ((kNC_Name == property) || (kNC_SpecialFolder == property) || (kNC_TotalMessages == property)
|| (kNC_TotalUnreadMessages == property) || (kNC_Charset == property) || (kNC_BiffState == property))
{
nsCOMPtr<nsIRDFResource> folderResource(do_QueryInterface(folder, &rv));
if(NS_FAILED(rv))
return rv;
rv = GetTargetHasAssertion(this, folderResource, property, tv, target, hasAssertion);
}
else
*hasAssertion = PR_FALSE;
return rv;
}
nsresult
NS_NewMsgFolderDataSource(const nsIID& iid, void **result)
{
NS_PRECONDITION(result != nsnull, "null ptr");
if (! result)
return NS_ERROR_NULL_POINTER;
nsMsgFolderDataSource* datasource = new nsMsgFolderDataSource();
if (! datasource)
return NS_ERROR_OUT_OF_MEMORY;
nsresult rv;
rv = datasource->Init();
if (NS_FAILED(rv)) {
delete datasource;
return rv;
}
return datasource->QueryInterface(iid, result);
}