зеркало из https://github.com/mozilla/gecko-dev.git
Bug #134492 --> when printing a msg with attachments, also print a list of the attachments.
Thanks to Kevin Teuscher for helping to drive this patch. r=mscott sr=bienvenu/brendan a=asa
This commit is contained in:
Родитель
3aa59b9b92
Коммит
59b960258e
|
@ -68,6 +68,8 @@ static NS_DEFINE_CID(kDateTimeFormatCID, NS_DATETIMEFORMAT_CID);
|
||||||
*/
|
*/
|
||||||
nsMimeHtmlDisplayEmitter::nsMimeHtmlDisplayEmitter() : nsMimeBaseEmitter()
|
nsMimeHtmlDisplayEmitter::nsMimeHtmlDisplayEmitter() : nsMimeBaseEmitter()
|
||||||
{
|
{
|
||||||
|
mFirst = PR_TRUE;
|
||||||
|
mSkipAttachment = PR_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsMimeHtmlDisplayEmitter::~nsMimeHtmlDisplayEmitter(void)
|
nsMimeHtmlDisplayEmitter::~nsMimeHtmlDisplayEmitter(void)
|
||||||
|
@ -346,65 +348,171 @@ nsMimeHtmlDisplayEmitter::EndHeader()
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsMimeHtmlDisplayEmitter::StartAttachment(const char *name, const char *contentType, const char *url,
|
nsMimeHtmlDisplayEmitter::StartAttachment(const char *name,
|
||||||
|
const char *contentType,
|
||||||
|
const char *url,
|
||||||
PRBool aNotDownloaded)
|
PRBool aNotDownloaded)
|
||||||
{
|
{
|
||||||
nsresult rv = NS_OK;
|
nsresult rv = NS_OK;
|
||||||
nsCOMPtr<nsIMsgHeaderSink> headerSink;
|
nsCOMPtr<nsIMsgHeaderSink> headerSink;
|
||||||
rv = GetHeaderSink(getter_AddRefs(headerSink));
|
rv = GetHeaderSink(getter_AddRefs(headerSink));
|
||||||
|
|
||||||
if (NS_FAILED(rv) || !headerSink)
|
if (NS_SUCCEEDED(rv) && headerSink)
|
||||||
return NS_OK; //If we don't need or cannot broadcast attachment info, just ignore it and return NS_OK
|
|
||||||
|
|
||||||
char * escapedUrl = nsEscape(url, url_Path);
|
|
||||||
nsXPIDLCString uriString;
|
|
||||||
|
|
||||||
nsCOMPtr<nsIMsgMessageUrl> msgurl (do_QueryInterface(mURL, &rv));
|
|
||||||
if (NS_SUCCEEDED(rv))
|
|
||||||
{
|
{
|
||||||
// HACK: news urls require us to use the originalSpec. everyone else uses GetURI
|
char * escapedUrl = nsEscape(url, url_Path);
|
||||||
// to get the RDF resource which describes the message.
|
nsXPIDLCString uriString;
|
||||||
nsCOMPtr<nsINntpUrl> nntpUrl (do_QueryInterface(mURL, &rv));
|
|
||||||
if (NS_SUCCEEDED(rv) && nntpUrl)
|
|
||||||
rv = msgurl->GetOriginalSpec(getter_Copies(uriString));
|
|
||||||
else
|
|
||||||
rv = msgurl->GetUri(getter_Copies(uriString));
|
|
||||||
}
|
|
||||||
|
|
||||||
// we need to convert the attachment name from UTF-8 to unicode before
|
nsCOMPtr<nsIMsgMessageUrl> msgurl (do_QueryInterface(mURL, &rv));
|
||||||
// we emit it...
|
if (NS_SUCCEEDED(rv))
|
||||||
nsXPIDLString unicodeHeaderValue;
|
{
|
||||||
|
// HACK: news urls require us to use the originalSpec. Everyone
|
||||||
|
// else uses GetURI to get the RDF resource which describes the message.
|
||||||
|
nsCOMPtr<nsINntpUrl> nntpUrl (do_QueryInterface(mURL, &rv));
|
||||||
|
if (NS_SUCCEEDED(rv) && nntpUrl)
|
||||||
|
rv = msgurl->GetOriginalSpec(getter_Copies(uriString));
|
||||||
|
else
|
||||||
|
rv = msgurl->GetUri(getter_Copies(uriString));
|
||||||
|
}
|
||||||
|
|
||||||
rv = NS_ERROR_FAILURE; // use failure to mean that we couldn't decode
|
// we need to convert the attachment name from UTF-8 to unicode before
|
||||||
if (mUnicodeConverter)
|
// we emit it...
|
||||||
rv = mUnicodeConverter->DecodeMimeHeader(name,
|
nsXPIDLString unicodeHeaderValue;
|
||||||
|
|
||||||
|
rv = NS_ERROR_FAILURE; // use failure to mean that we couldn't decode
|
||||||
|
if (mUnicodeConverter)
|
||||||
|
rv = mUnicodeConverter->DecodeMimeHeader(name,
|
||||||
getter_Copies(unicodeHeaderValue));
|
getter_Copies(unicodeHeaderValue));
|
||||||
|
|
||||||
if (NS_FAILED(rv))
|
if (NS_FAILED(rv))
|
||||||
{
|
{
|
||||||
unicodeHeaderValue.Assign(NS_ConvertUTF8toUCS2(name));
|
unicodeHeaderValue.Assign(NS_ConvertUTF8toUCS2(name));
|
||||||
|
|
||||||
// but it's not really a failure if we didn't have a converter in the first place
|
// but it's not really a failure if we didn't have a converter
|
||||||
if ( !mUnicodeConverter )
|
// in the first place
|
||||||
rv = NS_OK;
|
if ( !mUnicodeConverter )
|
||||||
|
rv = NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
headerSink->HandleAttachment(contentType, url /* was escapedUrl */,
|
||||||
|
unicodeHeaderValue, uriString,
|
||||||
|
aNotDownloaded);
|
||||||
|
|
||||||
|
nsCRT::free(escapedUrl);
|
||||||
|
mSkipAttachment = PR_TRUE;
|
||||||
|
}
|
||||||
|
else if (mFormat == nsMimeOutput::nsMimeMessagePrintOutput)
|
||||||
|
{
|
||||||
|
// then we need to deal with the attachments in the body by inserting
|
||||||
|
// them into a table..
|
||||||
|
rv = StartAttachmentInBody(name, contentType, url);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// If we don't need or cannot broadcast attachment info, just ignore it
|
||||||
|
mSkipAttachment = PR_TRUE;
|
||||||
|
rv = NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
headerSink->HandleAttachment(contentType, url /* was escapedUrl */, unicodeHeaderValue, uriString, aNotDownloaded);
|
|
||||||
|
|
||||||
nsCRT::free(escapedUrl);
|
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Attachment handling routines
|
||||||
|
// Ok, we are changing the way we handle these now...It used to be that we output
|
||||||
|
// HTML to make a clickable link, etc... but now, this should just be informational
|
||||||
|
// and only show up during printing
|
||||||
|
// XXX should they also show up during quoting?
|
||||||
|
nsresult
|
||||||
|
nsMimeHtmlDisplayEmitter::StartAttachmentInBody(const char *name, const char *contentType, const char *url)
|
||||||
|
{
|
||||||
|
mSkipAttachment = PR_FALSE;
|
||||||
|
|
||||||
|
if ( (contentType) &&
|
||||||
|
((!strcmp(contentType, APPLICATION_XPKCS7_MIME)) ||
|
||||||
|
(!strcmp(contentType, APPLICATION_XPKCS7_SIGNATURE)) ||
|
||||||
|
(!strcmp(contentType, TEXT_VCARD)))
|
||||||
|
) {
|
||||||
|
mSkipAttachment = PR_TRUE;
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mFirst)
|
||||||
|
UtilityWrite("<hr width=\"90%\" size=4>");
|
||||||
|
|
||||||
|
mFirst = PR_FALSE;
|
||||||
|
|
||||||
|
UtilityWrite("<center>");
|
||||||
|
UtilityWrite("<table border>");
|
||||||
|
UtilityWrite("<tr>");
|
||||||
|
UtilityWrite("<td>");
|
||||||
|
|
||||||
|
UtilityWrite("<div align=right class=\"headerdisplayname\" style=\"display:inline;\">");
|
||||||
|
|
||||||
|
UtilityWrite(name);
|
||||||
|
|
||||||
|
UtilityWrite("</div>");
|
||||||
|
|
||||||
|
UtilityWrite("</td>");
|
||||||
|
UtilityWrite("<td>");
|
||||||
|
UtilityWrite("<table border=0>");
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsMimeHtmlDisplayEmitter::AddAttachmentField(const char *field, const char *value)
|
nsMimeHtmlDisplayEmitter::AddAttachmentField(const char *field, const char *value)
|
||||||
{
|
{
|
||||||
|
if (mSkipAttachment || BroadCastHeadersAndAttachments())
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
|
// Don't let bad things happen
|
||||||
|
if ( !value || !*value )
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
|
// Don't output this ugly header...
|
||||||
|
if (!strcmp(field, HEADER_X_MOZILLA_PART_URL))
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
|
char *newValue = nsEscapeHTML(value);
|
||||||
|
|
||||||
|
UtilityWrite("<tr>");
|
||||||
|
|
||||||
|
UtilityWrite("<td>");
|
||||||
|
UtilityWrite("<div align=right class=\"headerdisplayname\" style=\"display:inline;\">");
|
||||||
|
|
||||||
|
UtilityWrite(field);
|
||||||
|
UtilityWrite(":");
|
||||||
|
UtilityWrite("</div>");
|
||||||
|
UtilityWrite("</td>");
|
||||||
|
UtilityWrite("<td>");
|
||||||
|
|
||||||
|
UtilityWrite(newValue);
|
||||||
|
|
||||||
|
UtilityWrite("</td>");
|
||||||
|
UtilityWrite("</tr>");
|
||||||
|
|
||||||
|
PR_Free(newValue);
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsMimeHtmlDisplayEmitter::EndAttachment()
|
nsMimeHtmlDisplayEmitter::EndAttachment()
|
||||||
{
|
{
|
||||||
|
if (mSkipAttachment)
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
|
mSkipAttachment = PR_FALSE; // reset it for next attachment round
|
||||||
|
|
||||||
|
if (BroadCastHeadersAndAttachments())
|
||||||
|
return NS_OK;
|
||||||
|
|
||||||
|
if (mFormat == nsMimeOutput::nsMimeMessagePrintOutput) {
|
||||||
|
UtilityWrite("</table>");
|
||||||
|
UtilityWrite("</td>");
|
||||||
|
UtilityWrite("</tr>");
|
||||||
|
|
||||||
|
UtilityWrite("</table>");
|
||||||
|
UtilityWrite("</center>");
|
||||||
|
UtilityWrite("<br>");
|
||||||
|
}
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -77,10 +77,14 @@ public:
|
||||||
virtual nsresult WriteHeaderFieldHTMLPostfix();
|
virtual nsresult WriteHeaderFieldHTMLPostfix();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
PRBool mFirst; // Attachment flag...
|
||||||
|
PRBool mSkipAttachment; // attachments we shouldn't show...
|
||||||
|
|
||||||
nsCOMPtr<nsIMsgHeaderSink> mHeaderSink;
|
nsCOMPtr<nsIMsgHeaderSink> mHeaderSink;
|
||||||
|
|
||||||
nsresult GetHeaderSink(nsIMsgHeaderSink ** aHeaderSink);
|
nsresult GetHeaderSink(nsIMsgHeaderSink ** aHeaderSink);
|
||||||
PRBool BroadCastHeadersAndAttachments();
|
PRBool BroadCastHeadersAndAttachments();
|
||||||
|
nsresult StartAttachmentInBody(const char *name, const char *contentType, const char *url);
|
||||||
|
|
||||||
nsCOMPtr<nsIDateTimeFormat> mDateFormater;
|
nsCOMPtr<nsIDateTimeFormat> mDateFormater;
|
||||||
nsresult GenerateDateString(const char * dateString, PRUnichar ** formattedDate);
|
nsresult GenerateDateString(const char * dateString, PRUnichar ** formattedDate);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче