Bug 337155 SeaMonkey missing spellcheck language selector in mail compose window and preferences also backporting enhancements to Thunderbird
p=me r=mnyromyr(SM)/mscott(TB) sr=neil git-svn-id: svn://10.0.0.236/trunk@201311 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
@@ -44,12 +44,14 @@ var gAllowSelectWord = true;
|
||||
var gPreviousReplaceWord = "";
|
||||
var gFirstTime = true;
|
||||
var gLastSelectedLang = null;
|
||||
var gDictCount = 0;
|
||||
|
||||
function Startup()
|
||||
{
|
||||
var sendMailMessageMode = false;
|
||||
|
||||
if (!GetCurrentEditor())
|
||||
var editor = GetCurrentEditor();
|
||||
if (!editor)
|
||||
{
|
||||
window.close();
|
||||
return;
|
||||
@@ -78,11 +80,8 @@ function Startup()
|
||||
filterContractId = "@mozilla.org/editor/txtsrvfilter;1";
|
||||
|
||||
gSpellChecker.setFilter(Components.classes[filterContractId].createInstance(Components.interfaces.nsITextServicesFilter));
|
||||
gSpellChecker.InitSpellChecker(GetCurrentEditor(), enableSelectionChecking);
|
||||
gSpellChecker.InitSpellChecker(editor, enableSelectionChecking);
|
||||
|
||||
// XXX: We need to read in a pref here so we can set the
|
||||
// default language for the spellchecker!
|
||||
// gSpellChecker.SetCurrentDictionary();
|
||||
}
|
||||
catch(ex) {
|
||||
dump("*** Exception error: InitSpellChecker\n");
|
||||
@@ -146,7 +145,7 @@ function Startup()
|
||||
gFirstTime = false;
|
||||
}
|
||||
|
||||
function InitLanguageMenu(curLang)
|
||||
function InitLanguageMenu(aCurLang)
|
||||
{
|
||||
|
||||
var o1 = {};
|
||||
@@ -155,9 +154,12 @@ function InitLanguageMenu(curLang)
|
||||
// Get the list of dictionaries from
|
||||
// the spellchecker.
|
||||
|
||||
try {
|
||||
try
|
||||
{
|
||||
gSpellChecker.GetDictionaryList(o1, o2);
|
||||
} catch(ex) {
|
||||
}
|
||||
catch(ex)
|
||||
{
|
||||
dump("Failed to get DictionaryList!\n");
|
||||
return;
|
||||
}
|
||||
@@ -165,65 +167,84 @@ function InitLanguageMenu(curLang)
|
||||
var dictList = o1.value;
|
||||
var count = o2.value;
|
||||
|
||||
// If we're not just starting up and dictionary count
|
||||
// hasn't changed then no need to update the menu.
|
||||
if (gDictCount == count)
|
||||
return;
|
||||
|
||||
// Store current dictionary count.
|
||||
gDictCount = count;
|
||||
|
||||
// Load the string bundles that will help us map
|
||||
// RFC 1766 strings to UI strings.
|
||||
|
||||
// Load the language string bundle.
|
||||
var languageBundle = document.getElementById("languageBundle");
|
||||
var regionBundle;
|
||||
var regionBundle = null;
|
||||
// If we have a language string bundle, load the region string bundle.
|
||||
if (languageBundle)
|
||||
regionBundle = document.getElementById("regionBundle");
|
||||
|
||||
var menuStr2;
|
||||
var isoStrArray;
|
||||
var defaultItem = null;
|
||||
var langId;
|
||||
var langLabel;
|
||||
var i;
|
||||
for (i = 0; i < dictList.length; i++)
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
try {
|
||||
try
|
||||
{
|
||||
langId = dictList[i];
|
||||
isoStrArray = dictList[i].split("-");
|
||||
|
||||
dictList[i] = new Array(2); // first subarray element - pretty name
|
||||
dictList[i][1] = langId; // second subarray element - language ID
|
||||
|
||||
if (languageBundle && isoStrArray[0])
|
||||
dictList[i][0] = languageBundle.getString(isoStrArray[0].toLowerCase());
|
||||
langLabel = languageBundle.getString(isoStrArray[0].toLowerCase());
|
||||
|
||||
if (regionBundle && dictList[i][0] && isoStrArray.length > 1 && isoStrArray[1])
|
||||
if (regionBundle && langLabel && isoStrArray.length > 1 && isoStrArray[1])
|
||||
{
|
||||
menuStr2 = regionBundle.getString(isoStrArray[1].toLowerCase());
|
||||
if (menuStr2)
|
||||
dictList[i][0] = dictList[i][0] + "/" + menuStr2;
|
||||
langLabel += "/" + menuStr2;
|
||||
}
|
||||
|
||||
if (!dictList[i][0])
|
||||
dictList[i][0] = dictList[i][1];
|
||||
} catch (ex) {
|
||||
// GetString throws an exception when
|
||||
// a key is not found in the bundle. In that
|
||||
// case, just use the original dictList string.
|
||||
|
||||
dictList[i][0] = dictList[i][1];
|
||||
if (!langLabel)
|
||||
langLabel = langId;
|
||||
}
|
||||
catch (ex)
|
||||
{
|
||||
// getString throws an exception when a key is not found in the
|
||||
// bundle. In that case, just use the original dictList string.
|
||||
langLabel = langId;
|
||||
}
|
||||
dictList[i] = [langLabel, langId];
|
||||
}
|
||||
|
||||
// note this is not locale-aware collation, just simple ASCII-based sorting
|
||||
// we really need to add loacel-aware JS collation, see bug XXXXX
|
||||
dictList.sort();
|
||||
// sort by locale-aware collation
|
||||
dictList.sort(
|
||||
function compareFn(a, b)
|
||||
{
|
||||
return a[0].localeCompare(b[0]);
|
||||
}
|
||||
);
|
||||
|
||||
for (i = 0; i < dictList.length; i++)
|
||||
// Remove any languages from the list.
|
||||
var languageMenuPopup = gDialog.LanguageMenulist.firstChild;
|
||||
while (languageMenuPopup.firstChild.localName != "menuseparator")
|
||||
languageMenuPopup.removeChild(languageMenuPopup.firstChild);
|
||||
|
||||
var defaultItem = null;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
var item = gDialog.LanguageMenulist.appendItem(dictList[i][0], dictList[i][1]);
|
||||
if (curLang && dictList[i][1] == curLang)
|
||||
var item = gDialog.LanguageMenulist.insertItemAt(i, dictList[i][0], dictList[i][1]);
|
||||
if (aCurLang && dictList[i][1] == aCurLang)
|
||||
defaultItem = item;
|
||||
}
|
||||
|
||||
// Now make sure the correct item in the menu list is selected.
|
||||
|
||||
if (defaultItem) {
|
||||
if (defaultItem)
|
||||
{
|
||||
gDialog.LanguageMenulist.selectedItem = defaultItem;
|
||||
gLastSelectedLang = defaultItem;
|
||||
}
|
||||
@@ -448,7 +469,6 @@ function Recheck()
|
||||
//TODO: Should we bother to add a "Recheck" method to interface?
|
||||
try {
|
||||
var curLang = gSpellChecker.GetCurrentDictionary();
|
||||
|
||||
gSpellChecker.UninitSpellChecker();
|
||||
gSpellChecker.InitSpellChecker(GetCurrentEditor(), false);
|
||||
gSpellChecker.SetCurrentDictionary(curLang);
|
||||
@@ -535,14 +555,34 @@ function doDefault()
|
||||
return false;
|
||||
}
|
||||
|
||||
function CancelSpellCheck()
|
||||
function ExitSpellChecker()
|
||||
{
|
||||
if (gSpellChecker)
|
||||
{
|
||||
try {
|
||||
try
|
||||
{
|
||||
var curLang = gSpellChecker.GetCurrentDictionary();
|
||||
gSpellChecker.UninitSpellChecker();
|
||||
} finally { gSpellChecker = null; }
|
||||
if ("@mozilla.org/spellchecker;1" in Components.classes) {
|
||||
var spellChecker = Components.classes["@mozilla.org/spellchecker/myspell;1"]
|
||||
.getService(Components.interfaces.mozISpellCheckingEngine);
|
||||
spellChecker.dictionary = curLang;
|
||||
}
|
||||
// now check the document over again with the new dictionary
|
||||
if ("inlineSpellChecker" in window.opener.InlineSpellChecker)
|
||||
if (window.opener.InlineSpellChecker.inlineSpellChecker.enableRealTimeSpell)
|
||||
window.opener.InlineSpellChecker.checkDocument(window.opener.content.document);
|
||||
}
|
||||
finally
|
||||
{
|
||||
gSpellChecker = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function CancelSpellCheck()
|
||||
{
|
||||
ExitSpellChecker();
|
||||
|
||||
// Signal to calling window that we canceled
|
||||
window.opener.cancelSendMessage = true;
|
||||
@@ -551,12 +591,8 @@ function CancelSpellCheck()
|
||||
|
||||
function onClose()
|
||||
{
|
||||
if (gSpellChecker)
|
||||
{
|
||||
try {
|
||||
gSpellChecker.UninitSpellChecker();
|
||||
} finally { gSpellChecker = null; }
|
||||
}
|
||||
ExitSpellChecker();
|
||||
|
||||
window.opener.cancelSendMessage = false;
|
||||
window.close();
|
||||
}
|
||||
|
||||
@@ -127,10 +127,10 @@
|
||||
accesskey="&languagePopup.accessKey;"/>
|
||||
<row>
|
||||
<menulist id="LanguageMenulist" oncommand="SelectLanguage()">
|
||||
<menupopup>
|
||||
<menuitem value="more-cmd" label="&moreDictionaries.label;"/>
|
||||
<menuseparator/>
|
||||
<menupopup onpopupshowing="InitLanguageMenu(gDialog.LanguageMenulist.selectedItem.value);">
|
||||
<!-- dynamic content populated by JS -->
|
||||
<menuseparator/>
|
||||
<menuitem value="more-cmd" label="&moreDictionaries.label;"/>
|
||||
</menupopup>
|
||||
</menulist>
|
||||
<hbox flex="1">
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
<!ENTITY stopButton.label "Stop">
|
||||
<!ENTITY stopButton.accessKey "t">
|
||||
<!ENTITY userDictionary.label "Personal Dictionary:">
|
||||
<!ENTITY moreDictionaries.label "Download More">
|
||||
<!ENTITY moreDictionaries.label "Download more dictionaries...">
|
||||
<!ENTITY addToUserDictionaryButton.label "Add Word">
|
||||
<!ENTITY addToUserDictionaryButton.accessKey "d">
|
||||
<!ENTITY editUserDictionaryButton.label "Edit...">
|
||||
|
||||
@@ -4559,12 +4559,6 @@ to filter unwanted mail.</p>
|
||||
<li><strong>Forward Messages</strong>: Choose how you want forwarded
|
||||
message text to appear: as an attachment or <em>inline</em> (in the body
|
||||
of your message).</li>
|
||||
<li><strong>Check spelling before sending</strong>: Select this option to
|
||||
have Mail & Newsgroups always check the spelling of your message before
|
||||
you send it.</li>
|
||||
<li><strong>Check spelling as you type</strong>: Select this option to have
|
||||
Mail & Newsgroups always check the spelling of your message as you type
|
||||
it.</li>
|
||||
<li><strong>Automatically save the message every ___ minutes</strong>: Choose
|
||||
this option if you want Mail & Newsgroups to save the message you are
|
||||
currently composing automatically at the given interval. After a computer
|
||||
@@ -4577,6 +4571,15 @@ to filter unwanted mail.</p>
|
||||
keyboard shortcut by mistake when composing a message.</li>
|
||||
<li><strong>Wrap plain text messages at ___ characters</strong>: Enter a
|
||||
number to set the right margin for text in the message area.</li>
|
||||
<li><strong>Check spelling before sending</strong>: Select this option to
|
||||
have Mail & Newsgroups always check the spelling of your message before
|
||||
you send it.</li>
|
||||
<li><strong>Check spelling as you type</strong>: Select this option to have
|
||||
Mail & Newsgroups always check the spelling of your message as you type
|
||||
it.</li>
|
||||
<li><strong>Language</strong>: Use the drop-down list to select the language
|
||||
you want to use to check the spelling in your messages or to download more
|
||||
dictionaries.</li>
|
||||
<li><strong>Defaults for HTML Messages</strong>: Here you can define what the
|
||||
defaults are for font, size, text and background color if you choose to
|
||||
send mails in HTML format.</li>
|
||||
|
||||
@@ -44,12 +44,14 @@ var gAllowSelectWord = true;
|
||||
var gPreviousReplaceWord = "";
|
||||
var gFirstTime = true;
|
||||
var gLastSelectedLang = null;
|
||||
var gDictCount = 0;
|
||||
|
||||
function Startup()
|
||||
{
|
||||
var sendMailMessageMode = false;
|
||||
|
||||
if (!GetCurrentEditor())
|
||||
var editor = GetCurrentEditor();
|
||||
if (!editor)
|
||||
{
|
||||
window.close();
|
||||
return;
|
||||
@@ -78,11 +80,8 @@ function Startup()
|
||||
filterContractId = "@mozilla.org/editor/txtsrvfilter;1";
|
||||
|
||||
gSpellChecker.setFilter(Components.classes[filterContractId].createInstance(Components.interfaces.nsITextServicesFilter));
|
||||
gSpellChecker.InitSpellChecker(GetCurrentEditor(), enableSelectionChecking);
|
||||
gSpellChecker.InitSpellChecker(editor, enableSelectionChecking);
|
||||
|
||||
// XXX: We need to read in a pref here so we can set the
|
||||
// default language for the spellchecker!
|
||||
// gSpellChecker.SetCurrentDictionary();
|
||||
}
|
||||
catch(ex) {
|
||||
dump("*** Exception error: InitSpellChecker\n");
|
||||
@@ -146,7 +145,7 @@ function Startup()
|
||||
gFirstTime = false;
|
||||
}
|
||||
|
||||
function InitLanguageMenu(curLang)
|
||||
function InitLanguageMenu(aCurLang)
|
||||
{
|
||||
|
||||
var o1 = {};
|
||||
@@ -155,9 +154,12 @@ function InitLanguageMenu(curLang)
|
||||
// Get the list of dictionaries from
|
||||
// the spellchecker.
|
||||
|
||||
try {
|
||||
try
|
||||
{
|
||||
gSpellChecker.GetDictionaryList(o1, o2);
|
||||
} catch(ex) {
|
||||
}
|
||||
catch(ex)
|
||||
{
|
||||
dump("Failed to get DictionaryList!\n");
|
||||
return;
|
||||
}
|
||||
@@ -165,65 +167,83 @@ function InitLanguageMenu(curLang)
|
||||
var dictList = o1.value;
|
||||
var count = o2.value;
|
||||
|
||||
// If dictionary count hasn't changed then no need to update the menu.
|
||||
if (gDictCount == count)
|
||||
return;
|
||||
|
||||
// Store current dictionary count.
|
||||
gDictCount = count;
|
||||
|
||||
// Load the string bundles that will help us map
|
||||
// RFC 1766 strings to UI strings.
|
||||
|
||||
// Load the language string bundle.
|
||||
var languageBundle = document.getElementById("languageBundle");
|
||||
var regionBundle;
|
||||
var regionBundle = null;
|
||||
// If we have a language string bundle, load the region string bundle.
|
||||
if (languageBundle)
|
||||
regionBundle = document.getElementById("regionBundle");
|
||||
|
||||
var menuStr2;
|
||||
var isoStrArray;
|
||||
var defaultItem = null;
|
||||
var langId;
|
||||
var langLabel;
|
||||
var i;
|
||||
for (i = 0; i < dictList.length; i++)
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
try {
|
||||
try
|
||||
{
|
||||
langId = dictList[i];
|
||||
isoStrArray = dictList[i].split("-");
|
||||
|
||||
dictList[i] = new Array(2); // first subarray element - pretty name
|
||||
dictList[i][1] = langId; // second subarray element - language ID
|
||||
|
||||
if (languageBundle && isoStrArray[0])
|
||||
dictList[i][0] = languageBundle.getString(isoStrArray[0].toLowerCase());
|
||||
langLabel = languageBundle.getString(isoStrArray[0].toLowerCase());
|
||||
|
||||
if (regionBundle && dictList[i][0] && isoStrArray.length > 1 && isoStrArray[1])
|
||||
if (regionBundle && langLabel && isoStrArray.length > 1 && isoStrArray[1])
|
||||
{
|
||||
menuStr2 = regionBundle.getString(isoStrArray[1].toLowerCase());
|
||||
if (menuStr2)
|
||||
dictList[i][0] = dictList[i][0] + "/" + menuStr2;
|
||||
langLabel += "/" + menuStr2;
|
||||
}
|
||||
|
||||
if (!dictList[i][0])
|
||||
dictList[i][0] = dictList[i][1];
|
||||
} catch (ex) {
|
||||
// GetString throws an exception when
|
||||
// a key is not found in the bundle. In that
|
||||
// case, just use the original dictList string.
|
||||
|
||||
dictList[i][0] = dictList[i][1];
|
||||
if (!langLabel)
|
||||
langLabel = langId;
|
||||
}
|
||||
catch (ex)
|
||||
{
|
||||
// getString throws an exception when a key is not found in the
|
||||
// bundle. In that case, just use the original dictList string.
|
||||
langLabel = langId;
|
||||
}
|
||||
dictList[i] = [langLabel, langId];
|
||||
}
|
||||
|
||||
// note this is not locale-aware collation, just simple ASCII-based sorting
|
||||
// we really need to add loacel-aware JS collation, see bug XXXXX
|
||||
dictList.sort();
|
||||
// sort by locale-aware collation
|
||||
dictList.sort(
|
||||
function compareFn(a, b)
|
||||
{
|
||||
return a[0].localeCompare(b[0]);
|
||||
}
|
||||
);
|
||||
|
||||
for (i = 0; i < dictList.length; i++)
|
||||
// Remove any languages from the list.
|
||||
var languageMenuPopup = gDialog.LanguageMenulist.firstChild;
|
||||
while (languageMenuPopup.firstChild.localName != "menuseparator")
|
||||
languageMenuPopup.removeChild(languageMenuPopup.firstChild);
|
||||
|
||||
var defaultItem = null;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
var item = gDialog.LanguageMenulist.appendItem(dictList[i][0], dictList[i][1]);
|
||||
if (curLang && dictList[i][1] == curLang)
|
||||
var item = gDialog.LanguageMenulist.insertItemAt(i, dictList[i][0], dictList[i][1]);
|
||||
if (aCurLang && dictList[i][1] == aCurLang)
|
||||
defaultItem = item;
|
||||
}
|
||||
|
||||
// Now make sure the correct item in the menu list is selected.
|
||||
|
||||
if (defaultItem) {
|
||||
if (defaultItem)
|
||||
{
|
||||
gDialog.LanguageMenulist.selectedItem = defaultItem;
|
||||
gLastSelectedLang = defaultItem;
|
||||
}
|
||||
@@ -452,7 +472,6 @@ function Recheck()
|
||||
//TODO: Should we bother to add a "Recheck" method to interface?
|
||||
try {
|
||||
var curLang = gSpellChecker.GetCurrentDictionary();
|
||||
|
||||
gSpellChecker.UninitSpellChecker();
|
||||
gSpellChecker.InitSpellChecker(GetCurrentEditor(), false);
|
||||
gSpellChecker.SetCurrentDictionary(curLang);
|
||||
@@ -539,14 +558,34 @@ function doDefault()
|
||||
return false;
|
||||
}
|
||||
|
||||
function CancelSpellCheck()
|
||||
function ExitSpellChecker()
|
||||
{
|
||||
if (gSpellChecker)
|
||||
{
|
||||
try {
|
||||
try
|
||||
{
|
||||
var curLang = gSpellChecker.GetCurrentDictionary();
|
||||
gSpellChecker.UninitSpellChecker();
|
||||
} finally { gSpellChecker = null; }
|
||||
if ("@mozilla.org/spellchecker;1" in Components.classes) {
|
||||
var spellChecker = Components.classes["@mozilla.org/spellchecker/myspell;1"]
|
||||
.getService(Components.interfaces.mozISpellCheckingEngine);
|
||||
spellChecker.dictionary = curLang;
|
||||
}
|
||||
// now check the document over again with the new dictionary
|
||||
if ("inlineSpellChecker" in window.opener.InlineSpellChecker)
|
||||
if (window.opener.InlineSpellChecker.inlineSpellChecker.enableRealTimeSpell)
|
||||
window.opener.InlineSpellChecker.checkDocument(window.opener.content.document);
|
||||
}
|
||||
finally
|
||||
{
|
||||
gSpellChecker = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function CancelSpellCheck()
|
||||
{
|
||||
ExitSpellChecker();
|
||||
|
||||
// Signal to calling window that we canceled
|
||||
window.opener.cancelSendMessage = true;
|
||||
@@ -555,12 +594,8 @@ function CancelSpellCheck()
|
||||
|
||||
function onClose()
|
||||
{
|
||||
if (gSpellChecker)
|
||||
{
|
||||
try {
|
||||
gSpellChecker.UninitSpellChecker();
|
||||
} finally { gSpellChecker = null; }
|
||||
}
|
||||
ExitSpellChecker();
|
||||
|
||||
window.opener.cancelSendMessage = false;
|
||||
window.close();
|
||||
}
|
||||
|
||||
@@ -39,14 +39,15 @@
|
||||
/**
|
||||
* interfaces
|
||||
*/
|
||||
var nsIMsgCompDeliverMode = Components.interfaces.nsIMsgCompDeliverMode;
|
||||
var nsIMsgCompSendFormat = Components.interfaces.nsIMsgCompSendFormat;
|
||||
var nsIMsgCompConvertible = Components.interfaces.nsIMsgCompConvertible;
|
||||
var nsIMsgCompType = Components.interfaces.nsIMsgCompType;
|
||||
var nsIMsgCompFormat = Components.interfaces.nsIMsgCompFormat;
|
||||
var nsIAbPreferMailFormat = Components.interfaces.nsIAbPreferMailFormat;
|
||||
var nsIPlaintextEditorMail = Components.interfaces.nsIPlaintextEditor;
|
||||
|
||||
const nsIMsgCompDeliverMode = Components.interfaces.nsIMsgCompDeliverMode;
|
||||
const nsIMsgCompSendFormat = Components.interfaces.nsIMsgCompSendFormat;
|
||||
const nsIMsgCompConvertible = Components.interfaces.nsIMsgCompConvertible;
|
||||
const nsIMsgCompType = Components.interfaces.nsIMsgCompType;
|
||||
const nsIMsgCompFormat = Components.interfaces.nsIMsgCompFormat;
|
||||
const nsIAbPreferMailFormat = Components.interfaces.nsIAbPreferMailFormat;
|
||||
const nsIPlaintextEditorMail = Components.interfaces.nsIPlaintextEditor;
|
||||
const nsISupportsString = Components.interfaces.nsISupportsString;
|
||||
const mozISpellCheckingEngine = Components.interfaces.mozISpellCheckingEngine;
|
||||
|
||||
/**
|
||||
* In order to distinguish clearly globals that are initialized once when js load (static globals) and those that need to be
|
||||
@@ -66,6 +67,7 @@ var sOther_headers = "";
|
||||
var sAccountManagerDataSource = null;
|
||||
var sRDF = null;
|
||||
var sNameProperty = null;
|
||||
var sDictCount = 0;
|
||||
|
||||
/* Create message window object. This is use by mail-offline.js and therefore should not be renamed. We need to avoid doing
|
||||
this kind of cross file global stuff in the future and instead pass this object as parameter when needed by function
|
||||
@@ -1361,7 +1363,6 @@ function ComposeStartup(recycled, aParams)
|
||||
|
||||
// Do setup common to Message Composer and Web Composer
|
||||
EditorSharedStartup();
|
||||
initLanguageMenu();
|
||||
}
|
||||
|
||||
var msgCompFields = gMsgCompose.compFields;
|
||||
@@ -2188,12 +2189,14 @@ function ToggleInlineSpellChecker(target)
|
||||
}
|
||||
}
|
||||
|
||||
function initLanguageMenu()
|
||||
function InitLanguageMenu()
|
||||
{
|
||||
var languageMenuList = document.getElementById('LanguageMenulist');
|
||||
if (!languageMenuList) return;
|
||||
var languageMenuList = document.getElementById('languageMenuList');
|
||||
if (!languageMenuList)
|
||||
return;
|
||||
|
||||
var spellChecker = Components.classes['@mozilla.org/spellchecker/myspell;1'].getService(Components.interfaces.mozISpellCheckingEngine);
|
||||
var spellChecker = Components.classes['@mozilla.org/spellchecker/myspell;1']
|
||||
.getService(mozISpellCheckingEngine);
|
||||
var o1 = {};
|
||||
var o2 = {};
|
||||
|
||||
@@ -2205,87 +2208,100 @@ function initLanguageMenu()
|
||||
var dictList = o1.value;
|
||||
var count = o2.value;
|
||||
|
||||
// Load the string bundles that will help us map
|
||||
// RFC 1766 strings to UI strings.
|
||||
// If dictionary count hasn't changed then no need to update the menu.
|
||||
if (sDictCount == count)
|
||||
return;
|
||||
|
||||
// Load the language string bundle.
|
||||
// Store current dictionary count.
|
||||
sDictCount = count;
|
||||
|
||||
// Load the string bundle that will help us map
|
||||
// RFC 1766 strings to UI strings.
|
||||
var languageBundle = document.getElementById("languageBundle");
|
||||
var isoStrArray;
|
||||
var langId;
|
||||
var langLabel;
|
||||
var i;
|
||||
|
||||
for (i = 0; i < dictList.length; i++)
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
try {
|
||||
try
|
||||
{
|
||||
langId = dictList[i];
|
||||
isoStrArray = dictList[i].split("-");
|
||||
|
||||
dictList[i] = new Array(2); // first subarray element - pretty name
|
||||
dictList[i][1] = langId; // second subarray element - language ID
|
||||
|
||||
if (languageBundle && isoStrArray[0])
|
||||
dictList[i][0] = languageBundle.getString(isoStrArray[0].toLowerCase());
|
||||
langLabel = languageBundle.getString(isoStrArray[0].toLowerCase());
|
||||
|
||||
// the user needs to be able to distinguish between the UK English dictionary
|
||||
// and say the United States English Dictionary. If we have a isoStr value then
|
||||
// wrap it in parentheses and append it to the menu item string. i.e.
|
||||
// English (US) and English (UK)
|
||||
if (!dictList[i][0])
|
||||
dictList[i][0] = dictList[i][1];
|
||||
if (!langLabel)
|
||||
langLabel = langId;
|
||||
else if (isoStrArray.length > 1 && isoStrArray[1]) // if we have a language ID like US or UK, append it to the menu item
|
||||
dictList[i][0] += ' (' + isoStrArray[1] + ')';
|
||||
} catch (ex) {
|
||||
// GetString throws an exception when
|
||||
// a key is not found in the bundle. In that
|
||||
// case, just use the original dictList string.
|
||||
|
||||
dictList[i][0] = dictList[i][1];
|
||||
langLabel += ' (' + isoStrArray[1] + ')';
|
||||
}
|
||||
catch (ex)
|
||||
{
|
||||
// getString throws an exception when a key is not found in the
|
||||
// bundle. In that case, just use the original dictList string.
|
||||
langLabel = langId;
|
||||
}
|
||||
dictList[i] = [langLabel, langId];
|
||||
}
|
||||
|
||||
// note this is not locale-aware collation, just simple ASCII-based sorting
|
||||
// we really need to add locale-aware JS collation
|
||||
dictList.sort();
|
||||
// sort by locale-aware collation
|
||||
dictList.sort(
|
||||
function compareFn(a, b)
|
||||
{
|
||||
return a[0].localeCompare(b[0]);
|
||||
}
|
||||
);
|
||||
|
||||
// now select the dictionary we are currently using
|
||||
for (i = 0; i < dictList.length; i++)
|
||||
// Remove any languages from the list.
|
||||
while (languageMenuList.hasChildNodes())
|
||||
languageMenuList.removeChild(languageMenuList.firstChild);
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
var item = document.createElement("menuitem");
|
||||
item.setAttribute("label", dictList[i][0]);
|
||||
item.setAttribute("value", dictList[i][1]);
|
||||
item.setAttribute('type', 'radio');
|
||||
item.setAttribute('oncommand', "changeLanguage(event)");
|
||||
languageMenuList.appendChild(item);
|
||||
}
|
||||
}
|
||||
|
||||
function onShowDictionaryMenu()
|
||||
function OnShowDictionaryMenu(aTarget)
|
||||
{
|
||||
var curLang = sPrefs.getComplexValue("spellchecker.dictionary", Components.interfaces.nsISupportsString).data;
|
||||
var languageMenuList = document.getElementById('LanguageMenulist');
|
||||
|
||||
var languages = languageMenuList.getElementsByAttribute('value', curLang);
|
||||
languages[0].setAttribute('checked', true);
|
||||
InitLanguageMenu();
|
||||
var curLang = sPrefs.getComplexValue("spellchecker.dictionary", nsISupportsString).data;
|
||||
var languages = aTarget.getElementsByAttribute("value", curLang);
|
||||
if (languages.length > 0)
|
||||
languages[0].setAttribute("checked", true);
|
||||
}
|
||||
|
||||
function changeLanguage(event)
|
||||
function ChangeLanguage(event)
|
||||
{
|
||||
// We need to change the dictionary language and if we are using inline spell check,
|
||||
// recheck the message
|
||||
|
||||
var spellChecker = Components.classes['@mozilla.org/spellchecker/myspell;1'].getService(Components.interfaces.mozISpellCheckingEngine);
|
||||
var spellChecker = Components.classes['@mozilla.org/spellchecker/myspell;1']
|
||||
.getService(mozISpellCheckingEngine);
|
||||
if (spellChecker.dictionary != event.target.value)
|
||||
{
|
||||
spellChecker.dictionary = event.target.value;
|
||||
var str = Components.classes["@mozilla.org/supports-string;1"]
|
||||
.createInstance(Components.interfaces.nsISupportsString);
|
||||
.createInstance(nsISupportsString);
|
||||
str.data = event.target.value;
|
||||
sPrefs.setComplexValue("spellchecker.dictionary", Components.interfaces.nsISupportsString, str);
|
||||
sPrefs.setComplexValue("spellchecker.dictionary", nsISupportsString, str);
|
||||
|
||||
// now check the document over again with the new dictionary
|
||||
InlineSpellChecker.checkDocument(window.content.document);
|
||||
if (InlineSpellChecker.inlineSpellChecker)
|
||||
if (InlineSpellChecker.inlineSpellChecker.enableRealTimeSpell)
|
||||
InlineSpellChecker.checkDocument(window.content.document);
|
||||
}
|
||||
|
||||
event.stopPropagation();
|
||||
}
|
||||
|
||||
|
||||
@@ -610,9 +610,9 @@
|
||||
<toolbarbutton class="toolbarbutton-1" type="menu-button"
|
||||
id="spellingButton" label="&spellingButton.label;"
|
||||
command="cmd_spelling">
|
||||
<menupopup id="LanguageMenulist" onpopupshowing="onShowDictionaryMenu();">
|
||||
<!-- this popup gets dynamically generated -->
|
||||
</menupopup>
|
||||
<!-- this popup gets dynamically generated -->
|
||||
<menupopup id="languageMenuList" oncommand="ChangeLanguage(event);"
|
||||
onpopupshowing="OnShowDictionaryMenu(event.target);"/>
|
||||
</toolbarbutton>
|
||||
|
||||
<toolbarbutton class="toolbarbutton-1" type="menu-button"
|
||||
|
||||
@@ -45,6 +45,7 @@ var gComposePane = {
|
||||
mDirectories: null,
|
||||
mLDAPPrefsService: null,
|
||||
mSpellChecker: null,
|
||||
mDictCount : 0,
|
||||
|
||||
init: function ()
|
||||
{
|
||||
@@ -299,7 +300,6 @@ var gComposePane = {
|
||||
this.mSpellChecker = Components.classes['@mozilla.org/spellchecker/myspell;1'].getService(Components.interfaces.mozISpellCheckingEngine);
|
||||
var o1 = {};
|
||||
var o2 = {};
|
||||
var languageMenuList = document.getElementById('LanguageMenulist');
|
||||
|
||||
// Get the list of dictionaries from
|
||||
// the spellchecker.
|
||||
@@ -309,60 +309,73 @@ var gComposePane = {
|
||||
var dictList = o1.value;
|
||||
var count = o2.value;
|
||||
|
||||
// If dictionary count hasn't changed then no need to update the menu.
|
||||
if (this.mDictCount == count)
|
||||
return;
|
||||
|
||||
// Store current dictionary count.
|
||||
this.mDictCount = count;
|
||||
|
||||
// Load the string bundles that will help us map
|
||||
// RFC 1766 strings to UI strings.
|
||||
|
||||
// Load the language string bundle.
|
||||
var languageBundle = document.getElementById("languageBundle");
|
||||
var regionBundle;
|
||||
var regionBundle = null;
|
||||
// If we have a language string bundle, load the region string bundle.
|
||||
if (languageBundle)
|
||||
regionBundle = document.getElementById("regionBundle");
|
||||
|
||||
var menuStr2;
|
||||
var isoStrArray;
|
||||
var defaultItem = null;
|
||||
var langId;
|
||||
var langLabel;
|
||||
var i;
|
||||
|
||||
for (i = 0; i < dictList.length; i++)
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
try {
|
||||
langId = dictList[i];
|
||||
isoStrArray = dictList[i].split("-");
|
||||
|
||||
dictList[i] = new Array(2); // first subarray element - pretty name
|
||||
dictList[i][1] = langId; // second subarray element - language ID
|
||||
|
||||
if (languageBundle && isoStrArray[0])
|
||||
dictList[i][0] = languageBundle.getString(isoStrArray[0].toLowerCase());
|
||||
langLabel = languageBundle.getString(isoStrArray[0].toLowerCase());
|
||||
|
||||
if (regionBundle && dictList[i][0] && isoStrArray.length > 1 && isoStrArray[1])
|
||||
if (regionBundle && langLabel && isoStrArray.length > 1 && isoStrArray[1])
|
||||
{
|
||||
menuStr2 = regionBundle.getString(isoStrArray[1].toLowerCase());
|
||||
if (menuStr2)
|
||||
dictList[i][0] = dictList[i][0] + "/" + menuStr2;
|
||||
langLabel += "/" + menuStr2;
|
||||
}
|
||||
|
||||
if (!dictList[i][0])
|
||||
dictList[i][0] = dictList[i][1];
|
||||
if (!langLabel)
|
||||
langLabel = langId;
|
||||
} catch (ex) {
|
||||
// GetString throws an exception when
|
||||
// a key is not found in the bundle. In that
|
||||
// case, just use the original dictList string.
|
||||
|
||||
dictList[i][0] = dictList[i][1];
|
||||
// getString throws an exception when a key is not found in the
|
||||
// bundle. In that case, just use the original dictList string.
|
||||
langLabel = langId;
|
||||
}
|
||||
dictList[i] = [langLabel, langId];
|
||||
}
|
||||
|
||||
// note this is not locale-aware collation, just simple ASCII-based sorting
|
||||
// we really need to add loacel-aware JS collation, see bug XXXXX
|
||||
dictList.sort();
|
||||
// sort by locale-aware collation
|
||||
dictList.sort(
|
||||
function compareFn(a, b)
|
||||
{
|
||||
return a[0].localeCompare(b[0]);
|
||||
}
|
||||
);
|
||||
|
||||
var languageMenuList = document.getElementById("languageMenuList");
|
||||
// Remove any languages from the list.
|
||||
var languageMenuPopup = languageMenuList.firstChild;
|
||||
while (languageMenuPopup.hasChildNodes())
|
||||
languageMenuPopup.removeChild(languageMenuPopup.firstChild);
|
||||
|
||||
var curLang = languageMenuList.value;
|
||||
var defaultItem = null;
|
||||
|
||||
// now select the dictionary we are currently using
|
||||
for (i = 0; i < dictList.length; i++)
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
var item = languageMenuList.appendItem(dictList[i][0], dictList[i][1]);
|
||||
if (curLang && dictList[i][1] == curLang)
|
||||
|
||||
@@ -192,9 +192,9 @@
|
||||
<separator class="thin"/>
|
||||
|
||||
<hbox align="center" pack="start">
|
||||
<label value ="&languagePopup.label;" control="LanguageMenulist" accesskey="&languagePopup.accessKey;"/>
|
||||
<menulist id="LanguageMenulist" preference="spellchecker.dictionary">
|
||||
<menupopup>
|
||||
<label value ="&languagePopup.label;" control="languageMenuList" accesskey="&languagePopup.accessKey;"/>
|
||||
<menulist id="languageMenuList" preference="spellchecker.dictionary">
|
||||
<menupopup onpopupshowing="gComposePane.initLanguageMenu();">
|
||||
<!-- dynamic content populated by JS -->
|
||||
</menupopup>
|
||||
</menulist>
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
var gAutoSaveInterval;
|
||||
var gLastSelectedLang;
|
||||
var gDictCount = 0;
|
||||
|
||||
function Startup() {
|
||||
if ("@mozilla.org/spellchecker;1" in Components.classes)
|
||||
InitLanguageMenu();
|
||||
else
|
||||
document.getElementById("spellingGroup").hidden = true;
|
||||
|
||||
gAutoSaveInterval = document.getElementById("autoSaveInterval");
|
||||
EnableTextbox(document.getElementById("autoSave"), gAutoSaveInterval, true);
|
||||
}
|
||||
|
||||
function EnableTextbox(aCheckbox, aTextbox, aStartingUp) {
|
||||
aTextbox.disabled = (!aCheckbox.checked ||
|
||||
parent.hPrefWindow.getPrefIsLocked(aTextbox.getAttribute("prefstring")));
|
||||
|
||||
if (!aTextbox.disabled && !aStartingUp)
|
||||
aTextbox.focus();
|
||||
}
|
||||
|
||||
function PopulateFonts() {
|
||||
var fontsList = document.getElementById("fontSelect");
|
||||
try {
|
||||
var enumerator = Components.classes["@mozilla.org/gfx/fontenumerator;1"]
|
||||
.getService(Components.interfaces.nsIFontEnumerator);
|
||||
var localFontCount = { value: 0 }
|
||||
var localFonts = enumerator.EnumerateAllFonts(localFontCount);
|
||||
for (var i = 0; i < localFonts.length; ++i) {
|
||||
if (localFonts[i] != "") {
|
||||
fontsList.appendItem(localFonts[i], localFonts[i]);
|
||||
}
|
||||
}
|
||||
} catch (ex) { }
|
||||
}
|
||||
|
||||
function InitLanguageMenu() {
|
||||
var spellChecker = Components.classes["@mozilla.org/spellchecker/myspell;1"]
|
||||
.getService(Components.interfaces.mozISpellCheckingEngine);
|
||||
|
||||
var o1 = {};
|
||||
var o2 = {};
|
||||
|
||||
// Get the list of dictionaries from the spellchecker.
|
||||
spellChecker.getDictionaryList(o1, o2);
|
||||
|
||||
var dictList = o1.value;
|
||||
var count = o2.value;
|
||||
|
||||
// If dictionary count hasn't changed then no need to update the menu.
|
||||
if (gDictCount == count)
|
||||
return;
|
||||
|
||||
// Store current dictionary count.
|
||||
gDictCount = count;
|
||||
|
||||
// Load the string bundles that will help us map
|
||||
// RFC 1766 strings to UI strings.
|
||||
|
||||
// Load the language string bundle.
|
||||
var languageBundle = document.getElementById("languageBundle");
|
||||
var regionBundle = null;
|
||||
// If we have a language string bundle, load the region string bundle.
|
||||
if (languageBundle)
|
||||
regionBundle = document.getElementById("regionBundle");
|
||||
|
||||
var menuStr2;
|
||||
var isoStrArray;
|
||||
var langId;
|
||||
var langLabel;
|
||||
var i;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
try {
|
||||
langId = dictList[i];
|
||||
isoStrArray = dictList[i].split("-");
|
||||
|
||||
if (languageBundle && isoStrArray[0])
|
||||
langLabel = languageBundle.getString(isoStrArray[0].toLowerCase());
|
||||
|
||||
if (regionBundle && langLabel && isoStrArray.length > 1 && isoStrArray[1]) {
|
||||
menuStr2 = regionBundle.getString(isoStrArray[1].toLowerCase());
|
||||
if (menuStr2)
|
||||
langLabel += "/" + menuStr2;
|
||||
}
|
||||
|
||||
if (!langLabel)
|
||||
langLabel = langId;
|
||||
} catch (ex) {
|
||||
// getString throws an exception when a key is not found in the
|
||||
// bundle. In that case, just use the original dictList string.
|
||||
langLabel = langId;
|
||||
}
|
||||
dictList[i] = [langLabel, langId];
|
||||
}
|
||||
|
||||
// sort by locale-aware collation
|
||||
dictList.sort(
|
||||
function compareFn(a, b) {
|
||||
return a[0].localeCompare(b[0]);
|
||||
}
|
||||
);
|
||||
|
||||
var languageMenuList = document.getElementById("languageMenuList");
|
||||
// Remove any languages from the list.
|
||||
var languageMenuPopup = languageMenuList.firstChild;
|
||||
while (languageMenuPopup.firstChild.localName != "menuseparator")
|
||||
languageMenuPopup.removeChild(languageMenuPopup.firstChild);
|
||||
|
||||
var curLang = languageMenuList.value;
|
||||
var defaultItem = null;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
var item = languageMenuList.insertItemAt(i, dictList[i][0], dictList[i][1]);
|
||||
if (curLang && dictList[i][1] == curLang)
|
||||
defaultItem = item;
|
||||
}
|
||||
|
||||
// Now make sure the correct item in the menu list is selected.
|
||||
if (defaultItem) {
|
||||
languageMenuList.selectedItem = defaultItem;
|
||||
gLastSelectedLang = defaultItem;
|
||||
}
|
||||
}
|
||||
|
||||
function SelectLanguage(aTarget) {
|
||||
try {
|
||||
if (aTarget.value != "more-cmd")
|
||||
gLastSelectedLang = aTarget;
|
||||
else {
|
||||
window.openDialog(getBrowserURL(), "_blank", "chrome,all,dialog=no",
|
||||
xlateURL('urn:clienturl:composer:spellcheckers'));
|
||||
if (gLastSelectedLang)
|
||||
document.getElementById("languageMenuList").selectedItem = gLastSelectedLang;
|
||||
}
|
||||
} catch (ex) {
|
||||
dump(ex);
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
<?xml-stylesheet href="chrome://communicator/skin/" type="text/css"?>
|
||||
|
||||
<?xul-overlay href="chrome://communicator/content/utilityOverlay.xul"?>
|
||||
|
||||
<!DOCTYPE page [
|
||||
<!ENTITY % pref-composing_messagesDTD SYSTEM "chrome://messenger/locale/messengercompose/pref-composing_messages.dtd" >
|
||||
%pref-composing_messagesDTD;
|
||||
@@ -10,56 +12,25 @@
|
||||
]>
|
||||
|
||||
<page xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
onload="populateFonts();parent.initPanel('chrome://messenger/content/messengercompose/pref-composing_messages.xul');"
|
||||
onload="PopulateFonts();parent.initPanel('chrome://messenger/content/messengercompose/pref-composing_messages.xul');"
|
||||
headertitle="&pref.composing.messages.title;">
|
||||
|
||||
|
||||
<stringbundle id="languageBundle" src="chrome://global/locale/languageNames.properties"/>
|
||||
<stringbundle id="regionBundle" src="chrome://global/locale/regionNames.properties"/>
|
||||
|
||||
<script type="application/x-javascript" src="chrome://messenger/content/messengercompose/pref-composing_messages.js"/>
|
||||
<script type="application/x-javascript">
|
||||
<![CDATA[
|
||||
var _elementIDs = ["forwardMessageMode", "autoSave",
|
||||
"autoSaveInterval","spellCheckBeforeSend", "inlineSpellCheck",
|
||||
"mailWarnOnSendAccelKey", "wrapLength", "FontSelect",
|
||||
var _elementIDs = ["forwardMessageMode", "autoSave", "autoSaveInterval",
|
||||
"spellCheckBeforeSend", "inlineSpellCheck", "languageMenuList",
|
||||
"mailWarnOnSendAccelKey", "wrapLength", "fontSelect",
|
||||
"fontSizeSelect", "textColor", "backgroundColor"];
|
||||
var gAutoSaveInterval;
|
||||
|
||||
function Startup()
|
||||
{
|
||||
var hideSpellCheck = !("@mozilla.org/spellchecker;1" in Components.classes);
|
||||
document.getElementById("spellCheckBeforeSend").hidden = hideSpellCheck;
|
||||
document.getElementById("inlineSpellCheck").hidden = hideSpellCheck;
|
||||
gAutoSaveInterval = document.getElementById("autoSaveInterval");
|
||||
enableTextbox(document.getElementById("autoSave"), gAutoSaveInterval, true);
|
||||
}
|
||||
|
||||
function enableTextbox(checkbox, textbox, startingUp) {
|
||||
textbox.disabled = (!checkbox.checked ||
|
||||
parent.hPrefWindow.getPrefIsLocked(textbox.getAttribute("prefstring")));
|
||||
|
||||
if (!textbox.disabled && !startingUp)
|
||||
textbox.focus();
|
||||
}
|
||||
|
||||
function populateFonts() {
|
||||
var fontsList = document.getElementById("FontSelect");
|
||||
try {
|
||||
var enumerator = Components.classes["@mozilla.org/gfx/fontenumerator;1"]
|
||||
.getService(Components.interfaces.nsIFontEnumerator);
|
||||
var localFontCount = { value: 0 }
|
||||
var localFonts = enumerator.EnumerateAllFonts(localFontCount);
|
||||
for (var i = 0; i < localFonts.length; ++i) {
|
||||
if (localFonts[i] != "") {
|
||||
fontsList.appendItem(localFonts[i], localFonts[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(e) { }
|
||||
}
|
||||
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<groupbox>
|
||||
<caption label="&forwardReply.label;"/>
|
||||
|
||||
<caption label="&generalComposing.label;"/>
|
||||
|
||||
<radiogroup id="forwardMessageMode" orient="horizontal" align="center"
|
||||
prefstring="mail.forward_message_mode">
|
||||
<label value="&forwardMsg.label;"/>
|
||||
@@ -67,28 +38,14 @@
|
||||
<radio value="0" label="&asAttachment.label;"
|
||||
accesskey="&asAttachment.accesskey;"/>
|
||||
</radiogroup>
|
||||
</groupbox>
|
||||
|
||||
<!-- Composing Mail -->
|
||||
<groupbox align="start">
|
||||
<caption label="&sendingMessagesHeader.label;"/>
|
||||
|
||||
<vbox align="start">
|
||||
<checkbox id="spellCheckBeforeSend" label="&spellCheck.label;"
|
||||
prefstring="mail.SpellCheckBeforeSend"
|
||||
accesskey="&spellCheck.accesskey;"/>
|
||||
<checkbox id="inlineSpellCheck" label="&spellCheckInline.label;"
|
||||
prefstring="mail.spellcheck.inline"
|
||||
accesskey="&spellCheckInline.accesskey;"/>
|
||||
</vbox>
|
||||
|
||||
<hbox align="center">
|
||||
<checkbox id="autoSave" label="&autoSave.label;"
|
||||
prefstring="mail.compose.autosave"
|
||||
accesskey="&autoSave.accesskey;"
|
||||
oncommand="enableTextbox(this, gAutoSaveInterval, false);"/>
|
||||
<textbox id="autoSaveInterval" size="2" preftype="int"
|
||||
prefstring="mail.compose.autosaveinterval"/>
|
||||
oncommand="EnableTextbox(this, gAutoSaveInterval, false);"/>
|
||||
<textbox id="autoSaveInterval" size="2" preftype="int"
|
||||
prefstring="mail.compose.autosaveinterval"/>
|
||||
<label value="&autoSaveEnd.label;"/>
|
||||
</hbox>
|
||||
|
||||
@@ -102,15 +59,44 @@
|
||||
prefstring="mailnews.wraplength" prefattribute="value"/>
|
||||
<label value="&char.label;"/>
|
||||
</hbox>
|
||||
</groupbox>
|
||||
|
||||
<!-- Composing Mail -->
|
||||
<groupbox id="spellingGroup" align="start">
|
||||
<caption label="&spellingHeader.label;"/>
|
||||
<vbox align="start">
|
||||
<checkbox id="spellCheckBeforeSend" label="&spellCheck.label;"
|
||||
prefstring="mail.SpellCheckBeforeSend"
|
||||
accesskey="&spellCheck.accesskey;"/>
|
||||
<checkbox id="inlineSpellCheck" label="&spellCheckInline.label;"
|
||||
prefstring="mail.spellcheck.inline"
|
||||
accesskey="&spellCheckInline.accesskey;"/>
|
||||
</vbox>
|
||||
|
||||
<separator class="thin"/>
|
||||
|
||||
<hbox align="center" pack="start">
|
||||
<label value="&languagePopup.label;" control="languageMenuList"
|
||||
accesskey="&languagePopup.accessKey;"/>
|
||||
<menulist id="languageMenuList" oncommand="SelectLanguage(event.target)"
|
||||
preftype="localizedstring" prefstring="spellchecker.dictionary">
|
||||
<menupopup onpopupshowing="InitLanguageMenu();">
|
||||
<!-- dynamic content populated by JS -->
|
||||
<menuseparator/>
|
||||
<menuitem value="more-cmd" label="&moreDictionaries.label;"/>
|
||||
</menupopup>
|
||||
</menulist>
|
||||
<spring flex="1"/>
|
||||
</hbox>
|
||||
|
||||
</groupbox>
|
||||
|
||||
|
||||
<groupbox align="start">
|
||||
<caption label="&defaultMessagesHeader.label;"/>
|
||||
<caption label="&defaultMessagesHeader.label;"/>
|
||||
<vbox>
|
||||
<hbox align="center">
|
||||
<label control="FontSelect" value="&font.label;" accesskey="&font.accesskey;"/>
|
||||
<menulist id="FontSelect" preftype="string" prefstring="msgcompose.font_face">
|
||||
<label control="fontSelect" value="&font.label;" accesskey="&font.accesskey;"/>
|
||||
<menulist id="fontSelect" preftype="string" prefstring="msgcompose.font_face">
|
||||
<menupopup>
|
||||
<menuitem value="" label="&fontVarWidth.label;"/>
|
||||
<menuitem value="tt" label="&fontFixedWidth.label;"/>
|
||||
@@ -120,7 +106,7 @@
|
||||
<menuitem value="Courier New, Courier, monospace" label="&fontCourier.label;"/>
|
||||
<menuseparator/>
|
||||
</menupopup>
|
||||
</menulist>
|
||||
</menulist>
|
||||
</hbox>
|
||||
<hbox align="center">
|
||||
<label control="fontSizeSelect" value="&size.label;" accesskey="&size.accesskey;"/>
|
||||
@@ -136,10 +122,10 @@
|
||||
</menulist>
|
||||
<label control="textColor" value="&fontColor.label;" accesskey="&fontColor.accesskey;"/>
|
||||
<colorpicker type="button" id="textColor" prefstring="msgcompose.text_color"/>
|
||||
<label control="backgroundColor" value="&bgColor.label;" accesskey="&bgColor.accesskey;"/>
|
||||
<label control="backgroundColor" value="&bgColor.label;" accesskey="&bgColor.accesskey;"/>
|
||||
<colorpicker type="button" id="backgroundColor" prefstring="msgcompose.background_color"/>
|
||||
</hbox>
|
||||
</vbox>
|
||||
</vbox>
|
||||
</groupbox>
|
||||
|
||||
</page>
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
***** END LICENSE BLOCK ***** -->
|
||||
|
||||
<!ENTITY pref.composing.messages.title "Composition">
|
||||
<!ENTITY forwardReply.label "Forwarding Messages">
|
||||
<!ENTITY generalComposing.label "General">
|
||||
<!ENTITY forwardMsg.label "Forward messages:">
|
||||
<!ENTITY inline.label "Inline">
|
||||
<!ENTITY inline.accesskey "n">
|
||||
@@ -46,22 +46,25 @@
|
||||
|
||||
<!ENTITY warnOnSendAccelKey.label "Confirm when using keyboard shortcut to send message">
|
||||
<!ENTITY warnOnSendAccelKey.accesskey "k">
|
||||
|
||||
<!ENTITY sendingMessagesHeader.label "Composing Messages">
|
||||
<!-- LOCALIZATION NOTE (autoSave.label): This will concatenate with
|
||||
"xxx minutes", using a number and (autoSaveEnd.label). -->
|
||||
<!ENTITY autoSave.label "Automatically save the message every">
|
||||
<!ENTITY autoSave.accesskey "u">
|
||||
<!ENTITY autoSaveEnd.label "minutes">
|
||||
<!ENTITY spellCheck.label "Check spelling before sending">
|
||||
<!ENTITY spellCheck.accesskey "C">
|
||||
<!ENTITY spellCheckInline.label "Check spelling as you type">
|
||||
<!ENTITY spellCheckInline.accesskey "e">
|
||||
<!-- LOCALIZATION NOTE (wrapOutMsg.label): This will concatenate with "xxx characters", using a number and (char.label). -->
|
||||
<!ENTITY wrapOutMsg.label "Wrap plain text messages at">
|
||||
<!ENTITY wrapOutMsg.accesskey "W">
|
||||
<!ENTITY char.label "characters">
|
||||
|
||||
<!ENTITY spellingHeader.label "Spelling">
|
||||
<!ENTITY spellCheck.label "Check spelling before sending">
|
||||
<!ENTITY spellCheck.accesskey "C">
|
||||
<!ENTITY spellCheckInline.label "Check spelling as you type">
|
||||
<!ENTITY spellCheckInline.accesskey "e">
|
||||
<!ENTITY languagePopup.label "Language:">
|
||||
<!ENTITY languagePopup.accessKey "g">
|
||||
<!ENTITY moreDictionaries.label "Download more dictionaries...">
|
||||
|
||||
<!ENTITY defaultMessagesHeader.label "Defaults for HTML Messages">
|
||||
<!ENTITY font.label "Font:">
|
||||
<!ENTITY font.accesskey "F">
|
||||
|
||||
@@ -40,14 +40,15 @@
|
||||
/**
|
||||
* interfaces
|
||||
*/
|
||||
var nsIMsgCompDeliverMode = Components.interfaces.nsIMsgCompDeliverMode;
|
||||
var nsIMsgCompSendFormat = Components.interfaces.nsIMsgCompSendFormat;
|
||||
var nsIMsgCompConvertible = Components.interfaces.nsIMsgCompConvertible;
|
||||
var nsIMsgCompType = Components.interfaces.nsIMsgCompType;
|
||||
var nsIMsgCompFormat = Components.interfaces.nsIMsgCompFormat;
|
||||
var nsIAbPreferMailFormat = Components.interfaces.nsIAbPreferMailFormat;
|
||||
var nsIPlaintextEditorMail = Components.interfaces.nsIPlaintextEditor;
|
||||
|
||||
const nsIMsgCompDeliverMode = Components.interfaces.nsIMsgCompDeliverMode;
|
||||
const nsIMsgCompSendFormat = Components.interfaces.nsIMsgCompSendFormat;
|
||||
const nsIMsgCompConvertible = Components.interfaces.nsIMsgCompConvertible;
|
||||
const nsIMsgCompType = Components.interfaces.nsIMsgCompType;
|
||||
const nsIMsgCompFormat = Components.interfaces.nsIMsgCompFormat;
|
||||
const nsIAbPreferMailFormat = Components.interfaces.nsIAbPreferMailFormat;
|
||||
const nsIPlaintextEditorMail = Components.interfaces.nsIPlaintextEditor;
|
||||
const nsISupportsString = Components.interfaces.nsISupportsString;
|
||||
const mozISpellCheckingEngine = Components.interfaces.mozISpellCheckingEngine;
|
||||
|
||||
/**
|
||||
* In order to distinguish clearly globals that are initialized once when js load (static globals) and those that need to be
|
||||
@@ -67,6 +68,7 @@ var sOther_headers = "";
|
||||
var sAccountManagerDataSource = null;
|
||||
var sRDF = null;
|
||||
var sNameProperty = null;
|
||||
var sDictCount = 0;
|
||||
|
||||
/* Create message window object. This is use by mail-offline.js and therefore should not be renamed. We need to avoid doing
|
||||
this kind of cross file global stuff in the future and instead pass this object as parameter when needed by function
|
||||
@@ -2114,6 +2116,120 @@ function ToggleInlineSpellChecker(target)
|
||||
}
|
||||
}
|
||||
|
||||
function InitLanguageMenu()
|
||||
{
|
||||
var languageMenuList = document.getElementById("languageMenuList");
|
||||
if (!languageMenuList)
|
||||
return;
|
||||
|
||||
var spellChecker = Components.classes["@mozilla.org/spellchecker/myspell;1"]
|
||||
.getService(mozISpellCheckingEngine);
|
||||
var o1 = {};
|
||||
var o2 = {};
|
||||
|
||||
// Get the list of dictionaries from the spellchecker.
|
||||
spellChecker.getDictionaryList(o1, o2);
|
||||
|
||||
var dictList = o1.value;
|
||||
var count = o2.value;
|
||||
|
||||
// If dictionary count hasn't changed then no need to update the menu.
|
||||
if (sDictCount == count)
|
||||
return;
|
||||
|
||||
// Store current dictionary count.
|
||||
sDictCount = count;
|
||||
|
||||
// Load the language string bundle that will help us map
|
||||
// RFC 1766 strings to UI strings.
|
||||
var languageBundle = document.getElementById("languageBundle");
|
||||
var isoStrArray;
|
||||
var langId;
|
||||
var langLabel;
|
||||
var i;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
try
|
||||
{
|
||||
langId = dictList[i];
|
||||
isoStrArray = dictList[i].split("-");
|
||||
|
||||
if (languageBundle && isoStrArray[0])
|
||||
langLabel = languageBundle.getString(isoStrArray[0].toLowerCase());
|
||||
|
||||
// the user needs to be able to distinguish between the UK English dictionary
|
||||
// and say the United States English Dictionary. If we have a isoStr value then
|
||||
// wrap it in parentheses and append it to the menu item string. i.e.
|
||||
// English (US) and English (UK)
|
||||
if (!langLabel)
|
||||
langLabel = langId;
|
||||
else if (isoStrArray.length > 1 && isoStrArray[1]) // if we have a language ID like US or UK, append it to the menu item
|
||||
langLabel += ' (' + isoStrArray[1] + ')';
|
||||
}
|
||||
catch (ex)
|
||||
{
|
||||
// getString throws an exception when a key is not found in the
|
||||
// bundle. In that case, just use the original dictList string.
|
||||
langLabel = langId;
|
||||
}
|
||||
dictList[i] = [langLabel, langId];
|
||||
}
|
||||
|
||||
// sort by locale-aware collation
|
||||
dictList.sort(
|
||||
function compareFn(a, b)
|
||||
{
|
||||
return a[0].localeCompare(b[0]);
|
||||
}
|
||||
);
|
||||
|
||||
// Remove any languages from the list.
|
||||
while (languageMenuList.hasChildNodes())
|
||||
languageMenuList.removeChild(languageMenuList.firstChild);
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
var item = document.createElement("menuitem");
|
||||
item.setAttribute("label", dictList[i][0]);
|
||||
item.setAttribute("value", dictList[i][1]);
|
||||
item.setAttribute("type", "radio");
|
||||
languageMenuList.appendChild(item);
|
||||
}
|
||||
}
|
||||
|
||||
function OnShowDictionaryMenu(aTarget)
|
||||
{
|
||||
InitLanguageMenu();
|
||||
var curLang = sPrefs.getComplexValue("spellchecker.dictionary", nsISupportsString).data;
|
||||
var languages = aTarget.getElementsByAttribute("value", curLang);
|
||||
if (languages.length > 0)
|
||||
languages[0].setAttribute("checked", true);
|
||||
}
|
||||
|
||||
function ChangeLanguage(event)
|
||||
{
|
||||
// We need to change the dictionary language and if we are using inline spell check,
|
||||
// recheck the message
|
||||
|
||||
var spellChecker = Components.classes["@mozilla.org/spellchecker/myspell;1"]
|
||||
.getService(mozISpellCheckingEngine);
|
||||
if (spellChecker.dictionary != event.target.value)
|
||||
{
|
||||
spellChecker.dictionary = event.target.value;
|
||||
var str = Components.classes["@mozilla.org/supports-string;1"]
|
||||
.createInstance(nsISupportsString);
|
||||
str.data = event.target.value;
|
||||
sPrefs.setComplexValue("spellchecker.dictionary", nsISupportsString, str);
|
||||
|
||||
// now check the document over again with the new dictionary
|
||||
if (InlineSpellChecker.inlineSpellChecker)
|
||||
if (InlineSpellChecker.inlineSpellChecker.enableRealTimeSpell)
|
||||
InlineSpellChecker.checkDocument(window.content.document);
|
||||
}
|
||||
event.stopPropagation();
|
||||
}
|
||||
|
||||
function ToggleReturnReceipt(target)
|
||||
{
|
||||
var msgCompFields = gMsgCompose.compFields;
|
||||
|
||||
@@ -85,6 +85,7 @@
|
||||
<stringbundle id="bundle_composeMsgs" src="chrome://messenger/locale/messengercompose/composeMsgs.properties"/>
|
||||
<stringbundle id="bundle_messenger" src="chrome://messenger/locale/messenger.properties"/>
|
||||
<stringbundle id="bundle_offlinePrompts" src="chrome://messenger/locale/offline.properties"/>
|
||||
<stringbundle id="languageBundle" src="chrome://global/locale/languageNames.properties"/>
|
||||
</stringbundleset>
|
||||
|
||||
<script type="application/x-javascript" src="chrome://communicator/content/contentAreaDD.js"/>
|
||||
@@ -457,9 +458,13 @@
|
||||
<menuitem type="checkbox" label="&attachVCardCmd.label;" accesskey="&attachVCardCmd.accesskey;" command="cmd_attachVCard"/>
|
||||
</menupopup>
|
||||
</toolbarbutton>
|
||||
<toolbarbutton class="toolbarbutton-1"
|
||||
<toolbarbutton class="toolbarbutton-1" type="menu-button"
|
||||
id="spellingButton" label="&spellingButton.label;"
|
||||
command="cmd_spelling"/>
|
||||
command="cmd_spelling">
|
||||
<!-- this popup gets dynamically generated -->
|
||||
<menupopup id="languageMenuList" oncommand="ChangeLanguage(event);"
|
||||
onpopupshowing="OnShowDictionaryMenu(event.target);"/>
|
||||
</toolbarbutton>
|
||||
<toolbarseparator id="saveSeparator" class="toolbarseparator-primary"/>
|
||||
<toolbarbutton class="toolbarbutton-1" type="menu-button"
|
||||
id="button-save" label="&saveButton.label;"
|
||||
|
||||
@@ -167,6 +167,7 @@ messenger.jar:
|
||||
content/messenger/junkLog.xul (base/resources/content/junkLog.xul)
|
||||
content/messenger/junkLog.js (base/resources/content/junkLog.js)
|
||||
content/messenger/messengercompose/pref-composing_messages.xul (compose/prefs/resources/content/pref-composing_messages.xul)
|
||||
content/messenger/messengercompose/pref-composing_messages.js (compose/prefs/resources/content/pref-composing_messages.js)
|
||||
content/messenger/messengercompose/pref-formatting.xul (compose/prefs/resources/content/pref-formatting.xul)
|
||||
content/messenger/messengercompose/pref-formatting.js (compose/prefs/resources/content/pref-formatting.js)
|
||||
content/messenger/messengercompose/messengercompose.xul (compose/resources/content/messengercompose.xul)
|
||||
|
||||
Reference in New Issue
Block a user