add ability to create storage for folders on demand, e.g., templates and drafts, r=mscott 45146

This commit is contained in:
bienvenu%netscape.com 2000-08-05 14:28:47 +00:00
Родитель f0409f54b0
Коммит d1cbb2ce9c
18 изменённых файлов: 394 добавлений и 23 удалений

Просмотреть файл

@ -138,6 +138,12 @@ const nsMsgBiffState nsMsgBiffState_Unknown = 2; // We dunno whether there is ne
void createSubfolder(in wstring folderName);
[noscript] nsIMsgFolder addSubfolder(in nsAutoString folderName);
/* this method ensures the storage for the folder exists.
For local folders, it creates the berkeley mailbox if missing.
For imap folders, it subscribes to the folder if it exists,
or creates it if it doesn't exist
*/
void createStorageIfMissing(in nsIUrlListener urlListener);
void compact();
void emptyTrash(in nsIMsgWindow aMsgWindow, in nsIUrlListener aListener);

Просмотреть файл

@ -1038,6 +1038,15 @@ NS_IMETHODIMP nsMsgFolder::DeleteSubFolders(nsISupportsArray *folders,
}
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;

Просмотреть файл

@ -90,6 +90,7 @@ public:
NS_IMETHOD ForceDBClosed(void);
NS_IMETHOD Delete(void);
NS_IMETHOD DeleteSubFolders(nsISupportsArray *folders, nsIMsgWindow *msgWindow);
NS_IMETHOD CreateStorageIfMissing(nsIUrlListener* urlListener);
NS_IMETHOD PropagateDelete(nsIMsgFolder *folder, PRBool deleteStorage);
NS_IMETHOD RecursiveDelete(PRBool deleteStorage);
NS_IMETHOD CreateSubfolder(const PRUnichar *folderName);

Просмотреть файл

@ -157,7 +157,7 @@ CopyListener::SetMsgComposeAndSendObject(nsMsgComposeAndSend *obj)
// to listen for message copy completion and eventually notify the caller
////////////////////////////////////////////////////////////////////////////////////
NS_IMPL_ISUPPORTS(nsMsgCopy, NS_GET_IID(nsMsgCopy));
NS_IMPL_ISUPPORTS(nsMsgCopy, NS_GET_IID(nsIUrlListener))
nsMsgCopy::nsMsgCopy()
{
@ -184,6 +184,7 @@ nsMsgCopy::StartCopyOperation(nsIMsgIdentity *aUserIdentity,
{
nsCOMPtr<nsIMsgFolder> dstFolder;
PRBool isDraft = PR_FALSE;
PRBool waitForUrl = PR_FALSE;
nsresult rv;
if (!aMsgSendObj)
@ -198,7 +199,7 @@ nsMsgCopy::StartCopyOperation(nsIMsgIdentity *aUserIdentity,
//
if (aMode == nsIMsgSend::nsMsgQueueForLater) // QueueForLater (Outbox)
{
rv = GetUnsentMessagesFolder(aUserIdentity, getter_AddRefs(dstFolder));
rv = GetUnsentMessagesFolder(aUserIdentity, getter_AddRefs(dstFolder), &waitForUrl);
isDraft = PR_FALSE;
if (!dstFolder || NS_FAILED(rv)) {
return NS_MSG_UNABLE_TO_SEND_LATER;
@ -206,7 +207,7 @@ nsMsgCopy::StartCopyOperation(nsIMsgIdentity *aUserIdentity,
}
else if (aMode == nsIMsgSend::nsMsgSaveAsDraft) // SaveAsDraft (Drafts)
{
rv = GetDraftsFolder(aUserIdentity, getter_AddRefs(dstFolder));
rv = GetDraftsFolder(aUserIdentity, getter_AddRefs(dstFolder), &waitForUrl);
isDraft = PR_TRUE;
if (!dstFolder || NS_FAILED(rv)) {
return NS_MSG_UNABLE_TO_SAVE_DRAFT;
@ -214,7 +215,7 @@ nsMsgCopy::StartCopyOperation(nsIMsgIdentity *aUserIdentity,
}
else if (aMode == nsIMsgSend::nsMsgSaveAsTemplate) // SaveAsTemplate (Templates)
{
rv = GetTemplatesFolder(aUserIdentity, getter_AddRefs(dstFolder));
rv = GetTemplatesFolder(aUserIdentity, getter_AddRefs(dstFolder), &waitForUrl);
isDraft = PR_FALSE;
if (!dstFolder || NS_FAILED(rv)) {
return NS_MSG_UNABLE_TO_SAVE_TEMPLATE;
@ -222,7 +223,7 @@ nsMsgCopy::StartCopyOperation(nsIMsgIdentity *aUserIdentity,
}
else // SaveInSentFolder (Sent) - nsMsgDeliverNow
{
rv = GetSentFolder(aUserIdentity, getter_AddRefs(dstFolder));
rv = GetSentFolder(aUserIdentity, getter_AddRefs(dstFolder), &waitForUrl);
isDraft = PR_FALSE;
if (!dstFolder || NS_FAILED(rv)) {
return NS_MSG_COULDNT_OPEN_FCC_FOLDER;
@ -230,7 +231,19 @@ nsMsgCopy::StartCopyOperation(nsIMsgIdentity *aUserIdentity,
}
mMode = aMode;
rv = DoCopy(aFileSpec, dstFolder, aMsgToReplace, isDraft, nsnull, aMsgSendObj);
if (!waitForUrl)
{
rv = DoCopy(aFileSpec, dstFolder, aMsgToReplace, isDraft, nsnull, aMsgSendObj);
}
else
{
mFileSpec = aFileSpec;
mDstFolder = dstFolder;
mMsgToReplace = aMsgToReplace;
mIsDraft = isDraft;
mMsgSendObj = aMsgSendObj;
// cache info needed for DoCopy and call DoCopy when OnStopUrl is called.
}
return rv;
}
@ -305,30 +318,103 @@ nsMsgCopy::DoCopy(nsIFileSpec *aDiskFile, nsIMsgFolder *dstFolder,
return rv;
}
nsresult
nsMsgCopy::GetUnsentMessagesFolder(nsIMsgIdentity *userIdentity, nsIMsgFolder **folder)
// nsIUrlListener methods
NS_IMETHODIMP
nsMsgCopy::OnStartRunningUrl(nsIURI * aUrl)
{
return LocateMessageFolder(userIdentity, nsIMsgSend::nsMsgQueueForLater, mSavePref, folder);
return NS_OK;
}
NS_IMETHODIMP
nsMsgCopy::OnStopRunningUrl(nsIURI * aUrl, nsresult aExitCode)
{
nsresult rv = aExitCode;
if (NS_SUCCEEDED(aExitCode))
{
rv = DoCopy(mFileSpec, mDstFolder, mMsgToReplace, mIsDraft, nsnull, mMsgSendObj);
}
return rv;
}
nsresult
nsMsgCopy::GetUnsentMessagesFolder(nsIMsgIdentity *userIdentity, nsIMsgFolder **folder, PRBool *waitForUrl)
{
nsresult ret = LocateMessageFolder(userIdentity, nsIMsgSend::nsMsgQueueForLater, mSavePref, folder);
CreateIfMissing(folder, waitForUrl);
return ret;
}
nsresult
nsMsgCopy::GetDraftsFolder(nsIMsgIdentity *userIdentity, nsIMsgFolder **folder)
nsMsgCopy::GetDraftsFolder(nsIMsgIdentity *userIdentity, nsIMsgFolder **folder, PRBool *waitForUrl)
{
return LocateMessageFolder(userIdentity, nsIMsgSend::nsMsgSaveAsDraft, mSavePref, folder);
nsresult ret = LocateMessageFolder(userIdentity, nsIMsgSend::nsMsgSaveAsDraft, mSavePref, folder);
CreateIfMissing(folder, waitForUrl);
return ret;
}
nsresult
nsMsgCopy::GetTemplatesFolder(nsIMsgIdentity *userIdentity, nsIMsgFolder **folder)
nsMsgCopy::GetTemplatesFolder(nsIMsgIdentity *userIdentity, nsIMsgFolder **folder, PRBool *waitForUrl)
{
return LocateMessageFolder(userIdentity, nsIMsgSend::nsMsgSaveAsTemplate, mSavePref, folder);
nsresult ret = LocateMessageFolder(userIdentity, nsIMsgSend::nsMsgSaveAsTemplate, mSavePref, folder);
CreateIfMissing(folder, waitForUrl);
return ret;
}
nsresult
nsMsgCopy::GetSentFolder(nsIMsgIdentity *userIdentity, nsIMsgFolder **folder)
nsMsgCopy::GetSentFolder(nsIMsgIdentity *userIdentity, nsIMsgFolder **folder, PRBool *waitForUrl)
{
return LocateMessageFolder(userIdentity, nsIMsgSend::nsMsgDeliverNow, mSavePref, folder);
nsresult ret = LocateMessageFolder(userIdentity, nsIMsgSend::nsMsgDeliverNow, mSavePref, folder);
CreateIfMissing(folder, waitForUrl);
return ret;
}
nsresult
nsMsgCopy::CreateIfMissing(nsIMsgFolder **folder, PRBool *waitForUrl)
{
nsresult ret = NS_OK;
if (folder && *folder)
{
nsCOMPtr <nsIFolder> parent;
(*folder)->GetParent(getter_AddRefs(parent));
if (!parent)
{
nsCOMPtr <nsIFileSpec> folderPath;
// for local folders, path is to the berkeley mailbox.
// for imap folders, path needs to have .msf appended to the name
(*folder)->GetPath(getter_AddRefs(folderPath));
if (folderPath)
{
PRBool isImapFolder = !nsCRT::strncasecmp(mSavePref, "imap:", 5);
if (isImapFolder)
{
nsXPIDLCString leafName;
folderPath->GetLeafName(getter_Copies(leafName));
nsCString fullLeafName(leafName);
// Append .msf (msg summary file) this is what windows will want.
// Mac and Unix can decide for themselves.
fullLeafName.Append(".msf"); // message summary file
folderPath->SetLeafName(fullLeafName);
}
PRBool exists;
folderPath->Exists(&exists);
if (!exists)
{
(*folder)->CreateStorageIfMissing(this);
if (isImapFolder)
*waitForUrl = PR_TRUE;
ret = NS_OK;
}
}
}
}
return ret;
}
////////////////////////////////////////////////////////////////////////////////////
// Utility Functions for MsgFolders
////////////////////////////////////////////////////////////////////////////////////

Просмотреть файл

@ -75,7 +75,7 @@ private:
// This is a class that deals with processing remote attachments. It implements
// an nsIStreamListener interface to deal with incoming data
//
class nsMsgCopy : public nsISupports
class nsMsgCopy : public nsIUrlListener
{
public:
static const nsIID& GetIID() { static nsIID iid = NS_IMSGCOPY_IID; return iid; }
@ -85,6 +85,8 @@ public:
// nsISupports interface
NS_DECL_ISUPPORTS
NS_DECL_NSIURLLISTENER
//////////////////////////////////////////////////////////////////////
// Object methods...
@ -102,10 +104,11 @@ public:
nsIMsgWindow *msgWindow,
nsMsgComposeAndSend *aMsgSendObj);
nsresult GetUnsentMessagesFolder(nsIMsgIdentity *userIdentity, nsIMsgFolder **msgFolder);
nsresult GetDraftsFolder(nsIMsgIdentity *userIdentity, nsIMsgFolder **msgFolder);
nsresult GetTemplatesFolder(nsIMsgIdentity *userIdentity, nsIMsgFolder **msgFolder);
nsresult GetSentFolder(nsIMsgIdentity *userIdentity, nsIMsgFolder **msgFolder);
nsresult GetUnsentMessagesFolder(nsIMsgIdentity *userIdentity, nsIMsgFolder **msgFolder, PRBool *waitForUrl);
nsresult GetDraftsFolder(nsIMsgIdentity *userIdentity, nsIMsgFolder **msgFolder, PRBool *waitForUrl);
nsresult GetTemplatesFolder(nsIMsgIdentity *userIdentity, nsIMsgFolder **msgFolder, PRBool *waitForUrl);
nsresult GetSentFolder(nsIMsgIdentity *userIdentity, nsIMsgFolder **msgFolder, PRBool *waitForUrl);
nsresult CreateIfMissing(nsIMsgFolder **folder, PRBool *waitForUrl);
//
@ -114,6 +117,10 @@ public:
nsIFileSpec *mFileSpec; // the file we are sending...
nsMsgDeliverMode mMode;
nsCOMPtr<CopyListener> mCopyListener;
nsCOMPtr<nsIMsgFolder> mDstFolder;
nsCOMPtr<nsIMessage> mMsgToReplace;
PRBool mIsDraft;
nsMsgComposeAndSend *mMsgSendObj;
char *mSavePref;
};

Просмотреть файл

@ -3289,7 +3289,7 @@ nsMsgComposeAndSend::NotifyListenersOnStopCopy(nsresult aStatus)
// This is one per copy so make sure we clean this up first.
if (mCopyObj)
{
delete mCopyObj;
NS_RELEASE(mCopyObj);
mCopyObj = nsnull;
}
@ -4118,7 +4118,7 @@ nsMsgComposeAndSend::StartMessageCopyOperation(nsIFileSpec *aFileSpec,
mCopyObj = new nsMsgCopy();
if (!mCopyObj)
return NS_ERROR_OUT_OF_MEMORY;
NS_ADDREF(mCopyObj);
//
// Actually, we need to pick up the proper folder from the prefs and not
// default to the default "Flagged" folder choices

Просмотреть файл

@ -53,6 +53,7 @@ interface nsIImapMailFolderSink : nsISupports {
attribute boolean folderNeedsACLListed;
attribute boolean folderNeedsSubscribing;
attribute boolean folderNeedsAdded;
attribute boolean folderVerifiedOnline;
string GetOnlineDelimiter();
// Tell mail master about the newly selected mailbox
void UpdateImapMailboxInfo(in nsIImapProtocol aProtocol,

Просмотреть файл

@ -205,6 +205,16 @@ interface nsIImapService : nsISupports
in wstring mailboxName,
in nsIUrlListener aUrlListener);
// this method will first check if the folder exists but is
// not subscribed to, in which case it will subscribe to the folder.
// otherwise, it will try to create the folder. It will try to do this
// with one url.
nsIURI ensureFolderExists(in nsIEventQueue aClientEventQueue,
in nsIMsgFolder aParentFolder,
in wstring aLeafName,
in nsIUrlListener aUrlListener);
void buildSubscribeDatasource(in nsIImapIncomingServer aServer, in nsIMsgWindow aMsgWindow);
void buildSubscribeDatasourceWithPath(in nsIImapIncomingServer aServer, in nsIMsgWindow aMsgWindow, in string folderPath);
};

Просмотреть файл

@ -86,6 +86,7 @@ interface nsIImapUrl : nsISupports
attribute boolean mimePartSelectorDetected;
attribute nsImapContentModifiedType contentModified;
attribute boolean fetchPartsOnDemand; // set to true if we're fetching a msg for display and want to not download parts
attribute boolean msgLoadingFromCache; // true if this msg load is coming from a cache, so we can know to mark it read
attribute nsISupports copyState;
attribute nsIFileSpec msgFileSpec;
attribute nsIImapMockChannel mockChannel;

Просмотреть файл

@ -685,6 +685,59 @@ NS_IMETHODIMP nsImapMailFolder::RemoveSubFolder (nsIMsgFolder *which)
return nsMsgFolder::DeleteSubFolders(folders, nsnull);
}
NS_IMETHODIMP nsImapMailFolder::CreateStorageIfMissing(nsIUrlListener* urlListener)
{
nsresult status = NS_OK;
nsCOMPtr <nsIFolder> parent;
GetParent(getter_AddRefs(parent));
nsCOMPtr <nsIMsgFolder> msgParent;
if (parent)
msgParent = do_QueryInterface(parent);
// parent is probably not set because *this* was probably created by rdf
// and not by folder discovery. So, we have to compute the parent.
if (!msgParent)
{
nsCAutoString folderName = mURI;
nsCAutoString uri;
PRInt32 leafPos = folderName.RFindChar('/');
nsCAutoString parentName(folderName);
if (leafPos > 0)
{
// If there is a hierarchy, there is a parent.
// Don't strip off slash if it's the first character
parentName.Truncate(leafPos);
// get the corresponding RDF resource
// RDF will create the folder resource if it doesn't already exist
NS_WITH_SERVICE(nsIRDFService, rdf, kRDFServiceCID, &status);
if (NS_FAILED(status)) return status;
nsCOMPtr<nsIRDFResource> resource;
status = rdf->GetResource(parentName, getter_AddRefs(resource));
if (NS_FAILED(status)) return status;
msgParent = do_QueryInterface(resource, &status);
}
}
if (msgParent)
{
nsXPIDLString folderName;
GetName(getter_Copies(folderName));
nsresult rv;
NS_WITH_SERVICE(nsIImapService, imapService, kCImapService, &rv);
if (NS_SUCCEEDED(rv) && imapService)
{
nsCOMPtr <nsIURI> uri;
imapService->EnsureFolderExists(m_eventQueue, msgParent, folderName, urlListener, getter_AddRefs(uri));
}
}
return status;
}
NS_IMETHODIMP nsImapMailFolder::GetVerifiedAsOnlineFolder(PRBool *aVerifiedAsOnlineFolder)
{
@ -4208,6 +4261,20 @@ NS_IMETHODIMP nsImapMailFolder::SetFolderNeedsAdded(PRBool bVal)
return NS_OK;
}
NS_IMETHODIMP nsImapMailFolder::GetFolderVerifiedOnline(PRBool *bVal)
{
if (!bVal)
return NS_ERROR_NULL_POINTER;
*bVal = m_verifiedAsOnlineFolder;
return NS_OK;
}
NS_IMETHODIMP nsImapMailFolder::SetFolderVerifiedOnline(PRBool bVal)
{
m_verifiedAsOnlineFolder = bVal;
return NS_OK;
}
NS_IMETHODIMP nsImapMailFolder::PerformExpand(nsIMsgWindow *aMsgWindow)
{
nsresult rv;

Просмотреть файл

@ -120,6 +120,7 @@ public:
NS_IMETHOD CreateSubfolder(const PRUnichar *folderName);
NS_IMETHOD AddSubfolderWithPath(nsAutoString *name, nsIFileSpec *dbPath, nsIMsgFolder **child);
NS_IMETHODIMP CreateStorageIfMissing(nsIUrlListener* urlListener);
NS_IMETHOD Compact();
NS_IMETHOD EmptyTrash(nsIMsgWindow *msgWindow, nsIUrlListener *aListener);

Просмотреть файл

@ -4734,6 +4734,31 @@ void nsImapProtocol::OnCreateFolder(const char * aSourceMailbox)
FolderNotCreated(aSourceMailbox);
}
void nsImapProtocol::OnEnsureExistsFolder(const char * aSourceMailbox)
{
List(aSourceMailbox, PR_FALSE); // how to tell if that succeeded?
PRBool exists = PR_FALSE;
if (m_imapMailFolderSink)
m_imapMailFolderSink->GetFolderVerifiedOnline(&exists);
if (exists)
{
Subscribe(aSourceMailbox);
}
else
{
PRBool created = CreateMailboxRespectingSubscriptions(aSourceMailbox);
if (created)
{
List(aSourceMailbox, PR_FALSE);
}
}
if (!GetServerStateParser().LastCommandSuccessful())
FolderNotCreated(aSourceMailbox);
}
void nsImapProtocol::OnSubscribe(const char * sourceMailbox)
{
Subscribe(sourceMailbox);
@ -6058,6 +6083,10 @@ void nsImapProtocol::ProcessAuthenticatedStateURL()
sourceMailbox = OnCreateServerSourceFolderPathString();
OnCreateFolder(sourceMailbox);
break;
case nsIImapUrl::nsImapEnsureExistsFolder:
sourceMailbox = OnCreateServerSourceFolderPathString();
OnEnsureExistsFolder(sourceMailbox);
break;
case nsIImapUrl::nsImapDiscoverChildrenUrl:
{
char *canonicalParent = nsnull;
@ -6795,7 +6824,12 @@ NS_IMETHODIMP nsImapMockChannel::AsyncRead(nsIStreamListener *listener, nsISuppo
NS_RELEASE(cacheListener);
if (NS_SUCCEEDED(rv)) // ONLY if we succeeded in actually starting the read should we return
{
// if the msg is unread, we should mark it read on the server. This lets
// the code running this url we're loading from the cache, if it cares.
imapUrl->SetMsgLoadingFromCache(PR_TRUE);
return rv;
}
}
}

Просмотреть файл

@ -453,6 +453,7 @@ private:
char * OnCreateServerSourceFolderPathString();
char * OnCreateServerDestinationFolderPathString();
void OnCreateFolder(const char * aSourceMailbox);
void OnEnsureExistsFolder(const char * aSourceMailbox);
void OnSubscribe(const char * aSourceMailbox);
void OnUnsubscribe(const char * aSourceMailbox);
void RefreshACLForFolderIfNecessary(const char * mailboxName);

Просмотреть файл

@ -53,6 +53,7 @@
#include "nsMsgBaseCID.h"
#include "nsMsgFolderFlags.h"
#include "nsISubscribableServer.h"
#include "nsIMessage.h"
#define PREF_MAIL_ROOT_IMAP "mail.root.imap"
@ -469,8 +470,50 @@ NS_IMETHODIMP nsImapService::DisplayMessage(const char* aMessageURI,
imapUrl->SetFetchPartsOnDemand(PR_TRUE);
msgurl->SetAddToMemoryCache(PR_FALSE);
}
PRBool msgLoadingFromCache = PR_FALSE;
rv = FetchMessage(imapUrl, nsIImapUrl::nsImapMsgFetch, folder, imapMessageSink,
aURL, aDisplayConsumer, msgKey, PR_TRUE);
if (NS_SUCCEEDED(rv))
{
imapUrl->GetMsgLoadingFromCache(&msgLoadingFromCache);
// we're reading this msg from the cache - mark it read on the server.
if (msgLoadingFromCache)
{
nsCOMPtr <nsIMsgDatabase> database;
if (NS_SUCCEEDED(folder->GetMsgDatabase(nsnull, getter_AddRefs(database))) && database)
{
PRBool msgRead = PR_TRUE;
database->IsRead(key, &msgRead);
if (!msgRead)
{
nsCOMPtr<nsISupportsArray> messages;
rv = NS_NewISupportsArray(getter_AddRefs(messages));
if (NS_FAILED(rv))
return rv;
NS_WITH_SERVICE(nsIRDFService, rdfService, kRDFServiceCID, &rv);
if (NS_FAILED(rv)) return rv;
nsCOMPtr<nsIRDFResource> msgResource;
nsCOMPtr<nsIMessage> message;
rv = rdfService->GetResource(aMessageURI,
getter_AddRefs(msgResource));
if(NS_SUCCEEDED(rv))
{
rv = msgResource->QueryInterface(NS_GET_IID(nsIMessage),
getter_AddRefs(message));
if (NS_SUCCEEDED(rv) && message)
{
nsCOMPtr<nsISupports> msgSupport(do_QueryInterface(message, &rv));
if (msgSupport)
{
messages->AppendElement(msgSupport);
folder->MarkMessagesRead(messages, PR_TRUE);
}
}
}
}
}
}
}
}
}
return rv;
@ -1971,7 +2014,7 @@ nsImapService::CreateFolder(nsIEventQueue* eventQueue, nsIMsgFolder* parent,
nsIUrlListener* urlListener, nsIURI** url)
{
NS_ASSERTION(eventQueue && parent && newFolderName && *newFolderName,
"Oops ... [RenameLeaf] null pointers");
"Oops ... [CreateFolder] null pointers");
if (!eventQueue || !parent || !newFolderName || !*newFolderName)
return NS_ERROR_NULL_POINTER;
@ -2013,6 +2056,55 @@ nsImapService::CreateFolder(nsIEventQueue* eventQueue, nsIMsgFolder* parent,
return rv;
}
NS_IMETHODIMP
nsImapService::EnsureFolderExists(nsIEventQueue* eventQueue, nsIMsgFolder* parent,
const PRUnichar* newFolderName,
nsIUrlListener* urlListener, nsIURI** url)
{
NS_ASSERTION(eventQueue && parent && newFolderName && *newFolderName,
"Oops ... [EnsureExists] null pointers");
if (!eventQueue || !parent || !newFolderName || !*newFolderName)
return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsIImapUrl> imapUrl;
nsCAutoString urlSpec;
nsresult rv;
PRUnichar hierarchySeparator = GetHierarchyDelimiter(parent);
rv = CreateStartOfImapUrl(nsnull, getter_AddRefs(imapUrl), parent, urlListener, urlSpec, hierarchySeparator);
if (NS_SUCCEEDED(rv) && imapUrl)
{
rv = SetImapUrlSink(parent, imapUrl);
if (NS_SUCCEEDED(rv))
{
nsCOMPtr<nsIURI> uri = do_QueryInterface(imapUrl);
nsXPIDLCString folderName;
GetFolderName(parent, getter_Copies(folderName));
urlSpec.Append("/ensureExists>");
urlSpec.AppendWithConversion(hierarchySeparator);
if ((const char *) folderName && nsCRT::strlen(folderName) > 0)
{
urlSpec.Append((const char *) folderName);
urlSpec.AppendWithConversion(hierarchySeparator);
}
char *utfNewName = CreateUtf7ConvertedStringFromUnicode( newFolderName);
char *escapedFolderName = nsEscape(utfNewName, url_Path);
urlSpec.Append(escapedFolderName);
nsCRT::free(escapedFolderName);
nsCRT::free(utfNewName);
rv = uri->SetSpec((char*) urlSpec.GetBuffer());
if (NS_SUCCEEDED(rv))
rv = GetImapConnectionAndLoadUrl(eventQueue, imapUrl,
nsnull,
url);
} // if (NS_SUCCEEDED(rv))
} // if (NS_SUCCEEDED(rv) && imapUrl)
return rv;
}
NS_IMETHODIMP
nsImapService::ListFolder(nsIEventQueue* aClientEventQueue,
nsIMsgFolder* aImapMailFolder,

Просмотреть файл

@ -66,6 +66,7 @@ nsImapUrl::nsImapUrl()
m_mimePartSelectorDetected = PR_FALSE;
m_allowContentChange = PR_TRUE; // assume we can do MPOD.
m_fetchPartsOnDemand = PR_FALSE; // but assume we're not doing it :-)
m_msgLoadingFromCache = PR_FALSE;
m_contentModified = IMAP_CONTENT_NOT_MODIFIED;
m_validUrl = PR_TRUE; // assume the best.
m_flags = 0;
@ -542,6 +543,11 @@ void nsImapUrl::ParseImapPart(char *imapPartOfUrl)
m_imapAction = nsImapCreateFolder;
ParseFolderPath(&m_sourceCanonicalFolderPathSubString);
}
else if (!nsCRT::strcasecmp(m_urlidSubString, "ensureExists"))
{
m_imapAction = nsImapEnsureExistsFolder;
ParseFolderPath(&m_sourceCanonicalFolderPathSubString);
}
else if (!nsCRT::strcasecmp(m_urlidSubString, "discoverchildren"))
{
m_imapAction = nsImapDiscoverChildrenUrl;
@ -1067,6 +1073,7 @@ NS_IMETHODIMP nsImapUrl::GetUri(char** aURI)
NS_IMPL_GETSET(nsImapUrl, AddDummyEnvelope, PRBool, m_addDummyEnvelope);
NS_IMPL_GETSET(nsImapUrl, CanonicalLineEnding, PRBool, m_canonicalLineEnding);
NS_IMPL_GETSET(nsImapUrl, MsgLoadingFromCache, PRBool, m_msgLoadingFromCache);
NS_IMETHODIMP nsImapUrl::SetMessageFile(nsIFileSpec * aFileSpec)
{

Просмотреть файл

@ -93,6 +93,7 @@ protected:
PRBool m_mimePartSelectorDetected;
PRBool m_allowContentChange; // if PR_FALSE, we can't use Mime parts on demand
PRBool m_fetchPartsOnDemand; // if PR_TRUE, we should fetch leave parts on server.
PRBool m_msgLoadingFromCache; // if PR_TRUE, we might need to mark read on server
nsImapContentModifiedType m_contentModified;
PRInt32 m_discoveryDepth;

Просмотреть файл

@ -911,6 +911,52 @@ nsresult nsMsgLocalMailFolder::CreateDirectoryForFolder(nsFileSpec &path)
return rv;
}
NS_IMETHODIMP nsMsgLocalMailFolder::CreateStorageIfMissing(nsIUrlListener* urlListener)
{
nsresult status = NS_OK;
nsCOMPtr <nsIFolder> parent;
GetParent(getter_AddRefs(parent));
nsCOMPtr <nsIMsgFolder> msgParent;
if (parent)
msgParent = do_QueryInterface(parent);
// parent is probably not set because *this* was probably created by rdf
// and not by folder discovery. So, we have to compute the parent.
if (!msgParent)
{
nsCAutoString folderName = mURI;
nsCAutoString uri;
PRInt32 leafPos = folderName.RFindChar('/');
nsCAutoString parentName(folderName);
if (leafPos > 0)
{
// If there is a hierarchy, there is a parent.
// Don't strip off slash if it's the first character
parentName.Truncate(leafPos);
// get the corresponding RDF resource
// RDF will create the folder resource if it doesn't already exist
NS_WITH_SERVICE(nsIRDFService, rdf, kRDFServiceCID, &status);
if (NS_FAILED(status)) return status;
nsCOMPtr<nsIRDFResource> resource;
status = rdf->GetResource(parentName, getter_AddRefs(resource));
if (NS_FAILED(status)) return status;
msgParent = do_QueryInterface(resource, &status);
}
}
if (msgParent)
{
nsXPIDLString folderName;
GetName(getter_Copies(folderName));
status = msgParent->CreateSubfolder(folderName);
}
return status;
}
nsresult
nsMsgLocalMailFolder::CreateSubfolder(const PRUnichar *folderName)
{

Просмотреть файл

@ -108,6 +108,7 @@ public:
NS_IMETHOD EmptyTrash(nsIMsgWindow *msgWindow, nsIUrlListener *aListener);
NS_IMETHOD Delete ();
NS_IMETHOD DeleteSubFolders(nsISupportsArray *folders, nsIMsgWindow *msgWindow);
NS_IMETHOD CreateStorageIfMissing(nsIUrlListener* urlListener);
NS_IMETHOD Rename (const PRUnichar *aNewName);
NS_IMETHOD Adopt(nsIMsgFolder *srcFolder, PRUint32 *outPos);