Bug 878805 - Check UI consistency across all Thunderbird folderpickers - Part 2. r=squib, ui-r=richard.marti

This commit is contained in:
alta88 2014-01-20 09:08:49 -05:00
Родитель e05e22ec36
Коммит 41de9a5dae
12 изменённых файлов: 155 добавлений и 160 удалений

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

@ -11,6 +11,7 @@ Components.utils.import("resource://gre/modules/Services.jsm");
let gFilterListMsgWindow = null;
let gCurrentFilterList;
let gCurrentFolder;
let gSelectedFolder;
let gFilterListbox = null;
let gEditButton = null;
@ -112,19 +113,25 @@ function onLoad()
updateButtons();
// Get the folderpane selected folder, if there is one.
try {
gSelectedFolder = window.arguments[0].folder;
} catch(e) {
gSelectedFolder = null;
}
// Get the folder where filters should be defined, if that server
// can accept filters.
let firstItem = getFilterFolderForSelection();
let firstItem = getFilterFolderForSelection(gSelectedFolder);
// If the selected server cannot have filters, get the default server
// If the default server cannot have filters, check all accounts
// and get a server that can have filters.
if (!firstItem)
firstItem = getServerThatCanHaveFilters().rootFolder;
firstItem = getServerThatCanHaveFilters().rootFolder;
if (firstItem) {
selectFolder(firstItem);
}
if (firstItem)
selectFolder(firstItem);
Services.obs.addObserver(filterEditorQuitObserver,
"quit-application-requested", false);
@ -161,6 +168,10 @@ function onFilterFolderClick(aFolder)
// the dialog may be closed and we'll lose current filters.
gCurrentFilterList.saveToDefaultFile();
// Initial selected folder no longer applies, use getFirstFolder() logic,
// unless it's nntp where we can use the subscribed newsgroup.
gSelectedFolder = aFolder.server.type == "nntp" ? aFolder : null;
selectFolder(aFolder);
}
@ -211,7 +222,7 @@ function setFolder(msgFolder)
// Get the first folder for this server. INBOX for
// IMAP and POP3 accounts and 1st news group for news.
gRunFiltersFolder.selectedIndex = 0;
runMenu.selectFolder(getFirstFolder(msgFolder));
runMenu.selectFolder(getFirstFolder(gSelectedFolder || msgFolder));
}
}
@ -234,14 +245,12 @@ function toggleFilter(aFilterItem)
aFilterItem.childNodes[1].setAttribute("enabled", filter.enabled);
}
// sets up the menulist and the filter list
// update the server menulist
function selectFolder(aFolder)
{
// update the server menu
var serverMenu = document.getElementById("serverMenuPopup");
serverMenu.selectFolder(aFolder);
setFolder(aFolder);
var serverMenu = document.getElementById("serverMenuPopup");
serverMenu.selectFolder(aFolder);
setFolder(aFolder);
}
/**
@ -708,32 +717,16 @@ function updateButtons()
* be defined (the root folder except for news) if the server can
* accept filters.
*
* @param nsIMsgFolder aFolder - selected folder, from window args
* @returns an nsIMsgFolder where the filter is defined
*/
function getFilterFolderForSelection()
function getFilterFolderForSelection(aFolder)
{
var args = window.arguments;
let rootFolder = aFolder && aFolder.server ? aFolder.server.rootFolder : null;
if (rootFolder && rootFolder.isServer && rootFolder.server.canHaveFilters)
return (aFolder.server.type == "nntp") ? aFolder : rootFolder;
if (args && args[0] && args[0].folder)
{
var selectedFolder = args[0].folder;
var msgFolder = selectedFolder.QueryInterface(Components.interfaces.nsIMsgFolder);
try
{
var rootFolder = msgFolder.server.rootFolder;
if (rootFolder.isServer)
{
var server = rootFolder.server;
if (server.canHaveFilters)
return (server.type == "nntp") ? msgFolder : rootFolder;
}
}
catch (ex)
{
}
}
return null;
return null;
}
/**
@ -823,35 +816,35 @@ function onFilterListKeyPress(aEvent)
function onTargetSelect(event) {
gRunFiltersFolder._folder = event.target._folder;
let runMenu = document.getElementById("runFiltersPopup");
runMenu.selectFolder(gRunFiltersFolder._folder);
gRunFiltersFolder.menupopup.selectFolder(gRunFiltersFolder._folder);
}
/**
* For a given server folder, get the first folder. For imap and pop it's INBOX
* and it's the very first group for news accounts.
* For a given server folder, get the default run target selected folder or show
* Choose Folder.
*/
function getFirstFolder(msgFolder)
{
// Sanity check.
if (! msgFolder.isServer)
if (!msgFolder.isServer)
return msgFolder;
try {
// Find Inbox for imap and pop
// Choose Folder for feeds.
if (msgFolder.server.type == "rss")
return null;
if (msgFolder.server.type != "nntp")
{
// Find Inbox for imap and pop; show Choose Folder if not found or
// Local Folders or any other account type.
const nsMsgFolderFlags = Components.interfaces.nsMsgFolderFlags;
var inboxFolder = msgFolder.getFolderWithFlags(nsMsgFolderFlags.Inbox);
if (inboxFolder)
return inboxFolder;
else
// If inbox does not exist then use the server as default.
return msgFolder;
// If inbox does not exist then return null.
return msgFolder.getFolderWithFlags(nsMsgFolderFlags.Inbox);
}
else
// XXX TODO: For news, we should find the 1st group/folder off the news groups. For now use server.
return msgFolder;
// For news, this is the account folder.
return msgFolder;
}
catch (ex) {
dump(ex + "\n");

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

@ -130,7 +130,8 @@
accesskey="&folderPickerPrefix.accesskey;"
disabled="true" control="runFiltersFolder"/>
<menulist id="runFiltersFolder" disabled="true" flex="1"
class="folderMenuItem">
class="folderMenuItem"
displayformat="verbose">
<menupopup id="runFiltersPopup"
class="menulist-menupopup"
type="folder"

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

@ -787,8 +787,6 @@
mode="filing"
showFileHereLabel="true"
showRecent="true"
fileHereLabel="&fileHereMenu.label;"
fileHereAccessKey="&fileHereMenu.accesskey;"
recentLabel="&contextMoveCopyMsgRecentMenu.label;"
recentAccessKey="&contextMoveCopyMsgRecentMenu.accesskey;"/>
</menu>
@ -801,8 +799,6 @@
mode="filing"
showFileHereLabel="true"
showRecent="true"
fileHereLabel="&copyHereMenu.label;"
fileHereAccessKey="&copyHereMenu.accesskey;"
recentLabel="&contextMoveCopyMsgRecentMenu.label;"
recentAccessKey="&contextMoveCopyMsgRecentMenu.accesskey;"/>
</menu>
@ -1884,7 +1880,6 @@
<menupopup id="appmenu_GoFolderPopup"
type="folder"
showFileHereLabel="true"
fileHereLabel="&thisFolder.label;"
showRecent="true"
recentLabel="&contextMoveCopyMsgRecentMenu.label;"/>
</menu>
@ -2053,7 +2048,6 @@
mode="filing"
showFileHereLabel="true"
showRecent="true"
fileHereLabel="&fileHereMenu.label;"
recentLabel="&moveCopyMsgRecentMenu.label;"/>
</menu>
<menu id="appmenu_copyMenu"
@ -2063,7 +2057,6 @@
mode="filing"
showFileHereLabel="true"
showRecent="true"
fileHereLabel="&copyHereMenu.label;"
recentLabel="&moveCopyMsgRecentMenu.label;"/>
</menu>
<menuitem id="appmenu_moveToFolderAgain"
@ -2681,8 +2674,6 @@
<menupopup id="menu_GoFolderPopup"
type="folder"
showFileHereLabel="true"
fileHereLabel="&thisFolder.label;"
fileHereAccessKey="&thisFolder.accesskey;"
showRecent="true"
recentLabel="&contextMoveCopyMsgRecentMenu.label;"
recentAccessKey="&contextMoveCopyMsgRecentMenu.accesskey;"/>
@ -2857,9 +2848,9 @@
label="&moveMsgToMenu.label;"
accesskey="&moveMsgToMenu.accesskey;"
oncommand="MsgMoveMessage(event.target._folder)">
<menupopup type="folder" mode="filing" showFileHereLabel="true"
showRecent="true" fileHereLabel="&fileHereMenu.label;"
fileHereAccessKey="&fileHereMenu.accesskey;"
<menupopup type="folder" mode="filing"
showFileHereLabel="true"
showRecent="true"
recentLabel="&moveCopyMsgRecentMenu.label;"
recentAccessKey="&moveCopyMsgRecentMenu.accesskey;"/>
</menu>
@ -2867,9 +2858,9 @@
label="&copyMsgToMenu.label;"
accesskey="&copyMsgToMenu.accesskey;"
oncommand="MsgCopyMessage(event.target._folder)">
<menupopup type="folder" mode="filing" showFileHereLabel="true"
showRecent="true" fileHereLabel="&copyHereMenu.label;"
fileHereAccessKey="&copyHereMenu.accesskey;"
<menupopup type="folder" mode="filing"
showFileHereLabel="true"
showRecent="true"
recentLabel="&moveCopyMsgRecentMenu.label;"
recentAccessKey="&moveCopyMsgRecentMenu.accesskey;"/>
</menu>
@ -3088,8 +3079,6 @@
mode="filing"
showRecent="true"
showFileHereLabel="true"
fileHereLabel="&fileHereMenu.label;"
fileHereAccessKey="&fileHereMenu.accesskey;"
recentLabel="&moveCopyMsgRecentMenu.label;"
recentAccessKey="&moveCopyMsgRecentMenu.accesskey;"/>
</toolbarbutton>

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

@ -5,3 +5,7 @@
# LOCALIZATION NOTE(globalInbox)
# %S=name of the Local folders account
globalInbox=Global Inbox (%S)
# LOCALIZATION NOTE(verboseFolderFormat): %1$S is folder name, %2$S is server name
verboseFolderFormat=%1$S on %2$S
chooseFolder=Choose Folder…
noFolders=No available folders

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

@ -313,8 +313,6 @@
<!ENTITY prevStarredMsgCmd.accesskey "S">
<!ENTITY folderMenu.label "Folder">
<!ENTITY folderMenu.accesskey "O">
<!ENTITY thisFolder.label "This Folder">
<!ENTITY thisFolder.accesskey "F">
<!ENTITY goRecentlyClosedTabs.label "Recently Closed Tabs">
<!ENTITY goRecentlyClosedTabs.accesskey "R">
<!ENTITY startPageCmd.label "Mail Start Page">
@ -379,10 +377,6 @@
<!ENTITY watchThreadMenu.label "Watch Thread">
<!ENTITY watchThreadMenu.accesskey "W">
<!ENTITY watchThreadMenu.key "w">
<!ENTITY fileHereMenu.label "File Here">
<!ENTITY fileHereMenu.accesskey "F">
<!ENTITY copyHereMenu.label "Copy Here">
<!ENTITY copyHereMenu.accesskey "C">
<!ENTITY tagMenu.label "Tag">
<!ENTITY tagMenu.accesskey "g">
<!ENTITY tagCmd0.key "0">

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

@ -215,11 +215,6 @@ treechildren::-moz-tree-image(junkStatusCol) {
-moz-padding-start: 2px;
}
#folderLocationPopup menuitem:first-child {
padding-top: 3px;
padding-bottom: 4px;
}
@media (-moz-windows-default-theme) {
#afterViewPickerUnreadSeparator,
#afterViewPickerCustomViewsSeparator {

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

@ -22,8 +22,6 @@
Components.utils.import("resource:///modules/StringBundle.js", this);
this._stringBundle = new this
.StringBundle("chrome://messenger/locale/folderWidgets.properties");
this._stringBundleMessenger = new this
.StringBundle("chrome://messenger/locale/messenger.properties");
// Get the displayformat if set.
if (this.parentNode && this.parentNode.localName == "menulist")
@ -88,7 +86,6 @@
</method>
<field name="_stringBundle">null</field>
<field name="_stringBundleMessenger">null</field>
<!--
- If non-null, the subFolders of this nsIMsgFolder will be used to
@ -372,6 +369,7 @@
attribute or no mode attribute. However the code won't add such a
menu item if one of the following conditions is met:
(*) There is no parent folder
(*) Folder is server and showAccountsFileHere is explicitly false
(*) Current folder has a mode, the parent folder can be selected,
no messages can be filed into the parent folder (e.g. when the
parent folder is a news group or news server) and the folder
@ -381,32 +379,34 @@
label or if the attribute does not exist the name of the parent
folder instead.
*/
if (this._parentFolder && (!mode ||
(this.getAttribute("showFileHereLabel") == "true" &&
(this._parentFolder.noSelect ||
this._parentFolder.canFileMessages || mode == "newFolder" ||
this.getAttribute("showAccountsFileHere") == "true")))) {
var menuitem = document.createElement("menuitem");
menuitem._folder = this._parentFolder;
menuitem.setAttribute("generated", "true");
if (this.hasAttribute("fileHereLabel")) {
menuitem.setAttribute("label", this.getAttribute("fileHereLabel"));
menuitem.setAttribute("accesskey", this.getAttribute("fileHereAccessKey"));
} else {
menuitem.setAttribute("label", this._parentFolder.prettyName);
menuitem.setAttribute("class", "folderMenuItem menuitem-iconic");
this._setCssSelectors(this._parentFolder, menuitem);
let parent = this._parentFolder;
if (parent && (this.getAttribute("showFileHereLabel") == "true" || !mode)) {
let showAccountsFileHere = this.getAttribute("showAccountsFileHere");
if ((!parent.isServer || showAccountsFileHere != "false") &&
(!mode || mode == "newFolder" || parent.noSelect ||
parent.canFileMessages || showAccountsFileHere == "true")) {
var menuitem = document.createElement("menuitem");
menuitem._folder = this._parentFolder;
menuitem.setAttribute("generated", "true");
if (this.hasAttribute("fileHereLabel")) {
menuitem.setAttribute("label", this.getAttribute("fileHereLabel"));
menuitem.setAttribute("accesskey", this.getAttribute("fileHereAccessKey"));
} else {
menuitem.setAttribute("label", this._parentFolder.prettyName);
menuitem.setAttribute("class", "folderMenuItem menuitem-iconic");
this._setCssSelectors(this._parentFolder, menuitem);
}
// Eww. have to support some legacy code here...
menuitem.setAttribute("id", this._parentFolder.URI);
this.appendChild(menuitem);
if (this._parentFolder.noSelect)
menuitem.setAttribute("disabled", "true");
var sep= document.createElement("menuseparator");
sep.setAttribute("generated", "true");
this.appendChild(sep);
}
// Eww. have to support some legacy code here...
menuitem.setAttribute("id", this._parentFolder.URI);
this.appendChild(menuitem);
if (this._parentFolder.noSelect)
menuitem.setAttribute("disabled", "true");
var sep= document.createElement("menuseparator");
sep.setAttribute("generated", "true");
this.appendChild(sep);
}
let globalInboxFolder = null;
@ -689,11 +689,11 @@
<parameter name="aFolder"/>
<body><![CDATA[
if (aFolder.isServer)
return aFolder.name;
return aFolder.prettyName;
if (this._displayformat == "verbose")
return this._stringBundleMessenger.getFormattedString(
"verboseFolderFormat", [aFolder.name, aFolder.server.prettyName]);
return this._stringBundle.getFormattedString("verboseFolderFormat",
[aFolder.prettyName, aFolder.server.prettyName]);
if (this._displayformat == "path")
return this.FeedUtils.getFolderPrettyPath(aFolder) || aFolder.name;
@ -705,7 +705,7 @@
<!--
- Makes a given folder selected.
-
- @param aFolder the folder to select (if unset, then choose first folder)
- @param aFolder the folder to select (if none, then Choose Folder)
- @note If aFolder is not in this popup, but is instead a descendant of
- a member of the popup, that ancestor will be selected.
- @return true if any usable folder was found, otherwise false.
@ -713,54 +713,65 @@
<method name="selectFolder">
<parameter name="aFolder"/>
<body><![CDATA[
// Set the label of the aParent element as if aFolder had been selected.
function setupParent(aFolder, aParent) {
aParent.setAttribute("label",
aParent.menupopup.getDisplayName(aFolder));
aParent.setAttribute("value", aFolder.URI);
aParent.setAttribute("IsServer", aFolder.isServer);
aParent.setAttribute("IsSecure", aFolder.server.isSecure);
aParent.setAttribute("ServerType", aFolder.server.type);
aParent.setAttribute("SpecialFolder",
aParent.menupopup.getSpecialFolderString(aFolder));
aParent.setAttribute("IsFeedFolder",
(aParent.menupopup.FeedUtils.getFeedUrlsInFolder(aFolder) ? true : false));
}
for (let child of this.childNodes) {
if (!child || !child._folder || child.disabled)
continue;
// Is this the folder in question or subfolder of the folder?
if (!aFolder || (child._folder.URI == aFolder.URI) ||
(child.tagName == "menu" &&
child._folder.isAncestorOf(aFolder))) {
if (!aFolder || (child._folder.URI == aFolder.URI))
this.parentNode.selectedItem = child;
// Set the label of the menulist element as if aFolder had been selected.
function setupParent(aFolder, aMenulist, aNoFolders) {
let menupopup = aMenulist.menupopup;
if (aFolder) {
aMenulist.setAttribute("label", menupopup.getDisplayName(aFolder));
} else {
aMenulist.setAttribute("label", menupopup._stringBundle.getString(
aNoFolders ? "noFolders" : "chooseFolder"));
}
aMenulist.setAttribute("value",
aFolder ? aFolder.URI : "");
aMenulist.setAttribute("IsServer",
aFolder ? aFolder.isServer : false);
aMenulist.setAttribute("IsSecure",
aFolder ? aFolder.server.isSecure : false);
aMenulist.setAttribute("ServerType",
aFolder ? aFolder.server.type : "none");
aMenulist.setAttribute("SpecialFolder",
aFolder ? menupopup.getSpecialFolderString(aFolder) : "none");
aMenulist.setAttribute("IsFeedFolder", Boolean(
aFolder && menupopup.FeedUtils.getFeedUrlsInFolder(aFolder)));
}
if (aFolder) {
// If this is a subfolder of what's in question, we merely appear
// to select this node.
setupParent(aFolder || child._folder, this.parentNode);
let folder;
if (aFolder) {
for (let child of this.childNodes) {
if (child && child._folder && !child.disabled &&
(child._folder.URI == aFolder.URI ||
(child.tagName == "menu" &&
child._folder.isAncestorOf(aFolder)))) {
if (child._folder.URI == aFolder.URI)
this.parentNode.selectedItem = child;
folder = aFolder;
break;
}
return true;
}
}
if (aFolder) {
// If the caller specified a folder to select and it was not
// found, blow up.
throw new Error("Unable to select folder " + aFolder.prettyName +
" in the picker!");
} else {
// If the caller didn't care much but nothing got selected,
// this means there are at most some disabled items in the menulist.
// Pretend to select the first one so that the widget is not shown
// empty.
if (this.childNodes.length > 0)
setupParent(this.getItemAtIndex(0)._folder, this.parentNode);
else
Components.utils.reportError("Unable to find any folder in the picker!");
// If the caller specified a folder to select and it was not
// found, or if the caller didn't pass a folder (meaning a logical
// and valid folder wasn't determined), don't blow up but reset
// attributes and set a nice Choose Folder label so the user may
// select a valid folder per the filter for this picker. If there are
// no children, then no folder passed the filter; disable the menulist
// as there's nothing to choose from.
let noFolders;
if (!this.childElementCount)
{
this.parentNode.setAttribute("disabled", true);
noFolders = true;
}
return false;
else
{
this.parentNode.removeAttribute("disabled");
noFolders = false;
}
setupParent(folder, this.parentNode, noFolders);
return folder ? true : false;
]]></body>
</method>

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

@ -31,7 +31,8 @@
<label value="&description.label;" accesskey="&description.accesskey;" control="msgNewFolderPicker"/>
<menulist id="msgNewFolderPicker" class="folderMenuItem">
<menulist id="msgNewFolderPicker" class="folderMenuItem"
displayformat="verbose">
<menupopup id="MsgNewFolderPopup" type="folder" showFileHereLabel="true"
class="menulist-menupopup"
mode="newFolder"

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

@ -54,7 +54,8 @@
<row align="center" id="chooseFolderLocationRow">
<label value="&description.label;" accesskey="&description.accesskey;" control="msgNewFolderPicker"/>
<menulist id="msgNewFolderPicker" class="folderMenuItem" flex="1">
<menulist id="msgNewFolderPicker" class="folderMenuItem" flex="1"
displayformat="verbose">
<menupopup id="msgNewFolderPopup" type="folder" mode="newFolder"
showFileHereLabel="true"
oncommand="onFolderPick(event);"/>

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

@ -186,7 +186,7 @@ var gFolderListener = {
if (eventType == "FolderCreateCompleted")
{
SetFolderPicker(folder.URI, gActionTargetElement.id);
gActionTargetElement.selectFolder(folder);
SetBusyCursor(window, false);
}
else if (eventType == "FolderCreateFailed")
@ -683,7 +683,8 @@ function SearchNewFolderOkCallback(name, uri)
if (!imapFolder)
{
var curFolder = uri+"/"+encodeURIComponent(name);
SetFolderPicker(curFolder, gActionTargetElement.id);
let folder = MailUtils.getFolderForURI(curFolder);
gActionTargetElement.selectFolder(folder);
}
}

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

@ -33,7 +33,6 @@
<script type="application/javascript" src="chrome://messenger/content/mailWindowOverlay.js"/>
<script type="application/javascript" src="chrome://messenger/content/mailCommands.js"/>
<script type="application/javascript" src="chrome://messenger/content/FilterEditor.js"/>
<script type="application/javascript" src="chrome://messenger/content/msgFolderPickerOverlay.js"/>
<commandset>
<command id="cmd_updateFilterType" oncommand="updateFilterType();"/>

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

@ -712,9 +712,15 @@
<implementation>
<constructor>
<![CDATA[
if (!this.menulist.value)
this.menulist.value = gFilterList.folder.URI;
SetFolderPickerElement(this.menulist.value, this.menulist);
Components.utils.import("resource:///modules/MailUtils.js", this);
let folder = this.menulist.value ?
this.MailUtils.getFolderForURI(this.menulist.value) :
gFilterList.folder;
// An account folder is not a move/copy target; show "Choose Folder".
folder = folder.isServer ? null : folder;
let menupopup = this.menulist.menupopup;
// The menupopup constructor needs to finish first.
setTimeout(function() { menupopup.selectFolder(folder); }, 0);
]]>
</constructor>