Bug 389139 - Do not show the current account in the folderpicker as a target for deferring. Allow hiding/disabling accounts in the picker. ui-r=bwinton, r=Neil, r=mkmelin

This commit is contained in:
aceman 2013-06-10 08:12:47 -04:00
Родитель 1f16fa6927
Коммит 94cbf8b7e4
12 изменённых файлов: 189 добавлений и 120 удалений

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

@ -25,8 +25,6 @@
<!ENTITY overrideNamespaces.label "Allow server to override these namespaces">
<!ENTITY overrideNamespaces.accesskey "A">
<!ENTITY pop3Desc.label "When downloading pop mail for this server, use the following folder for new mail:" >
<!ENTITY globalInbox.label "Global Inbox (Local Folders Account)">
<!ENTITY globalInbox.accesskey "G">
<!ENTITY accountDirectory.label "Inbox for this server's account">
<!ENTITY accountDirectory.accesskey "S">
<!ENTITY deferToServer.label "Inbox for different account">

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

@ -0,0 +1,7 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# LOCALIZATION NOTE(globalInbox)
# %S=name of the Local folders account
globalInbox=Global Inbox (%S)

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

@ -51,11 +51,12 @@
locale/@AB_CD@/messenger/am-smime.dtd (%chrome/messenger/am-smime.dtd)
locale/@AB_CD@/messenger/am-smime.properties (%chrome/messenger/am-smime.properties)
locale/@AB_CD@/messenger/messenger.properties (%chrome/messenger/messenger.properties)
locale/@AB_CD@/messenger/folderpane.dtd (%chrome/messenger/folderpane.dtd)
locale/@AB_CD@/messenger/newFolderDialog.dtd (%chrome/messenger/newFolderDialog.dtd)
locale/@AB_CD@/messenger/newTagDialog.dtd (%chrome/messenger/newTagDialog.dtd)
locale/@AB_CD@/messenger/renameFolderDialog.dtd (%chrome/messenger/renameFolderDialog.dtd)
locale/@AB_CD@/messenger/folderpane.dtd (%chrome/messenger/folderpane.dtd)
locale/@AB_CD@/messenger/folderProps.dtd (%chrome/messenger/folderProps.dtd)
locale/@AB_CD@/messenger/folderWidgets.properties (%chrome/messenger/folderWidgets.properties)
locale/@AB_CD@/messenger/subscribe.dtd (%chrome/messenger/subscribe.dtd)
locale/@AB_CD@/messenger/subscribe.properties (%chrome/messenger/subscribe.properties)
locale/@AB_CD@/messenger/msgFolderPickerOverlay.dtd (%chrome/messenger/msgFolderPickerOverlay.dtd)

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

@ -18,6 +18,9 @@
Components.utils.import("resource:///modules/MailUtils.js", this);
Components.utils.import("resource:///modules/folderUtils.jsm", this);
Components.utils.import("resource:///modules/iteratorUtils.jsm", this);
Components.utils.import("resource:///modules/StringBundle.js", this);
this._stringBundle = new this
.StringBundle("chrome://messenger/locale/folderWidgets.properties");
// Find out if we are in a wrapper (customize toolbars mode is active).
let inWrapper = false;
@ -77,6 +80,8 @@
]]></body>
</method>
<field name="_stringBundle">null</field>
<!--
- If non-null, the subFolders of this nsIMsgFolder will be used to
- populate this menu. If this is null, the menu will be populated
@ -132,7 +137,7 @@
aFolder.server.canCreateFoldersOnServer;
},
defered: function filter_defered(aFolder) {
deferred: function filter_defered(aFolder) {
return aFolder.server.canCreateFoldersOnServer &&
!aFolder.supportsOffline;
},
@ -319,14 +324,25 @@
</method>
<!--
- Actually constructs the menu-items based on the folders given
- Actually constructs the menu-items based on the folders given.
-
- @param aFolders an array of nsIMsgFolders to use for building
- @param aFolders An array of nsIMsgFolders to use for building.
-->
<method name="_build">
<parameter name="aFolders"/>
<body><![CDATA[
var folders;
let folders;
let excludeServers = [];
let disableServers = [];
// excludeServers attribute is a comma separated list of server keys.
if (this.hasAttribute("excludeServers"))
excludeServers = this.getAttribute("excludeServers").split(",");
// disableServers attribute is a comma separated list of server keys.
if (this.hasAttribute("disableServers"))
disableServers = this.getAttribute("disableServers").split(",");
// Extensions and other consumers can add to these modes too, see the
// above note on the _filters field.
var mode = this.getAttribute("mode");
@ -338,6 +354,11 @@
folders = aFolders;
}
if (excludeServers.length > 0) {
folders = folders.filter(function(aFolder) {
return !(excludeServers.indexOf(aFolder.server.key) != -1); });
}
/* This code block will do the following: Add a menu item that refers
back to the parent folder when there is a showFileHereLabel
attribute or no mode attribute. However the code won't add such a
@ -379,31 +400,38 @@
sep.setAttribute("generated", "true");
this.appendChild(sep);
}
// Some menus want a "Recent" option, but that should only be on our
// top-level menu
if (!this._parentFolder && this.getAttribute("showRecent") == "true")
this._buildRecentMenu();
/**
* Sorts the list of folders. We give first priority to the sortKey
* property, and then via a case-insensitive comparison of names
*/
function nameCompare(a, b) {
var sortKey = a.compareSortKeys(b);
if (sortKey)
return sortKey;
return a.prettyName.toLowerCase() > b.prettyName.toLowerCase();
let globalInboxFolder = null;
// See if this is the toplevel menu (usually with accounts).
if (!this._parentFolder) {
// Some menus want a "Recent" option, but that should only be on our
// top-level menu
if (this.getAttribute("showRecent") == "true")
this._buildRecentMenu();
// If we are showing the accounts for deferring, move Local Folders to the top.
if (mode == "deferred") {
globalInboxFolder = this.MailServices.accounts.localFoldersServer
.rootFolder;
let localFoldersIndex = folders.indexOf(globalInboxFolder);
if (localFoldersIndex != -1) {
folders.splice(localFoldersIndex, 1);
folders.unshift(globalInboxFolder);
}
}
// If we're the root of the folder hierarchy, then we actually don't
// want to sort the folders, but rather the accounts to which the
// folders belong. Since that sorting was already done, we don't need
// to do anything for that case here.
} else {
// Sorts the list of folders. We give first priority to the sortKey
// property if it is available, otherwise a case-insensitive
// comparison of names.
folders = folders.sort(function nameCompare(a, b) {
return a.compareSortKeys(b) ||
a.prettyName.localeCompare(b.prettyName);
});
}
/**
* If we're the root of the folder hierarchy, then we actually don't
* want to sort the folders, but rather the accounts to which the
* folders belong. Since that sorting was already done, we don't need
* to do anything for that case here
*/
if (this._parentFolder)
folders = folders.sort(nameCompare);
/* In some cases, the user wants to have a list of subfolders for only
* some account types (or maybe all of them). So we use this to
* determine what the user wanted.
@ -440,8 +468,9 @@
// Remove this workaround when Bug 502900 is fixed.
this.MailUtils.discoverFolders();
for each (var folder in folders) {
var node;
for (let folder of folders) {
let node;
// If we're going to add subFolders, we need to make menus, not
// menuitems.
if (!folder.hasSubFolders || !shouldExpand(folder.server.type)) {
@ -477,6 +506,9 @@
this.getAttribute("oncommand"));
popup.setAttribute("mode",
this.getAttribute("mode"));
if (this.hasAttribute("disableServers"))
popup.setAttribute("disableServers",
this.getAttribute("disableServers"));
if (this.hasAttribute("position"))
popup.setAttribute("position",
this.getAttribute("position"));
@ -496,13 +528,20 @@
popup.setAttribute("generated", "true");
node.appendChild(popup);
}
if (disableServers.indexOf(folder.server.key) != -1)
node.setAttribute("disabled", "true");
node._folder = folder;
node.setAttribute("label", folder.prettyName);
let label = "";
if (mode == "deferred" && folder.isServer &&
folder.server.rootFolder == globalInboxFolder) {
label = this._stringBundle.get("globalInbox", [folder.prettyName]);
} else {
label = folder.prettyName;
}
node.setAttribute("label", label);
this._setCssSelectors(folder, node);
//xxx for later optimization
//builtFolders.push(folder);
}
]]></body>
</method>
@ -653,35 +692,56 @@
<!--
- Makes a given folder selected.
-
- @param aFolder the folder to select
- @note If aFolder is not in this popup, but is instead a descendant of
- a member of the popup, that ancestor will be selected.
- @param aFolder the folder to select (if unset, then choose first 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.
-->
<method name="selectFolder">
<parameter name="aFolder"/>
<body><![CDATA[
for (var i in this.childNodes) {
var child = this.childNodes[i];
if (!child || !child._folder)
// Set the label of the aParent element as if aFolder had been selected.
function setupParent(aFolder, aParent) {
aParent.setAttribute("label", aFolder.name);
aParent.setAttribute("IsServer", aFolder.isServer);
aParent.setAttribute("IsSecure", aFolder.server.isSecure);
aParent.setAttribute("ServerType", aFolder.server.type);
}
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 ((child._folder.URI == aFolder.URI) ||
if (!aFolder || (child._folder.URI == aFolder.URI) ||
(child.tagName == "menu" &&
child._folder.isAncestorOf(aFolder))) {
if (child._folder.URI == aFolder.URI) {
// Making an assumption about our DOM positioning here.
this.parentNode.selectedIndex = i;
if (!aFolder || (child._folder.URI == aFolder.URI))
this.parentNode.selectedItem = child;
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);
}
// If this is a subfolder of what's in question, we merely appear
// to select this node.
this.parentNode.setAttribute("label", aFolder.name);
this.parentNode.setAttribute("IsServer", aFolder.isServer);
this.parentNode.setAttribute("IsSecure", aFolder.server.isSecure);
this.parentNode.setAttribute("ServerType", aFolder.server.type);
return;
return true;
}
}
throw "unable to find folder to select!";
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!");
}
return false;
]]></body>
</method>
@ -703,7 +763,6 @@
this._removeListener();
this._folders = null;
this._initialized = false;
]]></body>
</method>

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

@ -53,10 +53,10 @@ function onInit(aPageId, aServerId)
try {
folder = GetMsgFolderFromUri(spamActionTargetFolder, true);
document.getElementById("actionFolderPopup").selectFolder(folder);
} catch (e) {
// OK for folder to not exist.
} catch (e) { } // OK for the folder to not exist.
if (!folder)
folder = GetMsgFolderFromUri(spamActionTargetFolder, false);
}
document.getElementById("actionTargetFolder")
.setAttribute("label", prettyFolderName(folder));

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

@ -9,8 +9,6 @@ Components.utils.import("resource://gre/modules/Services.jsm");
// pull stuff out of window.arguments
var gServerSettings = window.arguments[0];
var serverList;
var gFirstDeferredAccount;
// initialize the controls with the "gServerSettings" argument
@ -43,42 +41,41 @@ function onLoad()
}
else if (gServerSettings.serverType == "pop3")
{
var radioGroup = document.getElementById("folderStorage");
document.getElementById("imapPanel").hidden = true;
let radioGroup = document.getElementById("folderStorage");
gFirstDeferredAccount = gServerSettings.deferredToAccount;
var localFoldersAccount = getLocalFoldersAccount();
var folderPopup = document.getElementById("deferedServerPopup");
if (gFirstDeferredAccount.length)
let folderPopup = document.getElementById("deferredServerPopup");
// The current account should not be shown in the folder picker
// of the "other account" option.
folderPopup._teardown();
folderPopup.setAttribute("excludeServers",
gServerSettings.account.incomingServer.key);
folderPopup._ensureInitialized();
if (gServerSettings.account.incomingServer.isDeferredTo) {
// Some other account already defers to this account
// therefore this one can't be deferred further.
radioGroup.value = "currentAccount";
folderPopup.selectFolder();
radioGroup.disabled = true;
}
else if (gFirstDeferredAccount.length)
{
// The current account is already deferred...
let account = MailServices.accounts.getAccount(gFirstDeferredAccount);
if (account)
{
folderPopup.selectFolder(account.incomingServer.rootFolder);
}
if (gFirstDeferredAccount == localFoldersAccount.key)
{
radioGroup.selectedItem = document.getElementById("globalInbox");
folderPopup.selectFolder(localFoldersAccount.incomingServer.rootFolder);
updateInboxAccount(false, true);
}
else
{
radioGroup.selectedItem = document.getElementById("deferToServer");
folderPopup.selectFolder(account.incomingServer.rootFolder);
updateInboxAccount(true, true);
}
radioGroup.value = "otherAccount";
folderPopup.selectFolder(account.incomingServer.rootFolder);
}
else
{
radioGroup.selectedItem = document.getElementById("accountDirectory");
// we should find out if there's another pop3/movemail server to defer to,
// perhaps by checking the number of elements in the picker. For now,
// just use the local folders account
folderPopup.selectFolder(localFoldersAccount.incomingServer.rootFolder);
updateInboxAccount(false, false);
// Current account is not deferred.
radioGroup.value = "currentAccount";
// If there are no other suitable accounts to defer to,
// then disable the option.
if (!folderPopup.selectFolder())
document.getElementById("deferToOtherAccount").disabled = true;
}
}
@ -106,7 +103,7 @@ function onOk()
var gPrefsBundle = document.getElementById("bundle_prefs");
// if this account wasn't deferred, and is now...
if (radioGroup.value != 1 && !gFirstDeferredAccount.length)
if (radioGroup.value != "currentAccount" && !gFirstDeferredAccount.length)
{
var confirmDeferAccount =
gPrefsBundle.getString("confirmDeferAccountWarning");
@ -118,14 +115,11 @@ function onOk()
}
switch (radioGroup.value)
{
case "0":
gServerSettings['deferredToAccount'] = getLocalFoldersAccount().key;
break;
case "1":
case "currentAccount":
gServerSettings['deferredToAccount'] = "";
break;
case "2":
var server = document.getElementById("deferedServerFolderPicker")
case "otherAccount":
let server = document.getElementById("deferredServerFolderPicker")
.selectedItem._folder.server;
let account = MailServices.accounts.FindAccountForServer(server);
gServerSettings['deferredToAccount'] = account.key;
@ -152,11 +146,8 @@ function onOk()
// Set radio element choices and picker states
function updateInboxAccount(enablePicker, enableDeferGetNewMail, event)
function updateInboxAccount(enablePicker)
{
var picker = document.getElementById('deferedServerFolderPicker');
picker.disabled = !enablePicker;
var deferCheckbox = document.getElementById('deferGetNewMail');
deferCheckbox.disabled = !enableDeferGetNewMail
document.getElementById("deferredServerFolderPicker").disabled = !enablePicker;
document.getElementById("deferGetNewMail").disabled = !enablePicker;
}

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

@ -105,25 +105,28 @@
<vbox id="pop3Panel">
<label flex="1" control="folderStorage">&pop3Desc.label;</label>
<hbox align="center">
<radiogroup id="folderStorage" orient="horizontal" amsa_persist="true">
<radiogroup id="folderStorage"
orient="horizontal"
amsa_persist="true"
onselect="updateInboxAccount(this.selectedIndex == 1);">
<rows>
<row>
<radio value="1" id = "accountDirectory" label="&accountDirectory.label;"
accesskey="&accountDirectory.accesskey;"
oncommand="updateInboxAccount(false, false)" />
</row>
<row align = "center">
<radio value="0" id = "globalInbox" label="&globalInbox.label;"
oncommand="updateInboxAccount(false, true)"
accesskey="&globalInbox.accesskey;"/>
<radio id="deferToCurrentAccount"
value="currentAccount"
label="&accountDirectory.label;"
accesskey="&accountDirectory.accesskey;"/>
</row>
<row>
<radio value="2" id="deferToServer" label="&deferToServer.label;"
accesskey="&deferToServer.accesskey;"
oncommand="updateInboxAccount(true, true)"/>
<menulist id="deferedServerFolderPicker" aria-labelledby="deferToServer">
<menupopup type="folder" id="deferedServerPopup"
expandFolders="false" mode="defered"/>
<radio id="deferToOtherAccount"
value="otherAccount"
label="&deferToServer.label;"
accesskey="&deferToServer.accesskey;"/>
<menulist id="deferredServerFolderPicker"
aria-labelledby="deferToServer">
<menupopup id="deferredServerPopup"
type="folder"
expandFolders="false"
mode="deferred"/>
</menulist>
</row>
</rows>

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

@ -99,6 +99,7 @@ function onAdvanced()
serverSettings.serverType = serverType;
serverSettings.serverPrettyName = gServer.prettyName;
serverSettings.account = top.getCurrentAccount();
if (serverType == "imap")
{
@ -297,7 +298,9 @@ function setupImapDeleteUI(aServerId)
trashPopup._parentFolder = GetMsgFolderFromUri(aServerId);
trashPopup._ensureInitialized();
var trashFolder = GetMsgFolderFromUri(aServerId+"/"+trashFolderName);
// TODO: There is something wrong here, selectFolder() fails even if the
// folder does exist. Try to fix in bug 802609.
let trashFolder = GetMsgFolderFromUri(aServerId + "/" + trashFolderName, false);
try {
trashPopup.selectFolder(trashFolder);
} catch(ex) {

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

@ -473,6 +473,7 @@ interface nsIMsgIncomingServer : nsISupports {
nsIMsgFolder getMsgFolderFromURI(in nsIMsgFolder aFolderResource, in ACString aURI);
/// Indicates if any other server has deferred storage to this account.
readonly attribute boolean isDeferredTo;
const long keepDups = 0;

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

@ -0,0 +1,7 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# LOCALIZATION NOTE(globalInbox)
# %S=name of the Local folders account
globalInbox=Global Inbox (%S)

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

@ -25,8 +25,6 @@
<!ENTITY overrideNamespaces.label "Allow server to override these namespaces">
<!ENTITY overrideNamespaces.accesskey "A">
<!ENTITY pop3Desc.label "When downloading pop mail for this server, use the following folder for new mail:" >
<!ENTITY globalInbox.label "Global Inbox (Local Folders Account)">
<!ENTITY globalInbox.accesskey "G">
<!ENTITY accountDirectory.label "Inbox for this server's account">
<!ENTITY accountDirectory.accesskey "S">
<!ENTITY deferToServer.label "Inbox for different account">

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

@ -260,6 +260,7 @@
locale/@AB_CD@/messenger/FilterListDialog.dtd (%chrome/mailnews/FilterListDialog.dtd)
locale/@AB_CD@/messenger/folderpane.dtd (%chrome/mailnews/folderpane.dtd)
locale/@AB_CD@/messenger/folderProps.dtd (%chrome/mailnews/folderProps.dtd)
locale/@AB_CD@/messenger/folderWidgets.properties (%chrome/mailnews/folderwidgets.properties)
locale/@AB_CD@/messenger/gloda.properties (%chrome/mailnews/gloda.properties)
locale/@AB_CD@/messenger/imapMsgs.properties (%chrome/mailnews/imapMsgs.properties)
locale/@AB_CD@/messenger/importDialog.dtd (%chrome/mailnews/importDialog.dtd)