fixed bug 21742 -- [FEATURE] Save all attachments; r=mscott

This commit is contained in:
jefft%netscape.com 2000-04-13 22:19:48 +00:00
Родитель 98632e7323
Коммит 8603e2c5a2
14 изменённых файлов: 389 добавлений и 103 удалений

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

@ -98,6 +98,7 @@ interface nsIMessenger : nsISupports {
void SetDocumentCharset(in wstring characterSet);
void saveAs(in string url, in boolean asFile, in nsIMsgIdentity identity, in nsIMsgWindow aMsgWindow);
void openAttachment(in string url, in string displayName, in string messageUri);
void saveAllAttachments(in unsigned long count, [array, size_is(count)] in string urlArray, [array, size_is(count)] in string displayNameArray, [array, size_is(count)] in string messageUriArray);
void find();
void findAgain();
};

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

@ -40,6 +40,11 @@ var currentHeaderData;
var gNumAddressesToShow = 3;
var gShowUserAgent = false;
// attachments array
var attachmentUrlArray = new Array();
var attachmentDisplayNameArray = new Array();
var attachmentMessageUriArray = new Array();
var msgHeaderParser = Components.classes[msgHeaderParserProgID].getService(Components.interfaces.nsIMsgHeaderParser);
var abAddressCollector = Components.classes[abAddressCollectorProgID].getService(Components.interfaces.nsIAbAddressCollecter);
@ -185,6 +190,18 @@ var messageHeaderSink = {
}
AddAttachmentToMenu(displayName, commandString);
var count = attachmentUrlArray.length;
// dump ("** attachment count**" + count + "\n");
if (count < 0) count = 0;
attachmentUrlArray[count] = url;
attachmentDisplayNameArray[count] = escape(displayName);
attachmentMessageUriArray[count] = uri;
},
onEndAllAttachments: function()
{
AddSaveAllAttachmentsMenu();
}
};
@ -226,25 +243,21 @@ function OpenAttachURL(url, displayName, messageUri)
function AddAttachmentToMenu(name, oncommand)
{
var popup = document.getElementById("attachmentPopup");
if ( popup && (popup.childNodes.length >= 2) )
if (popup)
{
var item = document.createElement('menuitem');
if ( item )
{
// popup.removeAttribute('menugenerated');
var child = popup.childNodes[popup.childNodes.length - 2];
var bigMenu = document.getElementById('attachmentMenu');
popup.insertBefore(item, child);
popup.appendChild(item);
item.setAttribute('value', name);
item.setAttribute('oncommand', oncommand);
}
var button = document.getElementById("attachmentButton");
if (button)
button.setAttribute("value", popup.childNodes.length - 2);
button.setAttribute("value", popup.childNodes.length);
}
var attachBox = document.getElementById("attachmentBox");
@ -252,19 +265,56 @@ function AddAttachmentToMenu(name, oncommand)
attachBox.removeAttribute("hide");
}
function SaveAllAttachments()
{
try
{
messenger.saveAllAttachments(attachmentUrlArray.length,
attachmentUrlArray,
attachmentDisplayNameArray,
attachmentMessageUriArray);
}
catch (ex)
{
dump ("** failed to save all attachments ** \n");
}
}
function AddSaveAllAttachmentsMenu()
{
var popup = document.getElementById("attachmentPopup");
if (popup && popup.childNodes.length > 1)
{
var separator = document.createElement('menuseparator');
var item = document.createElement('menuitem');
if (separator && item)
{
popup.appendChild(separator);
popup.appendChild(item);
item.setAttribute('value', "Save All...");
item.setAttribute('oncommand', "SaveAllAttachments()");
}
}
}
function ClearAttachmentMenu()
{
var popup = document.getElementById("attachmentPopup");
if ( popup )
{
while ( popup.childNodes.length > 2 )
while ( popup.childNodes.length )
popup.removeChild(popup.childNodes[0]);
}
var attachBox = document.getElementById("attachmentBox");
if (attachBox)
attachBox.setAttribute("hide", "true");
// reset attachments name array
attachmentUrlArray.length = 0;
attachmentDisplayNameArray.length = 0;
attachmentMessageUriArray.length = 0;
}
// Assumes that all the child nodes of the parent div need removed..leaving

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

@ -71,8 +71,6 @@ Rights Reserved.
<menu id="attachmentMenu" class="attachment-menu">
<titledbutton id="attachmentButton" class="push" value="1" align="right"/>
<menupopup id="attachmentPopup" popupanchor="bottomright" popupalign="topright">
<menuseparator/>
<menuitem value=".Save All..." disabled="true" oncommand="SaveAllAttachmentsDialog()"/>
</menupopup>
</menu>
<spring flex="1"/>

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

@ -195,6 +195,8 @@ ConvertBufToPlainText(nsString &aConBuf)
// jefft - this is a rather obscured class serves for Save Message As File,
// Save Message As Template, and Save Attachment to a file
//
class nsSaveAllAttachmentsState;
class nsSaveAsListener : public nsIUrlListener,
public nsIMsgCopyServiceListener,
public nsIStreamListener
@ -216,6 +218,7 @@ public:
nsCOMPtr<nsIChannel> m_channel;
nsXPIDLCString m_templateUri;
nsMessenger *m_messenger; // not ref counted
nsSaveAllAttachmentsState *m_saveAllAttachmentsState;
// rhp: For character set handling
PRBool m_doCharsetConversion;
@ -224,6 +227,23 @@ public:
nsString m_msgBuffer;
};
class nsSaveAllAttachmentsState
{
public:
nsSaveAllAttachmentsState(PRUint32 count, const char **urlArray,
const char **displayNameArray,
const char **messageUriArray,
const char *directoryName);
virtual ~nsSaveAllAttachmentsState();
PRUint32 m_count;
PRUint32 m_curIndex;
char* m_directoryName;
char** m_urlArray;
char** m_displayNameArray;
char** m_messageUriArray;
};
//
// nsMessenger
//
@ -453,6 +473,106 @@ nsMessenger::OpenURL(const char * url)
return NS_OK;
}
nsresult
nsMessenger::SaveAttachment(nsIFileSpec * fileSpec,
const char * unescapedUrl,
const char * messageUri,
void *closure)
{
nsIMsgMessageService * messageService = nsnull;
nsSaveAsListener *aListener = nsnull;
nsSaveAllAttachmentsState *saveState= (nsSaveAllAttachmentsState*) closure;
nsAutoString from, to;
nsCOMPtr<nsISupports> channelSupport;
nsCOMPtr<nsIStreamListener> convertedListener;
nsAutoString urlString;
char *urlCString = nsnull;
nsCOMPtr<nsIURI> aURL;
PRBool canFetchMimeParts = PR_FALSE;
nsCAutoString fullMessageUri = messageUri;
nsresult rv = NS_OK;
fileSpec->MakeUnique();
NS_WITH_SERVICE(nsIStreamConverterService,
streamConverterService,
kIStreamConverterServiceCID, &rv);
if (NS_FAILED(rv)) goto done;
aListener = new nsSaveAsListener(fileSpec, this);
if (!aListener)
{
rv = NS_ERROR_OUT_OF_MEMORY;
goto done;
}
NS_ADDREF(aListener);
if (saveState)
aListener->m_saveAllAttachmentsState = saveState;
urlString = unescapedUrl;
urlString.ReplaceSubstring("/;section", "?section");
urlCString = urlString.ToNewCString();
rv = CreateStartupUrl(urlCString, getter_AddRefs(aURL));
nsCRT::free(urlCString);
if (NS_FAILED(rv)) goto done;
rv = GetMessageServiceFromURI(messageUri, &messageService);
if (NS_FAILED(rv)) goto done;
messageService->GetCanFetchMimeParts(&canFetchMimeParts);
if (canFetchMimeParts)
{
PRInt32 sectionPos = urlString.Find("?section");
nsString mimePart;
urlString.Right(mimePart, urlString.Length() - sectionPos);
fullMessageUri.Append(mimePart);
messageUri = fullMessageUri.GetBuffer();
}
{
aListener->m_channel = null_nsCOMPtr();
rv = NS_NewInputStreamChannel(getter_AddRefs(aListener->m_channel),
aURL,
nsnull, // inputStream
nsnull, // contentType
-1);
if (NS_FAILED(rv)) goto done;
from = MESSAGE_RFC822;
to = "text/xul";
channelSupport = do_QueryInterface(aListener->m_channel);
rv = streamConverterService->AsyncConvertData(
from.GetUnicode(), to.GetUnicode(), aListener,
channelSupport, getter_AddRefs(convertedListener));
if (NS_FAILED(rv)) goto done;
if (canFetchMimeParts)
rv = messageService->OpenAttachment(aURL, messageUri, convertedListener,
mMsgWindow, nsnull,nsnull);
else
rv = messageService->DisplayMessage(messageUri,
convertedListener,mMsgWindow,
nsnull, nsnull);
}
done:
if (messageService)
ReleaseMessageServiceFromURI(unescapedUrl, messageService);
if (NS_FAILED(rv))
{
NS_IF_RELEASE(aListener);
Alert("saveAttachmentFailed");
}
return rv;
}
NS_IMETHODIMP
nsMessenger::OpenAttachment(const char * url, const char * displayName,
@ -461,27 +581,10 @@ nsMessenger::OpenAttachment(const char * url, const char * displayName,
// *** for now OpenAttachment is really a SaveAttachment
nsresult rv = NS_ERROR_OUT_OF_MEMORY;
char *unescapedUrl = nsnull;
nsIMsgMessageService * messageService = nsnull;
nsSaveAsListener *aListener = nsnull;
nsAutoString from, to;
nsCOMPtr<nsIFileSpec> aSpec;
nsCOMPtr<nsIFileSpecWithUI> fileSpec;
nsCOMPtr<nsISupports> channelSupport;
nsCOMPtr<nsIStreamListener> convertedListener;
nsAutoString urlString;
char *urlCString = nsnull;
char * unescapedDisplayName = nsnull;
nsCOMPtr<nsIURI> aURL;
nsAutoString tempStr;
PRBool canFetchMimeParts = PR_FALSE;
nsCAutoString fullMessageUri = messageUri;
NS_WITH_SERVICE(nsIStreamConverterService,
streamConverterService,
kIStreamConverterServiceCID, &rv);
if (NS_FAILED(rv)) goto done;
rv = NS_ERROR_OUT_OF_MEMORY;
if (!url) goto done;
@ -521,7 +624,7 @@ nsMessenger::OpenAttachment(const char * url, const char * displayName,
nsIFileSpecWithUI::eAllFiles);
nsCRT::free(unescapedDisplayName);
if (rv = NS_ERROR_ABORT)
if (rv == NS_ERROR_ABORT)
{
rv = NS_OK;
goto done;
@ -531,84 +634,73 @@ nsMessenger::OpenAttachment(const char * url, const char * displayName,
aSpec = do_QueryInterface(fileSpec, &rv);
if (NS_FAILED(rv)) goto done;
aListener = new nsSaveAsListener(aSpec, this);
if (!aListener)
{
rv = NS_ERROR_OUT_OF_MEMORY;
goto done;
}
NS_ADDREF(aListener);
urlString = unescapedUrl;
urlString.ReplaceSubstring("/;section", "?section");
urlCString = urlString.ToNewCString();
rv = CreateStartupUrl(urlCString, getter_AddRefs(aURL));
nsCRT::free(urlCString);
if (NS_FAILED(rv)) goto done;
rv = GetMessageServiceFromURI(messageUri, &messageService);
if (NS_FAILED(rv)) goto done;
messageService->GetCanFetchMimeParts(&canFetchMimeParts);
if (canFetchMimeParts)
{
PRInt32 sectionPos = urlString.Find("?section");
nsString mimePart;
urlString.Right(mimePart, urlString.Length() - sectionPos);
fullMessageUri.Append(mimePart);
// nsCOMPtr <nsIStreamListener> streamListener = do_QueryInterface((nsIStreamListener *) aListener);
// nsCOMPtr <nsISupports> supportsListener = streamListener;
messageUri = fullMessageUri.GetBuffer();
// rv = messageService->DisplayMessage(fullMessageUri.GetBuffer(),
// supportsListener, mMsgWindow,
// nsnull, nsnull);
}
{
aListener->m_channel = null_nsCOMPtr();
rv = NS_NewInputStreamChannel(getter_AddRefs(aListener->m_channel),
aURL,
nsnull, // inputStream
nsnull, // contentType
-1);
if (NS_FAILED(rv)) goto done;
from = MESSAGE_RFC822;
to = "text/xul";
channelSupport = do_QueryInterface(aListener->m_channel);
rv = streamConverterService->AsyncConvertData(
from.GetUnicode(), to.GetUnicode(), aListener,
channelSupport, getter_AddRefs(convertedListener));
if (NS_FAILED(rv)) goto done;
if (canFetchMimeParts)
rv = messageService->OpenAttachment(aURL, messageUri, convertedListener, mMsgWindow, nsnull,nsnull);
else
rv = messageService->DisplayMessage(messageUri,
convertedListener,mMsgWindow,
nsnull, nsnull);
}
rv = SaveAttachment(aSpec, unescapedUrl, messageUri, nsnull);
done:
if (messageService)
ReleaseMessageServiceFromURI(unescapedUrl, messageService);
PR_FREEIF(unescapedUrl);
return rv;
}
if (NS_FAILED(rv))
NS_IMETHODIMP
nsMessenger::SaveAllAttachments(PRUint32 count, const char **urlArray,
const char **displayNameArray,
const char **messageUriArray)
{
nsresult rv = NS_ERROR_OUT_OF_MEMORY;
nsCOMPtr<nsIFileSpecWithUI> uFileSpec;
nsCOMPtr<nsIFileSpec> fileSpec;
nsFileSpec aFileSpec;
nsXPIDLCString dirName;
char *unescapedUrl = nsnull, *unescapedName = nsnull, *tempCStr = nsnull;
nsAutoString tempStr;
nsSaveAllAttachmentsState *saveState = nsnull;
uFileSpec = getter_AddRefs(NS_CreateFileSpecWithUI());
if (!uFileSpec) goto done;
rv = uFileSpec->ChooseDirectory("Save All Attachments",
getter_Copies(dirName));
if (rv == NS_ERROR_ABORT)
{
NS_IF_RELEASE(aListener);
Alert("saveAttachmentFailed");
rv = NS_OK;
goto done;
}
return rv;
if (NS_FAILED(rv)) goto done;
rv = NS_NewFileSpec(getter_AddRefs(fileSpec));
if (NS_FAILED(rv)) goto done;
saveState = new nsSaveAllAttachmentsState(count, urlArray,
displayNameArray,
messageUriArray,
(const char*) dirName);
{
nsFileURL fileUrl((const char *) dirName);
nsFilePath dirPath(fileUrl);
unescapedUrl = PL_strdup(urlArray[0]);
nsUnescape(unescapedUrl);
unescapedName = PL_strdup(displayNameArray[0]);
nsUnescape(unescapedName);
rv = ConvertToUnicode("UTF-8", unescapedName, tempStr);
if (NS_FAILED(rv)) goto done;
rv = ConvertFromUnicode(nsMsgI18NFileSystemCharset(), tempStr,
&tempCStr);
if (NS_FAILED(rv)) goto done;
PR_FREEIF(unescapedName);
unescapedName = tempCStr;
aFileSpec = dirPath;
aFileSpec += unescapedName;
fileSpec->SetFromFileSpec(aFileSpec);
rv = SaveAttachment(fileSpec, unescapedUrl, messageUriArray[0],
(void *)saveState);
if (NS_FAILED(rv)) goto done;
}
done:
PR_FREEIF (unescapedUrl);
PR_FREEIF (unescapedName);
return rv;
}
@ -1519,6 +1611,7 @@ nsSaveAsListener::nsSaveAsListener(nsIFileSpec* aSpec, nsMessenger *aMessenger)
m_charset = "";
m_outputFormat = "";
m_msgBuffer = "";
m_saveAllAttachmentsState = nsnull;
}
nsSaveAsListener::~nsSaveAsListener()
@ -1687,6 +1780,56 @@ nsSaveAsListener::OnStopRequest(nsIChannel* aChannel, nsISupports* aSupport,
m_outputStream = null_nsCOMPtr();
}
if (m_saveAllAttachmentsState)
{
m_saveAllAttachmentsState->m_curIndex++;
if (m_saveAllAttachmentsState->m_curIndex <
m_saveAllAttachmentsState->m_count)
{
char * unescapedUrl = nsnull, * unescapedName = nsnull,
* tempCStr = nsnull;
nsAutoString tempStr;
nsSaveAllAttachmentsState *state = m_saveAllAttachmentsState;
PRUint32 i = state->m_curIndex;
nsFileURL fileUrl(state->m_directoryName);
nsFilePath dirPath(fileUrl);
nsCOMPtr<nsIFileSpec> fileSpec;
nsFileSpec aFileSpec;
rv = NS_NewFileSpec(getter_AddRefs(fileSpec));
if (NS_FAILED(rv)) goto done;
unescapedUrl = PL_strdup(state->m_urlArray[i]);
nsUnescape(unescapedUrl);
unescapedName = PL_strdup(state->m_displayNameArray[i]);
nsUnescape(unescapedName);
rv = ConvertToUnicode("UTF-8", unescapedName, tempStr);
if (NS_FAILED(rv)) goto done;
rv = ConvertFromUnicode(nsMsgI18NFileSystemCharset(), tempStr,
&tempCStr);
if (NS_FAILED(rv)) goto done;
PR_FREEIF(unescapedName);
unescapedName = tempCStr;
aFileSpec = dirPath;
aFileSpec += unescapedName;
fileSpec->SetFromFileSpec(aFileSpec);
rv = m_messenger->SaveAttachment(fileSpec, unescapedUrl,
state->m_messageUriArray[i],
(void *)state);
done:
if (NS_FAILED(rv))
{
delete state;
m_saveAllAttachmentsState = nsnull;
}
PR_FREEIF(unescapedUrl);
PR_FREEIF(unescapedName);
}
else
{
delete m_saveAllAttachmentsState;
m_saveAllAttachmentsState = nsnull;
}
}
Release(); // all done kill ourself
return NS_OK;
}
@ -1775,3 +1918,42 @@ nsMessenger::GetString(const PRUnichar *aStringName)
else
return nsCRT::strdup(aStringName);
}
nsSaveAllAttachmentsState::nsSaveAllAttachmentsState(PRUint32 count,
const char **urlArray,
const char **nameArray,
const char **uriArray,
const char *dirName)
{
PRUint32 i;
NS_ASSERTION(count && urlArray && nameArray && uriArray && dirName,
"fatal - invalid parameters\n");
m_count = count;
m_curIndex = 0;
m_urlArray = new char*[count];
m_displayNameArray = new char*[count];
m_messageUriArray = new char*[count];
for (i = 0; i < count; i++)
{
m_urlArray[i] = nsCRT::strdup(urlArray[i]);
m_displayNameArray[i] = nsCRT::strdup(nameArray[i]);
m_messageUriArray[i] = nsCRT::strdup(uriArray[i]);
}
m_directoryName = nsCRT::strdup(dirName);
}
nsSaveAllAttachmentsState::~nsSaveAllAttachmentsState()
{
PRUint32 i;
for (i = 0; i < m_count; i++)
{
nsCRT::free(m_urlArray[i]);
nsCRT::free(m_displayNameArray[i]);
nsCRT::free(m_messageUriArray[i]);
}
delete m_urlArray;
delete m_displayNameArray;
delete m_messageUriArray;
nsCRT::free(m_directoryName);
}

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

@ -46,6 +46,8 @@ public:
NS_DECL_NSIMESSENGER
nsresult Alert(const char * stringName);
nsresult SaveAttachment(nsIFileSpec *fileSpec, const char* unescapedUrl,
const char* messageUri, void *closure);
protected:
nsresult DoDelete(nsIRDFCompositeDataSource* db, nsISupportsArray *srcArray, nsISupportsArray *deletedArray);

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

@ -818,7 +818,7 @@ nsImapProtocol::PseudoInterruptMsgLoad(nsIImapUrl *aImapUrl, PRBool *interrupted
nsAutoCMonitor(this);
if (m_runningUrl)
if (m_runningUrl && !TestFlag(IMAP_CLEAN_UP_URL_STATE))
{
nsImapAction imapAction;
m_runningUrl->GetImapAction(&imapAction);
@ -1148,7 +1148,9 @@ PRBool nsImapProtocol::ProcessCurrentURL()
rv = m_channelListener->OnStopRequest(m_mockChannel, m_channelContext, NS_OK, nsnull);
m_lastActiveTime = PR_Now(); // ** jt -- is this the best place for time stamp
PseudoInterrupt(PR_FALSE); // clear this, because we must be done interrupting?
PseudoInterrupt(PR_FALSE); // clear this, because we must be done
// interrupting?
SetFlag(IMAP_CLEAN_UP_URL_STATE);
if (NS_SUCCEEDED(rv) && GetConnectionStatus() >= 0 && GetServerStateParser().LastCommandSuccessful()
&& m_imapMiscellaneousSink && m_runningUrl)
{
@ -1168,6 +1170,8 @@ PRBool nsImapProtocol::ProcessCurrentURL()
ReleaseUrlState();
ResetProgressInfo();
m_urlInProgress = PR_FALSE;
ClearFlag(IMAP_CLEAN_UP_URL_STATE);
// now try queued urls, now that we've released this connection.
if (m_imapServerSink && GetConnectionStatus() >= 0)
{

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

@ -74,6 +74,8 @@ class nsIMsgIncomingServer;
#define IMAP_CONNECTION_IS_OPEN 0x00000004 /* is the connection currently open? */
#define IMAP_WAITING_FOR_DATA 0x00000008
#define IMAP_CLEAN_UP_URL_STATE 0x00000010 // processing clean up url state
class nsImapProtocol : public nsIImapProtocol, public nsIRunnable
{
public:

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

@ -349,6 +349,12 @@ nsMimeBaseEmitter::EndAttachment()
return NS_OK;
}
nsresult
nsMimeBaseEmitter::EndAllAttachments()
{
return NS_OK;
}
NS_IMETHODIMP
nsMimeBaseEmitter::AddAttachmentField(const char *field, const char *value)
{

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

@ -356,6 +356,17 @@ nsMimeHtmlDisplayEmitter::EndAttachment()
return NS_OK;
}
nsresult
nsMimeHtmlDisplayEmitter::EndAllAttachments()
{
nsresult rv = NS_OK;
nsCOMPtr<nsIMsgHeaderSink> headerSink;
rv = GetHeaderSink(getter_AddRefs(headerSink));
if (headerSink)
headerSink->OnEndAllAttachments();
return rv;
}
nsresult
nsMimeHtmlDisplayEmitter::WriteBody(const char *buf, PRUint32 size, PRUint32 *amountWritten)
{

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

@ -49,6 +49,7 @@ public:
PRBool aNotDownloaded);
NS_IMETHOD AddAttachmentField(const char *field, const char *value);
NS_IMETHOD EndAttachment();
NS_IMETHOD EndAllAttachments();
// Body handling routines
NS_IMETHOD WriteBody(const char *buf, PRUint32 size, PRUint32 *amountWritten);

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

@ -65,6 +65,8 @@ interface nsIMimeEmitter : nsISupports{
void AddAttachmentField([const] in string field, [const] in string value);
void EndAttachment();
void EndAllAttachments();
// Body handling routines
void StartBody(in PRBool bodyOnly, [const] in string msgID, [const] in string outCharset);
void WriteBody([const] in string buf, in PRUint32 size, out PRUint32 amountWritten);

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

@ -51,5 +51,7 @@ interface nsIMsgHeaderSink : nsISupports{
// make a sandwhich around header processing.....
void onStartHeaders();
void onEndHeaders();
void handleAttachment(in string url, in wstring displayName, in string uri, in boolean aNotDownloaded);
void handleAttachment(in string url, in wstring displayName, in string
uri, in boolean aNotDownloaded);
void onEndAllAttachments();
};

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

@ -510,6 +510,7 @@ NotifyEmittersOfAttachmentList(MimeDisplayOptions *opt,
++i;
++tmp;
}
mimeEmitterEndAllAttachments(opt);
}
// Utility to create a nsIURI object...
@ -1518,6 +1519,29 @@ mimeEmitterEndAttachment(MimeDisplayOptions *opt)
return NS_ERROR_FAILURE;
}
extern "C" nsresult
mimeEmitterEndAllAttachments(MimeDisplayOptions *opt)
{
// Check for draft processing...
if (NoEmitterProcessing(opt->format_out))
return NS_OK;
mime_stream_data *msd = GetMSD(opt);
if (!msd)
return NS_ERROR_FAILURE;
if (msd->output_emitter)
{
nsIMimeEmitter *emitter = (nsIMimeEmitter *)msd->output_emitter;
if (emitter)
return emitter->EndAllAttachments();
else
return NS_OK;
}
return NS_ERROR_FAILURE;
}
extern "C" nsresult
mimeEmitterStartBody(MimeDisplayOptions *opt, PRBool bodyOnly, const char *msgID, const char *outCharset)
{

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

@ -141,6 +141,7 @@ extern "C" nsresult mimeEmitterAddHeaderField(MimeDisplayOptions *opt, const
extern "C" nsresult mimeEmitterStartAttachment(MimeDisplayOptions *opt, const char *name, const char *contentType, const char *url,
PRBool aNotDownloaded);
extern "C" nsresult mimeEmitterEndAttachment(MimeDisplayOptions *opt);
extern "C" nsresult mimeEmitterEndAllAttachments(MimeDisplayOptions *opt);
extern "C" nsresult mimeEmitterStartBody(MimeDisplayOptions *opt, PRBool bodyOnly, const char *msgID, const char *outCharset);
extern "C" nsresult mimeEmitterEndBody(MimeDisplayOptions *opt);
extern "C" nsresult mimeEmitterEndHeader(MimeDisplayOptions *opt);