Fix for bug 55657. Implement possibility to disable display attachment inline. R=cavin, SR=bienvenu

This commit is contained in:
ducarroz%netscape.com 2002-11-22 15:47:04 +00:00
Родитель f3533f76fe
Коммит 3ee0115c7f
15 изменённых файлов: 160 добавлений и 23 удалений

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

@ -173,6 +173,10 @@ function view_init()
thread_menuitem.setAttribute('checked',threadColumn.getAttribute('currentView')=='threaded');
}
// Initialize the View Attachment Inline menu
var viewAttachmentInline = pref.getBoolPref("mail.inline_attachments");
document.getElementById("viewAttachmentsInlineMenuitem").setAttribute("checked", viewAttachmentInline ? "true" : "false");
document.commandDispatcher.updateCommands('create-menu-view');
}
@ -1368,6 +1372,15 @@ function MsgBodyAsPlaintext()
return true;
}
function ToggleInlineAttachment(target)
{
var viewAttachmentInline = !pref.getBoolPref("mail.inline_attachments");
pref.setBoolPref("mail.inline_attachments", viewAttachmentInline)
target.setAttribute("checked", viewAttachmentInline ? "true" : "false");
MsgReload();
}
function MsgReload()
{
ReloadMessage();

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

@ -1110,6 +1110,7 @@ Rights Reserved.
<menuitem label="&collapseAllThreadsCmd.label;" accesskey="&collapseAllThreadsCmd.accesskey;" key="key_collapseAllThreads" disabled="true" observes="cmd_collapseAllThreads"/>
</menupopup>
</menu>
<menuseparator/>
<menu id="viewheadersmenu" label="&headersMenu.label;" accesskey="&headersMenu.accesskey;">
<menupopup onpopupshowing="InitViewHeadersMenu();">
<menuitem id="viewallheaders"
@ -1151,6 +1152,8 @@ Rights Reserved.
oncommand="MsgBodyAsPlaintext()"/>
</menupopup>
</menu>
<menuitem id="viewAttachmentsInlineMenuitem" label="&viewAttachmentsInlineCmd.label;" accesskey="&viewAttachmentsInlineCmd.accesskey;"
oncommand="ToggleInlineAttachment(event.target)" type="checkbox" checked="true"/>
<menuseparator/>
<menuitem id="stopMenuitem" label="&stopCmd.label;" accesskey="&stopCmd.accesskey;" key="key_stop" disabled="true" command="cmd_stop"/>
<menuitem label="&reloadCmd.label;" accesskey="&reloadCmd.accesskey;" observes="cmd_reload"/>

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

@ -205,14 +205,14 @@ Rights Reserved.
<!ENTITY headersBriefCmd.label ".Brief">
<!ENTITY headersBriefCmd.accesskey "B">
<!ENTITY bodyMenu.label "Message Body As">
<!ENTITY bodyMenu.accesskey "O">
<!ENTITY bodyMenu.accesskey "B">
<!ENTITY bodyAllowHTML.label "Original HTML">
<!ENTITY bodyAllowHTML.accesskey "H">
<!ENTITY bodySanitized.label "Simple HTML">
<!ENTITY bodySanitized.accesskey "S">
<!ENTITY bodyAsPlaintext.label "Plain Text">
<!ENTITY bodyAsPlaintext.accesskey "P">
<!ENTITY viewAttachmentsInlineCmd.label ".View Attachments Inline">
<!ENTITY viewAttachmentsInlineCmd.label "Display Attachments Inline">
<!ENTITY viewAttachmentsInlineCmd.accesskey "A">
<!ENTITY reloadCmd.label "Reload">
<!ENTITY reloadCmd.accesskey "R">

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

@ -74,5 +74,7 @@ interface nsIImapServerSink : nsISupports {
void RemoveChannelFromUrl(in nsIMsgMailNewsUrl aUrl, in unsigned long statusCode);
readonly attribute string arbitraryHeaders;
void forgetPassword();
readonly attribute boolean showAttachmentsInline;
};

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

@ -113,7 +113,8 @@ nsIMAPBodyShell::nsIMAPBodyShell(nsImapProtocol *protocolConnection, const char
m_folderName = nsCRT::strdup(folderName);
if (!m_folderName)
return;
SetContentModified(IMAP_CONTENT_MODIFIED_VIEW_INLINE);
SetContentModified(GetShowAttachmentsInline() ? IMAP_CONTENT_MODIFIED_VIEW_INLINE : IMAP_CONTENT_MODIFIED_VIEW_AS_LINKS);
// Turn the BODYSTRUCTURE response into a form that the nsIMAPBodypartMessage can be constructed from.
char *doctoredBuf = PR_smprintf("(\"message\" \"rfc822\" NIL NIL NIL NIL 0 () %s 0)", buf);
if (!doctoredBuf)
@ -140,6 +141,17 @@ void nsIMAPBodyShell::SetIsValid(PRBool valid)
}
PRBool nsIMAPBodyShell::GetShowAttachmentsInline()
{
if (!m_gotAttachmentPref)
{
m_showAttachmentsInline = !m_protocolConnection || m_protocolConnection->GetShowAttachmentsInline();
m_gotAttachmentPref = TRUE;
}
return m_showAttachmentsInline;
}
// Fills in buffer (and adopts storage) for header object
void nsIMAPBodyShell::AdoptMessageHeaders(char *headers, const char *partNum)
{
@ -945,7 +957,7 @@ PRBool nsIMAPBodypartLeaf::ShouldFetchInline()
if (m_parentPart->GetType() == IMAP_BODY_MULTIPART &&
(PL_strlen(m_partNumberString) >= 2) &&
!PL_strcmp(m_partNumberString + PL_strlen(m_partNumberString) - 2, ".1") && // this is the first text type on this level
!PL_strcmp(m_parentPart->GetPartNumberString(), "1") &&
(!PL_strcmp(m_parentPart->GetPartNumberString(), "1") || !PL_strcmp(m_parentPart->GetPartNumberString(), "2")) &&
!PL_strcasecmp(m_bodyType, "text"))
return PR_TRUE;
else
@ -1618,7 +1630,7 @@ PRBool nsIMAPBodyShellCache::AddShellToCache(nsIMAPBodyShell *shell)
// If it's already in the cache, then just return.
// This has the side-effect of re-ordering the LRU list
// to put this at the top, which is good, because it's what we want.
if (FindShellForUID(shell->GetUID(), shell->GetFolderName()))
if (FindShellForUID(shell->GetUID(), shell->GetFolderName(), shell->GetContentModified()))
return PR_TRUE;
// OK, so it's not in the cache currently.
@ -1653,17 +1665,26 @@ PRBool nsIMAPBodyShellCache::AddShellToCache(nsIMAPBodyShell *shell)
}
nsIMAPBodyShell *nsIMAPBodyShellCache::FindShellForUID(nsCString &UID, const char *mailboxName)
nsIMAPBodyShell *nsIMAPBodyShellCache::FindShellForUID(nsCString &UID, const char *mailboxName,
IMAP_ContentModifiedType modType)
{
nsCStringKey hashKey(UID);
nsIMAPBodyShell *foundShell = (nsIMAPBodyShell *) m_shellHash->Get(&hashKey);
if (!foundShell)
return NULL;
return nsnull;
// Make sure the content-modified types are compatible.
// This allows us to work seamlessly while people switch between
// View Attachments Inline and View Attachments As Links.
// Enforce the invariant that any cached shell we use
// match the current content-modified settings.
if (modType != foundShell->GetContentModified())
return nsnull;
// mailbox names must match also.
if (PL_strcmp(mailboxName, foundShell->GetFolderName()))
return NULL;
return nsnull;
// adjust the LRU stuff
m_shellList->RemoveElement(foundShell); // oh well, I suppose this defeats the performance gain of the hash if it actually is found
@ -1672,12 +1693,13 @@ nsIMAPBodyShell *nsIMAPBodyShellCache::FindShellForUID(nsCString &UID, const cha
return foundShell;
}
nsIMAPBodyShell *nsIMAPBodyShellCache::FindShellForUID(PRUint32 UID, const char *mailboxName)
nsIMAPBodyShell *nsIMAPBodyShellCache::FindShellForUID(PRUint32 UID, const char *mailboxName,
IMAP_ContentModifiedType modType)
{
nsCString uidString;
uidString.AppendInt(UID);
nsIMAPBodyShell *rv = FindShellForUID(uidString, mailboxName);
nsIMAPBodyShell *rv = FindShellForUID(uidString, mailboxName, modType);
return rv;
}

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

@ -270,7 +270,9 @@ public:
// If partNum is not NULL, then this works to generates a MIME part that hasn't been downloaded yet
// and leaves out all other parts. By default, to generate a normal message, partNum should be NULL.
PRBool PreflightCheckAllInline(); // Returns PR_TRUE if all parts are inline, PR_FALSE otherwise. Does not generate anything.
virtual PRBool GetShowAttachmentsInline(); // Returns TRUE if the user has the pref "Show Attachments Inline" set.
// Returns FALSE if the setting is "Show Attachments as Links"
PRBool PreflightCheckAllInline(); // Returns PR_TRUE if all parts are inline, PR_FALSE otherwise. Does not generate anything.
// Helpers
nsImapProtocol *GetConnection() { return m_protocolConnection; }
@ -299,7 +301,8 @@ protected:
char *m_folderName; // folder that contains this message
char *m_generatingPart; // If a specific part is being generated, this is it. Otherwise, NULL.
PRBool m_isBeingGenerated; // PR_TRUE if this body shell is in the process of being generated
PRBool m_gotAttachmentPref;
PRBool m_gotAttachmentPref; // Whether or not m_showAttachmentsInline has been initialized
PRBool m_showAttachmentsInline; // Whether or not we should display attachment inline
PRBool m_cached; // Whether or not this shell is cached
PRBool m_generatingWholeMessage; // whether or not we are generating the whole (non-MPOD) message
// Set to PR_FALSE if we are generating by parts
@ -328,8 +331,8 @@ public:
PRBool AddShellToCache(nsIMAPBodyShell *shell); // Adds shell to cache, possibly ejecting
// another entry based on scheme in EjectEntry().
nsIMAPBodyShell *FindShellForUID(nsCString &UID, const char *mailboxName); // Looks up a shell in the cache given the message's UID.
nsIMAPBodyShell *FindShellForUID(PRUint32 UID, const char *mailboxName); // Looks up a shell in the cache given the message's UID.
nsIMAPBodyShell *FindShellForUID(nsCString &UID, const char *mailboxName, IMAP_ContentModifiedType modType); // Looks up a shell in the cache given the message's UID.
nsIMAPBodyShell *FindShellForUID(PRUint32 UID, const char *mailboxName, IMAP_ContentModifiedType modType); // Looks up a shell in the cache given the message's UID.
// Returns the shell if found, NULL if not found.
protected:

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

@ -806,7 +806,7 @@ NS_IMETHODIMP nsIMAPHostSessionList::FindShellInCacheForHost(const char *serverK
if (host)
{
if (host->fShellCache)
*shell = host->fShellCache->FindShellForUID(uidString, mailboxName);
*shell = host->fShellCache->FindShellForUID(uidString, mailboxName, modType);
}
PR_ExitMonitor(gCachedHostInfoMonitor);
return (host == NULL) ? NS_ERROR_ILLEGAL_VALUE : NS_OK;

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

@ -3667,6 +3667,19 @@ nsImapIncomingServer::GetArbitraryHeaders(char **aResult)
return rv;
}
NS_IMETHODIMP
nsImapIncomingServer::GetShowAttachmentsInline(PRBool *aResult)
{
*aResult = PR_TRUE; // true per default
nsresult rv;
nsCOMPtr <nsIPref> prefs = do_GetService(NS_PREF_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv,rv);
rv = prefs->GetBoolPref("mail.inline_attachments", aResult);
return NS_OK; // In case this pref is not set we need to return NS_OK.
}
NS_IMETHODIMP
nsImapIncomingServer::OnUserOrHostNameChanged(const char *oldName, const char *newName)
{

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

@ -2003,7 +2003,9 @@ void nsImapProtocol::ProcessSelectedStateURL()
// We actually want a specific MIME part of the message.
// The Body Shell will generate it, even though we haven't downloaded it yet.
IMAP_ContentModifiedType modType = IMAP_CONTENT_MODIFIED_VIEW_INLINE ;
IMAP_ContentModifiedType modType = GetShowAttachmentsInline() ?
IMAP_CONTENT_MODIFIED_VIEW_INLINE :
IMAP_CONTENT_MODIFIED_VIEW_AS_LINKS ;
nsIMAPBodyShell *foundShell = nsnull;
res = m_hostSessionList->FindShellInCacheForHost(GetImapServerKey(),
@ -2063,7 +2065,9 @@ void nsImapProtocol::ProcessSelectedStateURL()
// Before fetching the bodystructure, let's check our body shell cache to see if
// we already have it around.
nsIMAPBodyShell *foundShell = NULL;
IMAP_ContentModifiedType modType = IMAP_CONTENT_MODIFIED_VIEW_INLINE;
IMAP_ContentModifiedType modType = GetShowAttachmentsInline() ?
IMAP_CONTENT_MODIFIED_VIEW_INLINE :
IMAP_CONTENT_MODIFIED_VIEW_AS_LINKS ;
nsCOMPtr<nsIMsgMailNewsUrl> mailurl = do_QueryInterface(m_runningUrl);
if (mailurl)
@ -3866,6 +3870,15 @@ PRBool nsImapProtocol::GetActive()
return ret;
}
PRBool nsImapProtocol::GetShowAttachmentsInline()
{
PRBool showAttachmentsInline = PR_TRUE;
if (m_imapMessageSink)
m_imapServerSink->GetShowAttachmentsInline(&showAttachmentsInline);
return showAttachmentsInline;
}
void nsImapProtocol::SetContentModified(IMAP_ContentModifiedType modified)
{
if (m_runningUrl && m_imapMessageSink)

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

@ -269,7 +269,9 @@ public:
void SetActive(PRBool active);
PRBool GetActive();
// Sets whether or not the content referenced by the current ActiveEntry has been modified.
PRBool GetShowAttachmentsInline();
// Sets whether or not the content referenced by the current ActiveEntry has been modified.
// Used for MIME parts on demand.
void SetContentModified(IMAP_ContentModifiedType modified);
PRBool GetShouldFetchAllParts();

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

@ -441,6 +441,8 @@ NS_IMETHODIMP nsImapUrl::GetImapPartToFetch(char **result)
{
wherepart += 9; // nsCRT::strlen("/;section=")
char *wherelibmimepart = PL_strstr(wherepart, "&part=");
if (!wherelibmimepart)
wherelibmimepart = PL_strstr(wherepart, "?part=");
int numCharsToCopy = (wherelibmimepart) ? wherelibmimepart - wherepart :
PL_strlen(m_listOfMessageIds) - (wherepart - m_listOfMessageIds);
if (numCharsToCopy)
@ -1104,7 +1106,7 @@ NS_IMETHODIMP nsImapUrl::SetContentModified(nsImapContentModifiedType contentMod
contentModifiedAnnotation = "Modified View Inline";
break;
case IMAP_CONTENT_MODIFIED_VIEW_AS_LINKS:
NS_ASSERTION(PR_FALSE, "we're not using this anymore!");
contentModifiedAnnotation = "Modified View As Link";
break;
case IMAP_CONTENT_FORCE_CONTENT_NOT_MODIFIED:
contentModifiedAnnotation = "Force Content Not Modified";

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

@ -787,6 +787,52 @@ mime_create (const char *content_type, MimeHeaders *hdrs,
clazz = (MimeObjectClass *)&mimeExternalObjectClass;
}
/* If the option `Show Attachments Inline' is off, now would be the time to change our mind... */
if (opts && !opts->show_attachment_inline_p)
{
if (mime_subclass_p(clazz, (MimeObjectClass *)&mimeInlineTextClass))
{
/* It's a text type. Write it only if it's the *first* part
that we're writing, and then only if it has no "filename"
specified (the assumption here being, if it has a filename,
it wasn't simply typed into the text field -- it was actually
an attached document.) */
if (opts->state && opts->state->first_part_written_p)
clazz = (MimeObjectClass *)&mimeExternalObjectClass;
else
{
/* If there's a name, then write this as an attachment. */
char *name = (hdrs ? MimeHeaders_get_name(hdrs, opts) : nsnull);
if (name)
{
clazz = (MimeObjectClass *)&mimeExternalObjectClass;
PR_Free(name);
}
}
}
else
if (mime_subclass_p(clazz,(MimeObjectClass *)&mimeContainerClass) &&
!mime_subclass_p(clazz,(MimeObjectClass *)&mimeMessageClass))
/* Multipart subtypes are ok, except for messages; descend into
multiparts, and defer judgement.
Encrypted blobs are just like other containers (make the crypto
layer invisible, and treat them as simple containers. So there's
no easy way to save encrypted data directly to disk; it will tend
to always be wrapped inside a message/rfc822. That's ok.) */
;
else if (opts && opts->part_to_load &&
mime_subclass_p(clazz,(MimeObjectClass *)&mimeMessageClass))
/* Descend into messages only if we're looking for a specific sub-part. */
;
else
{
/* Anything else, and display it as a link (and cause subsequent
text parts to also be displayed as links.) */
clazz = (MimeObjectClass *)&mimeExternalObjectClass;
}
}
PR_FREEIF(content_disposition);
obj = mime_new (clazz, hdrs, content_type);
@ -1303,7 +1349,7 @@ mime_set_url_imap_part(const char *url, const char *imappart, const char *libmim
PL_strcpy(result, url);
PL_strcat(result, "/;section=");
PL_strcat(result, imappart);
PL_strcat(result, "&part=");
PL_strcat(result, "?part=");
PL_strcat(result, libmimepart);
result[strlen(result)] = 0;

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

@ -1421,7 +1421,7 @@ MimeDisplayOptions::MimeDisplayOptions()
attachment_icon_layer_id = 0;
missing_parts = PR_FALSE;
show_attachment_inline_p = PR_FALSE;
}
MimeDisplayOptions::~MimeDisplayOptions()
@ -1619,6 +1619,9 @@ mime_bridge_create_display_stream(
if (msd->options->part_to_load)
msd->options->write_html_p = PR_FALSE;
if (msd->options->prefs)
msd->options->prefs->GetBoolPref("mail.inline_attachments", &(msd->options->show_attachment_inline_p));
obj = mime_new ((MimeObjectClass *)&mimeMessageClass, (MimeHeaders *) NULL, MESSAGE_RFC822);
if (!obj)
{

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

@ -484,8 +484,16 @@ MimeMultipartRelated_output_child_p(MimeObject *obj, MimeObject* child)
PR_Free(location);
if (absolute) {
nsCAutoString partnum;
nsCAutoString imappartnum;
partnum.Adopt(mime_part_address(child));
if (!partnum.IsEmpty()) {
if (obj->options->missing_parts)
{
char * imappart = mime_imap_part_address(child);
if (imappart)
imappartnum.Adopt(imappart);
}
/*
AppleDouble part need special care: we need to output only the data fork part of it.
The problem at this point is that we haven't yet decoded the children of the AppleDouble
@ -495,9 +503,13 @@ MimeMultipartRelated_output_child_p(MimeObject *obj, MimeObject* child)
partnum.Append(".2");
char* part;
part = mime_set_url_part(obj->options->url, partnum.get(),
if (!imappartnum.IsEmpty())
part = mime_set_url_imap_part(obj->options->url, imappartnum.get(), partnum.get());
else
part = mime_set_url_part(obj->options->url, partnum.get(),
PR_FALSE);
if (part) {
if (part)
{
char *name = MimeHeaders_get_name(child->headers, child->options);
// let's stick the filename in the part so save as will work.
if (name)

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

@ -392,6 +392,9 @@ public:
PRBool missing_parts; /* Whether or not this message is going to contain
missing parts (from IMAP Mime Parts On Demand) */
PRBool show_attachment_inline_p; /* Whether or not we should display attachment inline (whatever say
the content-disposition) */
};
#endif /* _MODLMIME_H_ */