Fixes related to message compose UI, save attachment, edit message as new and draft message. Those changes fix bug 14868, 23627, 24185, 24864, 24930, 26087, 26733, 27171, 27762, 27931, 27932, 29119, 29176, 30279, 31546 and 28677. R=alecf, rhp, jefft

This commit is contained in:
ducarroz%netscape.com 2000-03-23 06:39:19 +00:00
parent 081fe374c9
commit 4007ab88b6
21 changed files with 401 additions and 344 deletions

View File

@ -100,20 +100,25 @@ function ComposeMessage(type, format) //type is a nsIMsgCompType and format is a
// get the incoming server associated with this uri
var server = FindIncomingServer(uri);
// if they hit new and they are reading a newsgroup
// turn this into a new post, not a new mail message
if (type == msgComposeType.New) {
if (server.type == "nntp") {
type = msgComposeType.NewsPost;
// if they hit new or reply and they are reading a newsgroup
// turn this into a new post or a reply to group.
if (server.type == "nntp")
{
if (type == msgComposeType.Reply)
type = msgComposeType.ReplyToGroup;
else
if (type == msgComposeType.New)
{
type = msgComposeType.NewsPost;
// from the uri, get the newsgroup name
var resource = RDF.GetResource(uri);
var msgfolder = resource.QueryInterface(Components.interfaces.nsIMsgFolder);
if (msgfolder.isServer)
newsgroup = "";
else
newsgroup = msgfolder.name;
}
// from the uri, get the newsgroup name
var resource = RDF.GetResource(uri);
var msgfolder = resource.QueryInterface(Components.interfaces.nsIMsgFolder);
if (msgfolder.isServer)
newsgroup = "";
else
newsgroup = msgfolder.name;
}
}
}
@ -166,6 +171,7 @@ function ComposeMessage(type, format) //type is a nsIMsgCompType and format is a
dump('i = '+ i);
dump('\n');
if (type == msgComposeType.Reply || type == msgComposeType.ReplyAll || type == msgComposeType.ForwardInline ||
type == msgComposeType.ReplyToGroup || type == msgComposeType.ReplyToSenderAndGroup ||
type == msgComposeType.Template || type == msgComposeType.Draft)
{
msgComposeService.OpenComposeWindow(null, nodeList[i].getAttribute('id'), type, format, identity);

View File

@ -625,7 +625,7 @@ Rights Reserved.
<menuitem value="&forwardAsAttachmentCmd.label;" oncommand="MsgForwardAsAttachment(event);"/>
</menupopup>
</menu>
<menuitem value="&editMsgAsNewCmd.label;" disabled="true" oncommand="MsgEditMessageAsNew();"/>
<menuitem value="&editMsgAsNewCmd.label;" oncommand="MsgEditMessageAsNew();"/>
<menuseparator/>
<menu value="&moveMsgMenu.label;" id="moveMenu" datasources="rdf:null"
rdf:ignore="http://home.netscape.com/NC-rdf#MessageChild">

View File

@ -1078,7 +1078,12 @@ function MsgPreviousFlaggedMessage()
function MsgGoBack() {}
function MsgGoForward() {}
function MsgEditMessageAsNew() {}
function MsgEditMessageAsNew()
{
ComposeMessage(msgComposeType.Template, msgComposeFormat.Default);
}
function MsgAddSenderToAddressBook() {}
function MsgAddAllToAddressBook() {}

View File

@ -226,7 +226,7 @@ Rights Reserved.
<!ENTITY forwardAsMenu.label "Forward As">
<!ENTITY forwardAsInline.label "Inline">
<!ENTITY forwardAsAttachmentCmd.label "Attachment">
<!ENTITY editMsgAsNewCmd.label ".Edit Message As New">
<!ENTITY editMsgAsNewCmd.label "Edit Message As New">
<!ENTITY moveMsgMenu.label "Move Message">
<!ENTITY copyMsgMenu.label "Copy Message">
<!ENTITY fileHereMenu.label "File Here">

View File

@ -452,9 +452,27 @@ nsMessenger::OpenAttachment(const char * url, const char * displayName,
if (!fileSpec) goto done;
unescapedDisplayName = nsCRT::strdup(displayName);
if (!unescapedDisplayName) goto done;
nsUnescape(unescapedDisplayName);
/* we need to convert the UTF-8 fileName to platform specific character set.
The display name is in UTF-8 because it has been escaped from JS
*/
nsAutoString tempStr;
rv = ConvertToUnicode("UTF-8", unescapedDisplayName, tempStr);
if (NS_SUCCEEDED(rv))
{
char * tempCStr;
rv = ConvertFromUnicode(nsMsgI18NFileSystemCharset(), tempStr, &tempCStr);
if (NS_SUCCEEDED(rv))
{
nsCRT::free(unescapedDisplayName);
unescapedDisplayName = tempCStr;
}
}
rv = fileSpec->ChooseOutputFile("Save Attachment",
nsUnescape(unescapedDisplayName),
unescapedDisplayName,
nsIFileSpecWithUI::eAllFiles);
nsCRT::free(unescapedDisplayName);
@ -1609,7 +1627,7 @@ nsSaveAsListener::OnStopRequest(nsIChannel* aChannel, nsISupports* aSupport,
if (m_outputFormat == TEXT_PLAIN)
{
ConvertBufToPlainText(m_msgBuffer);
rv = nsMsgI18NSaveAsCharset(TEXT_PLAIN, (const char *)nsAutoCString(msgCompFileSystemCharset()),
rv = nsMsgI18NSaveAsCharset(TEXT_PLAIN, (const char *)nsAutoCString(nsMsgI18NFileSystemCharset()),
m_msgBuffer.GetUnicode(), &conBuf);
if ( NS_SUCCEEDED(rv) && (conBuf) )
conLength = m_msgBuffer.Length();

View File

@ -201,7 +201,7 @@ const char *msgCompHeaderInternalCharset()
}
// Charset used by the file system.
const nsString& msgCompFileSystemCharset()
const nsString& nsMsgI18NFileSystemCharset()
{
/* Get a charset used for the file. */
static nsString aPlatformCharset;

View File

@ -37,7 +37,7 @@ NS_MSG_BASE PRBool nsMsgI18N7bit_data_part(const char *charset, const char *s
NS_MSG_BASE char *nsMsgI18NGetAcceptLanguage(void);
NS_MSG_BASE const char *msgCompHeaderInternalCharset(void);
NS_MSG_BASE const nsString& msgCompFileSystemCharset(void);
NS_MSG_BASE const nsString& nsMsgI18NFileSystemCharset(void);
NS_MSG_BASE char * nsMsgI18NGetDefaultMailCharset(void);
NS_MSG_BASE nsresult ConvertFromUnicode(const nsString& aCharset,

View File

@ -108,6 +108,9 @@ interface nsIMsgCompFields : nsISupports {
void SetTemplateName(in wstring value);
wstring GetTemplateName();
void SetDraftId(in wstring value);
wstring GetDraftId();
void SetReturnReceipt(in boolean value);
boolean GetReturnReceipt();

View File

@ -26,6 +26,7 @@
#include "nsIEditorShell.idl"
#include "nsIMsgIdentity.idl"
%{ C++
#include "nsIDOMWindow.h"
#include "nsIEditorShell.h"
@ -36,15 +37,17 @@ typedef long MSG_ComposeType;
[scriptable, uuid(c7035852-7531-11d3-9a73-006008948010)]
interface nsIMsgCompType {
const long New = 0;
const long Reply = 1;
const long ReplyAll = 2;
const long ForwardAsAttachment = 3;
const long ForwardInline = 4;
const long NewsPost = 5;
const long Draft = 6;
const long Template = 7;
const long MailToUrl = 8;
const long New = 0;
const long Reply = 1;
const long ReplyAll = 2;
const long ForwardAsAttachment = 3;
const long ForwardInline = 4;
const long NewsPost = 5;
const long ReplyToGroup = 6;
const long ReplyToSenderAndGroup = 7;
const long Draft = 8;
const long Template = 9;
const long MailToUrl = 10;
};
@ -144,6 +147,10 @@ interface nsIMsgCompose : nsISupports {
looks for newsgroups stored in compose fields
*/
wstring GetNoHtmlNewsgroups(in wstring newsgroups);
/* ResetNodeEventHandlers: Temporary API to go around bug 26528. THis API will be removed when bug 26528 is fixed.
*/
void ResetNodeEventHandlers(in nsIDOMNode node);
/* ... */
attribute nsIEditorShell editor;

View File

@ -17,9 +17,10 @@
* Copyright (C) 1998-1999 Netscape Communications Corporation. All
* Rights Reserved.
*/
var msgCompDeliverMode = Components.interfaces.nsIMsgCompDeliverMode;
var msgCompSendFormat = Components.interfaces.nsIMsgCompSendFormat;
var msgCompType = Components.interfaces.nsIMsgCompType;
var accountManagerProgID = "component://netscape/messenger/account-manager";
var accountManager = Components.classes[accountManagerProgID].getService(Components.interfaces.nsIMsgAccountManager);
@ -131,16 +132,27 @@ function GetArgs()
return args;
}
function WaitFinishLoadingDocument()
function WaitFinishLoadingDocument(msgType)
{
if (documentLoaded)
{
CompFields2Recipients(msgCompose.compFields);
//If we are in plain text, we nee to set the wrap column
if (! msgCompose.composeHTML)
try
{
window.editorShell.wrapColumn = msgCompose.wrapLength;
}
catch (e)
{
dump("### window.editorShell.wrapColumn exception text: " + e + " - failed\n");
}
CompFields2Recipients(msgCompose.compFields, msgType);
SetComposeWindowTitle(13);
AdjustFocus();
}
else
setTimeout("WaitFinishLoadingDocument();", 200);
setTimeout("WaitFinishLoadingDocument(" + msgType + ");", 200);
}
function ComposeStartup()
@ -169,9 +181,6 @@ function ComposeStartup()
}
identitySelect.value = identity.key;
// fill in Recipient type combobox
FillRecipientTypeCombobox();
if (msgComposeService)
{
// this is frustrating, we need to convert the preselect identity key
@ -206,18 +215,11 @@ function ComposeStartup()
}
else
{
//Remove HTML toolbar as we are editing in plain text mode
//Remove HTML toolbar and format menu as we are editing in plain text mode
document.getElementById("FormatToolbar").setAttribute("hidden", true);
document.getElementById("formatMenu").setAttribute("hidden", true);
window.editorShell.SetEditorType("text");
try
{
window.editorShell.wrapColumn = msgCompose.wrapLength;
}
catch (e)
{
dump("### window.editorShell.wrapColumn exception text: " + e + " - failed\n");
}
dump("editor initialized in PLAIN TEXT mode\n");
}
@ -234,20 +236,14 @@ function ComposeStartup()
if (args.bodyislink == "true")
{
if (msgCompose.composeHTML)
{
msgCompFields.SetBody("<BR><A HREF=\"" + args.body +
"\">" + unescape(args.body)
+ "</A><BR>");
}
else
{
msgCompFields.SetBody("\n" + args.body + "\n");
}
msgCompFields.SetBody("\n<" + args.body + ">\n");
}
else
{
msgCompFields.SetBody(args.body);
}
}
if (args.to)
@ -281,7 +277,7 @@ function ComposeStartup()
msgCompose.editor = window.editorShell;
msgCompose.RegisterStateListener(stateListener);
WaitFinishLoadingDocument();
WaitFinishLoadingDocument(args.type);
}
}
}
@ -578,7 +574,7 @@ function SaveAsDraft()
function SaveAsTemplate()
{
dump("SaveAsDraft from XUL\n");
dump("SaveAsTemplate from XUL\n");
// 5 = nsMsgSaveAsTemplate
// RICHIE: We should really have a way of using constants and not
@ -761,11 +757,11 @@ function getIdentityForKey(key)
function AdjustFocus()
{
var element = document.getElementById("msgRecipient#1");
var element = document.getElementById("msgRecipient#" + awGetNumberOfRecipients());
if (element.value == "")
{
dump("set focus on the recipient\n");
element.focus();
awSetFocus(awGetNumberOfRecipients(), element);
}
else
{

View File

@ -19,19 +19,7 @@
* Contributor(s):
*/
function FillRecipientTypeCombobox()
{
top.MAX_RECIPIENTS = 1;
var body;
for ( var row = 2; row <= top.MAX_RECIPIENTS; row++ )
{
body = document.getElementById('addressWidgetBody');
awCopyNode(awGetTreeItem(1), body, 0);
}
}
top.MAX_RECIPIENTS = 0;
function Recipients2CompFields(msgCompFields)
{
@ -82,99 +70,83 @@ function Recipients2CompFields(msgCompFields)
dump("Message Compose Error: msgCompFields is null (ExtractRecipients)");
}
function CompFields2Recipients(msgCompFields)
function CompFields2Recipients(msgCompFields, msgType)
{
if (msgCompFields)
{
var row = 1;
var treeChildren = document.getElementById('addressWidgetBody');
var newTreeChildrenNode = treeChildren.cloneNode(false);
// var templateNode = treeChildren.firstChild(); // doesn't work!
var templateNode = awGetTreeItem(1);
row = awSetInputAndPopupFromArray(row, msgCompFields.SplitRecipients(msgCompFields.GetTo(), false), "addr_to");
row = awSetInputAndPopupFromArray(row, msgCompFields.SplitRecipients(msgCompFields.GetCc(), false), "addr_cc");
row = awSetInputAndPopupFromArray(row, msgCompFields.SplitRecipients(msgCompFields.GetBcc(), false), "addr_bcc");
row = awSetInputAndPopupFromArray(row, msgCompFields.SplitRecipients(msgCompFields.GetReplyTo(), false), "addr_reply");
row = awSetInputAndPopup(row, msgCompFields.GetOtherRandomHeaders(), "addr_other");
row = awSetInputAndPopup(row, msgCompFields.GetNewsgroups(), "addr_newsgroups");
row = awSetInputAndPopup(row, msgCompFields.GetFollowupTo(), "addr_followup");
awSetInputAndPopupFromArray(msgCompFields.SplitRecipients(msgCompFields.GetReplyTo(), false), "addr_reply", newTreeChildrenNode, templateNode);
awSetInputAndPopupFromArray(msgCompFields.SplitRecipients(msgCompFields.GetTo(), false), "addr_to", newTreeChildrenNode, templateNode);
awSetInputAndPopupFromArray(msgCompFields.SplitRecipients(msgCompFields.GetCc(), false), "addr_cc", newTreeChildrenNode, templateNode);
awSetInputAndPopupFromArray(msgCompFields.SplitRecipients(msgCompFields.GetBcc(), false), "addr_bcc", newTreeChildrenNode, templateNode);
awSetInputAndPopup(msgCompFields.GetOtherRandomHeaders(), "addr_other", newTreeChildrenNode, templateNode);
awSetInputAndPopup(msgCompFields.GetNewsgroups(), "addr_newsgroups", newTreeChildrenNode, templateNode);
awSetInputAndPopup(msgCompFields.GetFollowupTo(), "addr_followup", newTreeChildrenNode, templateNode);
if ( row > 1 ) row--;
// remove extra rows
while ( top.MAX_RECIPIENTS > row )
awRemoveRow(top.MAX_RECIPIENTS);
setTimeout("awFinishCopyNodes();", 0);
if (top.MAX_RECIPIENTS == 0)
top.MAX_RECIPIENTS = 1;
else
{
//If it's a new message, we need to add an extrat empty recipient.
var msgComposeType = Components.interfaces.nsIMsgCompType;
if (msgType == msgComposeType.New)
_awSetInputAndPopup("", "addr_to", newTreeChildrenNode, templateNode);
// var parent = treeChildren.parentNode(); // doesn't work!
var parent = document.getElementById('addressingWidgetTree')
parent.replaceChild(newTreeChildrenNode, treeChildren);
setTimeout("awFinishCopyNodes();", 0);
}
}
}
function awSetInputAndPopup(firstRow, inputValue, popupValue)
function _awSetInputAndPopup(inputValue, popupValue, parentNode, templateNode)
{
var row = firstRow;
// remove leading spaces
while (inputValue[0] == " " )
inputValue = inputValue.substring(1, inputValue.length);
top.MAX_RECIPIENTS++;
var newNode = templateNode.cloneNode(true);
parentNode.appendChild(newNode); // we need to insert the new node before we set the value of the select element!
var input = newNode.getElementsByTagName('INPUT');
if ( input && input.length == 1 )
{
input[0].setAttribute("value", inputValue);
input[0].setAttribute("id", "msgRecipient#" + top.MAX_RECIPIENTS);
}
var select = newNode.getElementsByTagName('SELECT');
if ( select && select.length == 1 )
{
//Doesn't work! select[0].setAttribute("value", popupValue);
select[0].value = popupValue;
select[0].setAttribute("id", "msgRecipientType#" + top.MAX_RECIPIENTS);
}
}
function awSetInputAndPopup(inputValue, popupValue, parentNode, templateNode)
{
if ( inputValue && popupValue )
{
var addressArray = inputValue.split(",");
for ( var index = 0; index < addressArray.length; index++ )
{
// remove leading spaces
while ( addressArray[index][0] == " " )
addressArray[index] = addressArray[index].substring(1, addressArray[index].length);
// we can add one row if trying to add just beyond current size
if ( row == (top.MAX_RECIPIENTS + 1))
{
var body = document.getElementById('addressWidgetBody');
awCopyNode(awGetTreeItem(1), body, 0);
top.MAX_RECIPIENTS++;
}
// if row is legal then set the values
if ( row <= top.MAX_RECIPIENTS )
{
awGetInputElement(row).value = addressArray[index];
awGetPopupElement(row).value = popupValue;
row++;
}
}
return(row);
_awSetInputAndPopup(addressArray[index], popupValue, parentNode, templateNode);
}
return(firstRow);
}
function awSetInputAndPopupFromArray(firstRow, inputArray, popupValue)
function awSetInputAndPopupFromArray(inputArray, popupValue, parentNode, templateNode)
{
var row = firstRow;
if ( inputArray && popupValue )
{
for ( var index = 0; index < inputArray.count; index++ )
{
// remove leading spaces
inputValue = inputArray.StringAt(index);
while ( inputValue[0] == " " )
inputValue = inputValue.substring(1, inputValue.length);
// we can add one row if trying to add just beyond current size
if ( row == (top.MAX_RECIPIENTS + 1))
{
var body = document.getElementById('addressWidgetBody');
awCopyNode(awGetTreeItem(1), body, 0);
top.MAX_RECIPIENTS++;
}
// if row is legal then set the values
if ( row <= top.MAX_RECIPIENTS )
{
awGetInputElement(row).value = inputValue;
awGetPopupElement(row).value = popupValue;
row++;
}
}
return(row);
_awSetInputAndPopup(inputArray.StringAt(index), popupValue, parentNode, templateNode);
}
return(firstRow);
}
function awNotAnEmptyArea(event)
@ -234,19 +206,28 @@ function awAppendNewRow(setFocus)
if ( body && treeitem1 )
{
var lastRecipientType = awGetPopupElement(top.MAX_RECIPIENTS).value;
var lastRecipientType = awGetPopupElement(top.MAX_RECIPIENTS).value;
awCopyNode(treeitem1, body, 0);
newNode = awCopyNode(treeitem1, body, 0);
top.MAX_RECIPIENTS++;
awGetPopupElement(top.MAX_RECIPIENTS).value = lastRecipientType;
var input = newNode.getElementsByTagName('INPUT');
if ( input && input.length == 1 )
{
input[0].setAttribute("value", "");
input[0].setAttribute("id", "msgRecipient#" + top.MAX_RECIPIENTS);
}
var select = newNode.getElementsByTagName('SELECT');
if ( select && select.length == 1 )
{
//doesn't work! select[0].setAttribute("value", lastRecipientType);
select[0].value = lastRecipientType;
select[0].setAttribute("id", "msgRecipientType#" + top.MAX_RECIPIENTS);
}
// focus on new input widget
if (setFocus)
{
var newInput = awGetInputElement(top.MAX_RECIPIENTS);
if ( newInput )
awSetFocus(top.MAX_RECIPIENTS, newInput);
}
if (setFocus && input[0] )
awSetFocus(top.MAX_RECIPIENTS, input[0]);
}
}
@ -255,28 +236,12 @@ function awAppendNewRow(setFocus)
function awGetPopupElement(row)
{
var treerow = awGetTreeRow(row);
if ( treerow )
{
var popup = treerow.getElementsByTagName('SELECT');
if ( popup && popup.length == 1 )
return popup[0];
}
return 0;
return document.getElementById("msgRecipientType#" + row);
}
function awGetInputElement(row)
{
var treerow = awGetTreeRow(row);
if ( treerow )
{
var input = treerow.getElementsByTagName('INPUT');
if ( input && input.length == 1 )
return input[0];
}
return 0;
return document.getElementById("msgRecipient#" + row);
}
function awGetTreeRow(row)
@ -328,97 +293,14 @@ function awGetRowByInputElement(inputElement)
// Copy Node - copy this node and insert ahead of the (before) node. Append to end if before=0
function awCopyNode(node, parentNode, beforeNode)
{
dump("awCopyNode\n");
// XXXwaterson Ideally, we'd just do this, but for bug 26528
// (and some of the funky logic about the 'id' attribute in
// awCopyNodeAndChildren).
//
//var newNode = node.cloneNode(true);
var newNode = awCopyNodeAndChildren(node);
var newNode = node.cloneNode(true);
if ( beforeNode )
parentNode.insertBefore(newNode, beforeNode);
else
parentNode.appendChild(newNode);
}
function awCopyNodeAndChildren(node)
{
var newNode;
if ( node.nodeName == "#text" )
{
// create new text node
newNode = document.createTextNode(node.data);
}
else
{
// create new node
if ( node.nodeName[0] >= 'A' && node.nodeName[0] <= 'Z' )
newNode = createHTML(node.nodeName);
else
newNode = document.createElement(node.nodeName);
var attributes = node.attributes;
if ( attributes && attributes.length )
{
var attrNode, name, value;
// copy attributes into new node
for ( var index = 0; index < attributes.length; index++ )
{
attrNode = attributes.item(index);
name = attrNode.nodeName;
value = attrNode.nodeValue;
if ( name != 'id' )
newNode.setAttribute(name, value);
}
}
if ( node.nodeName == "SELECT" )
{
// copy options inside of SELECT
if ( newNode )
{
for ( var index = 0; index < node.options.length; index++ )
{
var option = new Option(node.options.item(index).text,
node.options.item(index).value)
newNode.add(option, null);
}
}
}
else
{
// children of nodes
if ( node.childNodes )
{
var childNode;
for ( var child = 0; child < node.childNodes.length; child++ )
{
childNode = awCopyNodeAndChildren(node.childNodes[child]);
newNode.appendChild(childNode);
}
}
}
if ( node.nodeName == "INPUT" )
{
// copy the event handler, as it's not
// sufficient to just set the attribute.
newNode.onkeyup = node.onkeyup;
}
}
return newNode;
}
function createHTML(tag)
{
return document.createElementWithNameSpace(tag, "http://www.w3.org/TR/REC-html40");
return newNode;
}
// remove row
@ -482,46 +364,18 @@ function _awSetFocus()
}
//temporary patch for bug 26344
//temporary patch for bug 26344 & 26528
function awFinishCopyNode(node)
{
// dump ("awFinishCopyNode, node name=" + node.nodeName + "\n");
// Because event handler attributes set into a node before this node is inserted
// into the DOM are not recognised (in fact not compiled), we need to parsed again
// the whole node and reset event handlers.
var attributes = node.attributes;
if ( attributes && attributes.length )
{
var attrNode, name;
for ( var index = 0; index < attributes.length; index++ )
{
attrNode = attributes.item(index);
name = attrNode.nodeName;
if (name.substring(0, 2) == 'on')
{
node.setAttribute(name, attrNode.nodeValue);
// dump(" -->reset attribute " + name + "\n");
}
}
}
// children of nodes
if ( node.childNodes )
{
var childNode;
for ( var child = 0; child < node.childNodes.length; child++ )
childNode = awFinishCopyNode(node.childNodes[child]);
}
msgCompose.ResetNodeEventHandlers(node);
return;
}
function awFinishCopyNodes()
{
for ( var row = 2; row <= top.MAX_RECIPIENTS; row++ )
awFinishCopyNode(awGetTreeRow(row));
var treeChildren = document.getElementById('addressWidgetBody');
awFinishCopyNode(treeChildren);
}
@ -530,4 +384,9 @@ function awTabFromRecipient(element, event)
//If we are le last element in the tree, we don't want to create a new row.
if (element == awGetInputElement(top.MAX_RECIPIENTS))
top.doNotCreateANewRow = true;
}
function awGetNumberOfRecipients()
{
return top.MAX_RECIPIENTS;
}

View File

@ -39,15 +39,25 @@ Rights Reserved.
onclick="awClickEmptySpace(true)"
style="width:0px;height:0px;border:solid black 1px">
<treecol style="width:9em"/>
<treecol style="width:2em"/>
<treechildren id="addressWidgetBody">
<treeitem>
<treerow>
<treecell allowevents="true" onclick="awNotAnEmptyArea(event)">
<treecell allowevents="true">
<!--menulist id="msgRecipientType#1" style="width:0px"
onclick="awNotAnEmptyArea(event)"
onchange="contentChanged=true;">
<menupopup>
<menuitem value="&toAddr.label;"/>
<menuitem value="&ccAddr.label;"/>
<menuitem value="&bccAddr.label;"/>
<menuitem value="&replyAddr.label;"/>
<menuitem value="&newsgroupsAddr.label;"/>
<menuitem value="&followupAddr.label;"/>
</menupopup>
</menulist-->
<html:select id="msgRecipientType#1"
onchange="contentChanged=true;">
onclick="awNotAnEmptyArea(event)"
onchange="contentChanged=true;">
<html:option value="addr_to">&toAddr.label;</html:option>
<html:option value="addr_cc">&ccAddr.label;</html:option>
<html:option value="addr_bcc">&bccAddr.label;</html:option>
@ -55,13 +65,9 @@ Rights Reserved.
<html:option value="addr_newsgroups">&newsgroupsAddr.label;</html:option>
<html:option value="addr_followup">&followupAddr.label;</html:option>
</html:select>
</treecell>
<treecell onclick="awNotAnEmptyArea(event)">
<image/>
</treecell>
<image onclick="awNotAnEmptyArea(event)"/>
<treecell allowevents="true" onclick="awNotAnEmptyArea(event);">
<html:input id="msgRecipient#1"
flex="100%"
class="addressingWidget"
@ -70,6 +76,7 @@ Rights Reserved.
{ AutoCompleteAddress(this); awReturnHit(this); }"
onkeydown="if (event.which == 9) awTabFromRecipient(this, event);"
onchange="contentChanged=true; awInputChanged(this);"
onclick="awNotAnEmptyArea(event);"
/>
</treecell>
</treerow>

View File

@ -34,10 +34,11 @@ Rights Reserved.
onunload="ComposeUnload()"
onload="ComposeLoad()"
onclose="return ComposeCanClose()"
width="640" height="480"
title="&msgComposeWindow.title;"
align="vertical">
align="vertical"
width="640" height="480"
persist="width height x y"
>
<html:script language="JavaScript" src="chrome://editor/content/EditorCommands.js"/>
<html:script language="JavaScript" src="chrome://editor/content/EditorCommandsDebug.js"/>
@ -395,8 +396,7 @@ ACTUALLY, EVERY TIME YOU TYPE ANY OF THE KEY DEFINED HERE AFTER WITHOUT ANY OF T
<box align="horizontal">
<html:div>&fromAddr.label;</html:div>
<spring style="width:0.5em"/>
<html:select id="msgIdentity" flex="100%"
onchange="contentChanged=true;"/>
<html:select id="msgIdentity" onchange="contentChanged=true;"/>
</box>
<spring style="height:0.5em"/>
@ -408,8 +408,14 @@ ACTUALLY, EVERY TIME YOU TYPE ANY OF THE KEY DEFINED HERE AFTER WITHOUT ANY OF T
<html:div>&subject.label;</html:div>
<spring style="width:0.5em"/>
<html:input id="msgSubject" type="text" flex="100%"
onkeyup="SetComposeWindowTitle(event.which);"
onkeydown="if (event.which == 9) contentWindow.focus();"
onkeyup="SetComposeWindowTitle(event.which);
if (event.which == 13)
contentWindow.focus();"
onkeypress="if (event.which == 9)
if (event.shiftKey == false) {
contentWindow.focus();
event.preventDefault();
}"
onchange="contentChanged=true;"
/>
</box>
@ -473,7 +479,13 @@ ACTUALLY, EVERY TIME YOU TYPE ANY OF THE KEY DEFINED HERE AFTER WITHOUT ANY OF T
</toolbox>
<!-- The main mail three pane frame -->
<html:iframe type="content-primary" id="content-frame" src="about:blank" name="browser.message.body" flex="100%"/>
<html:iframe type="content-primary" id="content-frame" src="about:blank" name="browser.message.body" flex="100%"
onkeypress="if (event.which == 9)
if (event.shiftKey == true) {
document.getElementById('msgSubject').focus();
event.preventDefault();
}"
/>
<box id="status-bar">
<box align="vertical" style="width:100px">

View File

@ -3,7 +3,7 @@
<!ENTITY toAddr.label "To:">
<!ENTITY ccAddr.label "Cc:">
<!ENTITY bccAddr.label "Bcc:">
<!ENTITY replyAddr.label "Reply:">
<!ENTITY replyAddr.label "Reply-To:">
<!ENTITY newsgroupsAddr.label "Newsgroup:">
<!ENTITY followupAddr.label "Followup:">
<!ENTITY followupAddr.label "Followup-To:">

View File

@ -45,11 +45,7 @@ tree[class="addressingWidget"] treeitem > treerow > treecell > image {
user-focus: ignore;
}
tree[class="addressingWidget"] treeitem > treerow {
border-bottom:1px solid blue;
}
input[class="addressingWidget"] {
input[class="addressingWidget"] {
width: 90%;
border: none;
margin: 0px;
@ -89,6 +85,18 @@ toolbar#MsgHeadersToolbar {
border-bottom: 1px solid #999999;
}
box#addressingWidget {
user-focus: normal;
}
tree#attachmentBucket {
user-focus: normal;
}
#msgSubject {
user-focus: normal;
}
}
#msgIdentity {
user-focus: normal;
}

View File

@ -120,7 +120,11 @@ nsresult nsMsgCompFields::Copy(nsIMsgCompFields* pMsgCompFields)
for (i = 0; i < MSG_LAST_BOOL_HEADER_MASK; i ++)
m_boolHeaders[i] = pFields->m_boolHeaders[i];
m_force_plain_text = pFields->m_force_plain_text;
m_multipart_alt = pFields->m_multipart_alt;
m_receiptType = pFields->m_receiptType;
m_internalCharSet = pFields->m_internalCharSet;
m_draftID = pFields->m_draftID;
return NS_OK;
}
@ -452,6 +456,22 @@ nsresult nsMsgCompFields::GetTemplateName(PRUnichar **_retval)
return GetHeader(MSG_X_TEMPLATE_HEADER_MASK, _retval);
}
nsresult nsMsgCompFields::SetDraftId(const PRUnichar *value)
{
m_draftID = value;
return NS_OK;
}
nsresult nsMsgCompFields::GetDraftId(PRUnichar **_retval)
{
if (_retval)
{
*_retval = m_draftID.ToNewUnicode();
return NS_OK;
}
return NS_ERROR_NULL_POINTER;
}
nsresult nsMsgCompFields::SetReturnReceipt(PRBool value)
{
return SetBoolHeader(MSG_RETURN_RECEIPT_BOOL_HEADER_MASK, value);

View File

@ -184,6 +184,9 @@ public:
NS_IMETHOD SetTemplateName(const char *value) {return SetAsciiHeader(MSG_X_TEMPLATE_HEADER_MASK, value);}
const char* GetTemplateName() {return GetHeader(MSG_X_TEMPLATE_HEADER_MASK);}
NS_IMETHOD SetDraftId(const PRUnichar *value);
NS_IMETHOD GetDraftId(PRUnichar **_retval);
NS_IMETHOD SetReturnReceipt(PRBool value);
NS_IMETHOD GetReturnReceipt(PRBool *_retval);
PRBool GetReturnReceipt() {return GetBoolHeader(MSG_RETURN_RECEIPT_BOOL_HEADER_MASK);}
@ -247,7 +250,12 @@ protected:
PRBool m_multipart_alt;
PRInt32 m_receiptType; /* 0:None 1:DSN 2:MDN 3:BOTH */
nsString m_internalCharSet;
nsString m_draftID;
/* WARNING:
If you add any new member variable, you must update the function
nsMsgCompFields::Copy as well else they will not be copied automatically!
*/
};

View File

@ -1518,7 +1518,7 @@ msg_pick_real_name (nsMsgAttachmentHandler *attachment, const char *charset)
{
/* Convert to unicode */
nsAutoString uStr;
rv = ConvertToUnicode(msgCompFileSystemCharset(), attachment->m_real_name, uStr);
rv = ConvertToUnicode(nsMsgI18NFileSystemCharset(), attachment->m_real_name, uStr);
if (NS_FAILED(rv))
uStr.Assign(attachment->m_real_name);

View File

@ -27,6 +27,8 @@
#include "nsIDOMNodeList.h"
#include "nsIDOMHTMLInputElement.h"
#include "nsIDOMDocument.h"
#include "nsIDOMSelection.h"
#include "nsIDOMNamedNodeMap.h"
#include "nsMsgI18N.h"
#include "nsMsgCompCID.h"
#include "nsMsgSend.h"
@ -49,8 +51,6 @@
#include "nsTextFormatter.h"
#include "nsIEditor.h"
#include "nsIHTMLEditor.h"
#include "nsIDOMSelection.h"
#include "nsIDOMNode.h"
#include "nsEscape.h"
#include "plstr.h"
#include "nsIDocShell.h"
@ -480,12 +480,10 @@ nsresult nsMsgCompose::_SendMsg(MSG_DeliverMode deliverMode,
// Pref values are supposed to be stored as UTF-8, so no conversion
nsXPIDLCString email;
nsXPIDLString fullName;
nsXPIDLCString replyTo;
nsXPIDLString organization;
identity->GetEmail(getter_Copies(email));
identity->GetFullName(getter_Copies(fullName));
identity->GetReplyTo(getter_Copies(replyTo));
identity->GetOrganization(getter_Copies(organization));
char * sender = nsnull;
@ -504,10 +502,6 @@ nsresult nsMsgCompose::_SendMsg(MSG_DeliverMode deliverMode,
m_compFields->SetFrom(sender);
PR_FREEIF(sender);
//Set the reply-to only if the user have not specified one in the message
const char * reply = m_compFields->GetReplyTo();
if (reply == nsnull || *reply == 0)
m_compFields->SetReplyTo(replyTo);
m_compFields->SetOrganization(organization);
#if defined(DEBUG_ducarroz) || defined(DEBUG_seth_)
@ -814,28 +808,28 @@ nsresult nsMsgCompose::GetEditor(nsIEditorShell * *aEditor)
nsresult nsMsgCompose::SetEditor(nsIEditorShell * aEditor)
{
// First, store the editor shell.
m_editor = aEditor;
// First, store the editor shell.
m_editor = aEditor;
//
// Now this routine will create a listener for state changes
// in the editor and set us as the compose object of interest.
//
mDocumentListener = new nsMsgDocumentStateListener();
if (!mDocumentListener)
return NS_ERROR_OUT_OF_MEMORY;
//
// Now this routine will create a listener for state changes
// in the editor and set us as the compose object of interest.
//
mDocumentListener = new nsMsgDocumentStateListener();
if (!mDocumentListener)
return NS_ERROR_OUT_OF_MEMORY;
mDocumentListener->SetComposeObj(this);
NS_ADDREF(mDocumentListener);
mDocumentListener->SetComposeObj(this);
NS_ADDREF(mDocumentListener);
// Make sure we setup to listen for editor state changes...
m_editor->RegisterDocumentStateListener(mDocumentListener);
// Make sure we setup to listen for editor state changes...
m_editor->RegisterDocumentStateListener(mDocumentListener);
// Now, lets init the editor here!
// Just get a blank editor started...
m_editor->LoadUrl(nsAutoString("about:blank").GetUnicode());
// Now, lets init the editor here!
// Just get a blank editor started...
m_editor->LoadUrl(nsAutoString("about:blank").GetUnicode());
return NS_OK;
return NS_OK;
}
nsresult nsMsgCompose::GetBodyModified(PRBool * modified)
@ -941,6 +935,37 @@ nsresult nsMsgCompose::CreateMessage(const PRUnichar * originalMsgURI,
rv = m_compFields->Copy(compFields);
return rv;
}
if (m_identity)
{
/* Setup reply-to field */
nsXPIDLCString replyTo;
m_identity->GetReplyTo(getter_Copies(replyTo));
m_compFields->SetReplyTo(replyTo);
/* Setup bcc field */
PRBool aBool;
nsString bccStr;
m_identity->GetBccSelf(&aBool);
if (aBool)
{
nsXPIDLCString email;
m_identity->GetEmail(getter_Copies(email));
bccStr = email;
}
m_identity->GetBccOthers(&aBool);
if (aBool)
{
nsXPIDLCString bccList;
m_identity->GetBccList(getter_Copies(bccList));
if (bccStr.Length() > 0)
bccStr += ',';
bccStr += bccList;
}
m_compFields->SetBcc(bccStr.GetUnicode());
}
/* In case of forwarding multiple messages, originalMsgURI will contains several URI separated by a comma. */
/* we need to extract only the first URI*/
@ -969,6 +994,8 @@ nsresult nsMsgCompose::CreateMessage(const PRUnichar * originalMsgURI,
default: break;
case nsIMsgCompType::Reply :
case nsIMsgCompType::ReplyAll:
case nsIMsgCompType::ReplyToGroup:
case nsIMsgCompType::ReplyToSenderAndGroup:
{
mQuotingToFollow = PR_TRUE;
NS_WITH_SERVICE(nsIPref, prefs, kPrefCID, &rv);
@ -1186,7 +1213,8 @@ NS_IMETHODIMP QuotingOutputStreamListener::OnStopRequest(nsIChannel *aChannel, n
if (mCiteReference != "")
mComposeObj->mCiteReference = mCiteReference;
if (mHeaders && (type == nsIMsgCompType::Reply || type == nsIMsgCompType::ReplyAll))
if (mHeaders && (type == nsIMsgCompType::Reply || type == nsIMsgCompType::ReplyAll ||
type == nsIMsgCompType::ReplyToGroup || type == nsIMsgCompType::ReplyToSenderAndGroup))
{
nsIMsgCompFields *compFields = nsnull;
mComposeObj->GetCompFields(&compFields); //GetCompFields will addref, you need to release when your are done with it
@ -1250,8 +1278,9 @@ NS_IMETHODIMP QuotingOutputStreamListener::OnStopRequest(nsIChannel *aChannel, n
if (! newgroups.IsEmpty())
{
compFields->SetNewsgroups(newgroups.GetUnicode());
if (type == nsIMsgCompType::Reply)
if (type != nsIMsgCompType::Reply)
compFields->SetNewsgroups(newgroups.GetUnicode());
if (type == nsIMsgCompType::ReplyToGroup)
compFields->SetTo(&emptyUnichar);
}
@ -2015,6 +2044,8 @@ nsMsgCompose::BuildBodyMessageAndSignature()
case nsIMsgCompType::ForwardAsAttachment : /* should not append! but just in case */
case nsIMsgCompType::ForwardInline :
case nsIMsgCompType::NewsPost :
case nsIMsgCompType::ReplyToGroup :
case nsIMsgCompType::ReplyToSenderAndGroup :
addSignature = PR_TRUE;
break;
@ -2101,7 +2132,7 @@ nsresult nsMsgCompose::AttachmentPrettyName(const PRUnichar* url, PRUnichar** _r
if (leafName && *leafName)
{
nsAutoString tempStr;
nsresult rv = ConvertToUnicode(msgCompFileSystemCharset(), leafName, tempStr);
nsresult rv = ConvertToUnicode(nsMsgI18NFileSystemCharset(), leafName, tempStr);
if (NS_FAILED(rv))
tempStr = leafName;
*_retval = tempStr.ToNewUnicode();
@ -2273,3 +2304,72 @@ nsresult nsMsgCompose::GetNoHtmlNewsgroups(const PRUnichar *newsgroups, PRUnicha
*_retval = nsnull;
return rv;
}
nsresult nsMsgCompose::ResetNodeEventHandlers(nsIDOMNode *node)
{
// Because event handler attributes set into a node before this node is inserted
// into the DOM are not recognised (in fact not compiled), we need to parsed again
// the whole node and reset event handlers.
nsresult rv;
nsAutoString aStr;
PRUint32 i;
PRUint32 nbrOfElements;
nsCOMPtr<nsIDOMNode> pItem;
if (nsnull == node)
return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsIDOMNamedNodeMap> pAttributes;
rv = node->GetAttributes(getter_AddRefs(pAttributes));
if (NS_SUCCEEDED(rv) && pAttributes)
{
rv = pAttributes->GetLength(&nbrOfElements);
if (NS_FAILED(rv))
return rv;
for (i = 0; i < nbrOfElements; i ++)
{
rv = pAttributes->Item(i, getter_AddRefs(pItem));
if (NS_SUCCEEDED(rv) && pItem)
{
rv = pItem->GetNodeName(aStr);
if (NS_SUCCEEDED(rv))
{
if (aStr.Find("on", PR_FALSE, 0, 2) == 0) //name start with "on"
{
rv = pItem->GetNodeValue(aStr);
if (NS_SUCCEEDED(rv))
rv = pItem->SetNodeValue(aStr);
//Do not abort if it failed, let do the next one...
}
}
}
}
PRBool hasChild;
rv = node->HasChildNodes(&hasChild);
if (NS_SUCCEEDED(rv) && hasChild)
{
nsCOMPtr<nsIDOMNodeList> children;
rv = node->GetChildNodes(getter_AddRefs(children));
if (NS_SUCCEEDED(rv) && children)
{
rv = children->GetLength(&nbrOfElements);
if (NS_FAILED(rv))
return rv;
for (i = 0; i < nbrOfElements; i ++)
{
rv = children->Item(i, getter_AddRefs(pItem));
if (NS_SUCCEEDED(rv) && pItem)
ResetNodeEventHandlers(pItem);
//Do not abort if it failed, let do the next one...
}
}
}
}
return rv;
}

View File

@ -218,7 +218,7 @@ nsMsgLocalMailFolder::CreateSubFolders(nsFileSpec &path)
nsresult rv = NS_OK;
nsAutoString currentFolderNameStr;
nsAutoString convertedFolderNameStr;
const nsString fileCharset = msgCompFileSystemCharset();
const nsString fileCharset = nsMsgI18NFileSystemCharset();
nsCOMPtr<nsIMsgFolder> child;
char *folderName;
for (nsDirectoryIterator dir(path, PR_FALSE); dir.Exists(); dir++) {

View File

@ -216,7 +216,7 @@ mime_dump_attachments ( attachmentList );
curAttachment++;
}
if (attachments.Length())
compFields->SetAttachments(attachments.ToNewUnicode());
compFields->SetAttachments(attachments.GetUnicode());
}
NS_WITH_SERVICE(nsIMsgComposeService, msgComposeService,
@ -1338,7 +1338,11 @@ mime_parse_stream_complete (nsMIMESession *stream)
if (mdd->forwardInline)
CreateTheComposeWindow(fields, newAttachData, nsIMsgCompType::ForwardInline, composeFormat, mdd->identity);
else
{
nsString urlStr(mdd->url_name);
fields->SetDraftId(urlStr.GetUnicode());
CreateTheComposeWindow(fields, newAttachData, nsIMsgCompType::Draft, composeFormat, mdd->identity);
}
}
PR_FREEIF(body);
@ -1365,7 +1369,11 @@ mime_parse_stream_complete (nsMIMESession *stream)
if (mdd->forwardInline)
CreateTheComposeWindow(fields, newAttachData, nsIMsgCompType::ForwardInline, nsIMsgCompFormat::Default, mdd->identity);
else
{
nsString urlStr(mdd->url_name);
fields->SetDraftId(urlStr.GetUnicode());
CreateTheComposeWindow(fields, newAttachData, nsIMsgCompType::Draft, nsIMsgCompFormat::Default, mdd->identity);
}
}
}
}
@ -1640,7 +1648,7 @@ mime_decompose_file_init_fn ( void *stream_closure, MimeHeaders *headers )
nsresult rv = ConvertToUnicode(msgCompHeaderInternalCharset(), newAttachment->real_name, outStr);
if (NS_SUCCEEDED(rv))
{
rv = ConvertFromUnicode(msgCompFileSystemCharset(), outStr, &fileName);
rv = ConvertFromUnicode(nsMsgI18NFileSystemCharset(), outStr, &fileName);
if (NS_FAILED(rv))
fileName = PL_strdup(newAttachment->real_name);
}