summaryrefslogtreecommitdiffstats
path: root/mailnews/base/prefs/content/accountUtils.js
diff options
context:
space:
mode:
Diffstat (limited to 'mailnews/base/prefs/content/accountUtils.js')
-rw-r--r--mailnews/base/prefs/content/accountUtils.js462
1 files changed, 462 insertions, 0 deletions
diff --git a/mailnews/base/prefs/content/accountUtils.js b/mailnews/base/prefs/content/accountUtils.js
new file mode 100644
index 000000000..8b5020915
--- /dev/null
+++ b/mailnews/base/prefs/content/accountUtils.js
@@ -0,0 +1,462 @@
+/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* 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/. */
+
+Components.utils.import("resource://gre/modules/Services.jsm");
+Components.utils.import("resource:///modules/mailServices.js");
+
+var gAnyValidIdentity = false; //If there are no valid identities for any account
+// returns the first account with an invalid server or identity
+
+var gNewAccountToLoad = null; // used to load new messages if we come from the mail3pane
+
+function getInvalidAccounts(accounts)
+{
+ let numAccounts = accounts.length;
+ let invalidAccounts = new Array;
+ let numIdentities = 0;
+ for (let i = 0; i < numAccounts; i++) {
+ let account = accounts.queryElementAt(i, Components.interfaces.nsIMsgAccount);
+ try {
+ if (!account.incomingServer.valid) {
+ invalidAccounts[invalidAccounts.length] = account;
+ // skip to the next account
+ continue;
+ }
+ } catch (ex) {
+ // this account is busted, just keep going
+ continue;
+ }
+
+ var identities = account.identities;
+ numIdentities = identities.length;
+
+ for (var j = 0; j < numIdentities; j++) {
+ let identity = identities.queryElementAt(j, Components.interfaces.nsIMsgIdentity);
+ if (identity.valid) {
+ gAnyValidIdentity = true;
+ }
+ else {
+ invalidAccounts[invalidAccounts.length] = account;
+ }
+ }
+ }
+ return invalidAccounts;
+}
+
+function showMailIntegrationDialog() {
+ const nsIShellService = Components.interfaces.nsIShellService;
+
+ try {
+ var shellService = Components.classes["@mozilla.org/suite/shell-service;1"]
+ .getService(nsIShellService);
+ var appTypesCheck = shellService.shouldBeDefaultClientFor &
+ (nsIShellService.MAIL | nsIShellService.NEWS);
+
+ // show the default client dialog only if we have at least one account,
+ // if we should check for the default client, and we want to check if we are
+ // the default for mail/news and are not the default client for mail/news
+ if (appTypesCheck && shellService.shouldCheckDefaultClient &&
+ !shellService.isDefaultClient(true, appTypesCheck))
+ window.openDialog("chrome://communicator/content/defaultClientDialog.xul",
+ "DefaultClient", "modal,centerscreen,chrome,resizable=no");
+ } catch (ex) {}
+}
+
+/**
+ * Verify that there is at least one account. If not, open a new account wizard.
+ *
+ * @param wizardCallback if the wizard is run, callback when it is done.
+ * @param needsIdentity True only when verifyAccounts is called from the
+ * compose window. This last condition is so that we open
+ * the account wizard if the user does not have any
+ * identities defined and tries to compose mail.
+ * @param wizardOpen optional param that allows the caller to specify a
+ * different method to open a wizard. The wizardOpen method
+ * takes wizardCallback as an argument. The wizardCallback
+ * doesn't take any arguments.
+ */
+function verifyAccounts(wizardCallback, needsIdentity, wizardOpen)
+{
+ var openWizard = false;
+ var prefillAccount;
+ var state=true;
+ var ret = true;
+
+ try {
+ // migrate quoting preferences from global to per account. This function returns
+ // true if it had to migrate, which we will use to mean this is a just migrated
+ // or new profile
+ var newProfile = migrateGlobalQuotingPrefs(MailServices.accounts.allIdentities);
+
+ var accounts = MailServices.accounts.accounts;
+
+ // as long as we have some accounts, we're fine.
+ var accountCount = accounts.length;
+ var invalidAccounts = getInvalidAccounts(accounts);
+ if (invalidAccounts.length > 0 && invalidAccounts.length == accountCount) {
+ prefillAccount = invalidAccounts[0];
+ }
+
+ // if there are no accounts, or all accounts are "invalid"
+ // then kick off the account migration. Or if this is a new (to Mozilla) profile.
+ // MCD can set up accounts without the profile being used yet
+ if (newProfile) {
+ // check if MCD is configured. If not, say this is not a new profile
+ // so that we don't accidentally remigrate non MCD profiles.
+ var adminUrl;
+ try {
+ adminUrl = Services.prefs.getCharPref("autoadmin.global_config_url");
+ }
+ catch (ex) {}
+ if (!adminUrl)
+ newProfile = false;
+ }
+ if ((newProfile && !accountCount) || accountCount == invalidAccounts.length)
+ openWizard = true;
+
+ // openWizard is true if messenger migration returns some kind of
+ // error (including those cases where there is nothing to migrate).
+ // prefillAccount is non-null if there is at least one invalid account.
+ // gAnyValidIdentity is true when you've got at least one *valid*
+ // identity. Since local and RSS folders are identity-less accounts, if you
+ // only have one of those, it will be false.
+ // needsIdentity is true only when verifyAccounts is called from the
+ // compose window. This last condition is so that we open the account
+ // wizard if the user does not have any identities defined and tries to
+ // compose mail.
+
+ if (openWizard || prefillAccount || ((!gAnyValidIdentity) && needsIdentity))
+ {
+ if (wizardOpen != undefined)
+ wizardOpen(wizardCallback)
+ else
+ MsgAccountWizard(wizardCallback);
+ ret = false;
+ }
+ else
+ {
+ var localFoldersExists;
+ try
+ {
+ localFoldersExists = MailServices.accounts.localFoldersServer;
+ }
+ catch (ex)
+ {
+ localFoldersExists = false;
+ }
+
+ // we didn't create the MsgAccountWizard - we need to verify that local folders exists.
+ if (!localFoldersExists)
+ MailServices.accounts.createLocalMailAccount();
+ }
+
+ // This will do nothing on platforms without a shell service
+ const NS_SHELLSERVICE_CID = "@mozilla.org/suite/shell-service;1"
+ if (NS_SHELLSERVICE_CID in Components.classes)
+ {
+ // hack, set a time out to do this, so that the window can load first
+ setTimeout(showMailIntegrationDialog, 0);
+ }
+ return ret;
+ }
+ catch (ex) {
+ dump("error verifying accounts " + ex + "\n");
+ return false;
+ }
+}
+
+// we do this from a timer because if this is called from the onload=
+// handler, then the parent window doesn't appear until after the wizard
+// has closed, and this is confusing to the user
+function MsgAccountWizard(wizardCallback)
+{
+ setTimeout(function() { msgOpenAccountWizard(wizardCallback); }, 0);
+}
+
+/**
+ * Open the Old Mail Account Wizard, or focus it if it's already open.
+ *
+ * @param wizardCallback if the wizard is run, callback when it is done.
+ * @param type - optional account type token, for Tb.
+ * @see msgNewMailAccount below for the new implementation.
+ */
+function msgOpenAccountWizard(wizardCallback, type)
+{
+ gNewAccountToLoad = null;
+
+ window.openDialog("chrome://messenger/content/AccountWizard.xul", "AccountWizard",
+ "chrome,modal,titlebar,centerscreen",
+ {okCallback: wizardCallback, acctType: type});
+
+ loadInboxForNewAccount();
+
+ // If we started with no servers at all and "smtp servers" list selected,
+ // refresh display somehow. Bug 58506.
+ // TODO Better fix: select newly created account (in all cases)
+ if (typeof(getCurrentAccount) == "function" && // in AccountManager, not menu
+ !getCurrentAccount())
+ selectServer(null, null);
+}
+
+function initAccountWizardTB(args) {
+ let type = args[0] && args[0].acctType;
+ let selType = type == "newsgroups" ? "newsaccount" :
+ type == "movemail" ? "Movemail" : null;
+ let accountwizard = document.getElementById("AccountWizard");
+ let acctyperadio = document.getElementById("acctyperadio");
+ let feedRadio = acctyperadio.querySelector("radio[value='Feeds']");
+ if (feedRadio)
+ feedRadio.remove();
+ if (selType) {
+ acctyperadio.selectedItem = acctyperadio.querySelector("radio[value='"+selType+"']");
+ accountwizard.advance("identitypage");
+ }
+ else
+ acctyperadio.selectedItem = acctyperadio.getItemAtIndex(0);
+}
+
+function AddFeedAccount() {
+ window.openDialog("chrome://messenger-newsblog/content/feedAccountWizard.xul",
+ "", "chrome,modal,titlebar,centerscreen");
+}
+
+/**
+ * Opens the account settings window on the specified account
+ * and page of settings. If the window is already open it is only focused.
+ *
+ * @param selectPage The xul file name for the viewing page or
+ * null for the account main page. Other pages are
+ * 'am-server.xul', 'am-copies.xul', 'am-offline.xul',
+ * 'am-addressing.xul', 'am-smtp.xul'
+ * @param aServer The server of the account to select. Optional.
+ */
+function MsgAccountManager(selectPage, aServer)
+{
+ var existingAccountManager = Services.wm.getMostRecentWindow("mailnews:accountmanager");
+
+ if (existingAccountManager)
+ existingAccountManager.focus();
+ else {
+ if (!aServer) {
+ if (typeof GetSelectedMsgFolders === "function") {
+ let folders = GetSelectedMsgFolders();
+ if (folders.length > 0)
+ aServer = folders[0].server;
+ }
+ if (!aServer && (typeof GetDefaultAccountRootFolder === "function")) {
+ let folder = GetDefaultAccountRootFolder();
+ if (folder instanceof Components.interfaces.nsIMsgFolder)
+ aServer = folder.server;
+ }
+ }
+
+ window.openDialog("chrome://messenger/content/AccountManager.xul",
+ "AccountManager",
+ "chrome,centerscreen,modal,titlebar,resizable",
+ { server: aServer, selectPage: selectPage });
+ }
+}
+
+function loadInboxForNewAccount()
+{
+ // gNewAccountToLoad is set in the final screen of the Account Wizard if a POP account
+ // was created, the download messages box is checked, and the wizard was opened from the 3pane
+ if (gNewAccountToLoad) {
+ var rootMsgFolder = gNewAccountToLoad.incomingServer.rootMsgFolder;
+ const kInboxFlag = Components.interfaces.nsMsgFolderFlags.Inbox;
+ var inboxFolder = rootMsgFolder.getFolderWithFlags(kInboxFlag);
+ SelectFolder(inboxFolder.URI);
+ window.focus();
+ setTimeout(MsgGetMessage, 0);
+ gNewAccountToLoad = null;
+ }
+}
+
+// returns true if we migrated - it knows this because 4.x did not have the
+// pref mailnews.quotingPrefs.version, so if it's not set, we're either
+// migrating from 4.x, or a much older version of Mozilla.
+function migrateGlobalQuotingPrefs(allIdentities)
+{
+ // if reply_on_top and auto_quote exist then, if non-default
+ // migrate and delete, if default just delete.
+ var reply_on_top = 0;
+ var auto_quote = true;
+ var quotingPrefs = 0;
+ var migrated = false;
+ try {
+ quotingPrefs = Services.prefs.getIntPref("mailnews.quotingPrefs.version");
+ } catch (ex) {}
+
+ // If the quotingPrefs version is 0 then we need to migrate our preferences
+ if (quotingPrefs == 0) {
+ migrated = true;
+ try {
+ reply_on_top = Services.prefs.getIntPref("mailnews.reply_on_top");
+ auto_quote = Services.prefs.getBoolPref("mail.auto_quote");
+ } catch (ex) {}
+
+ if (!auto_quote || reply_on_top) {
+ let numIdentities = allIdentities.length;
+ var identity = null;
+ for (var j = 0; j < numIdentities; j++) {
+ identity = allIdentities.queryElementAt(j, Components.interfaces.nsIMsgIdentity);
+ if (identity.valid) {
+ identity.autoQuote = auto_quote;
+ identity.replyOnTop = reply_on_top;
+ }
+ }
+ }
+ Services.prefs.setIntPref("mailnews.quotingPrefs.version", 1);
+ }
+ return migrated;
+}
+
+// we do this from a timer because if this is called from the onload=
+// handler, then the parent window doesn't appear until after the wizard
+// has closed, and this is confusing to the user
+function NewMailAccount(msgWindow, okCallback, extraData)
+{
+ if (!msgWindow)
+ throw new Error("NewMailAccount must be given a msgWindow.");
+
+ // Populate the extra data.
+ if (!extraData)
+ extraData = {};
+ extraData.msgWindow = msgWindow;
+
+ let mail3Pane = Services.wm.getMostRecentWindow("mail:3pane");
+
+ if (!extraData.NewMailAccount)
+ extraData.NewMailAccount = NewMailAccount;
+
+ if (!extraData.msgNewMailAccount)
+ extraData.msgNewMailAccount = msgNewMailAccount;
+
+ if (!extraData.NewComposeMessage)
+ extraData.NewComposeMessage = mail3Pane.ComposeMessage;
+
+ if (!extraData.openAddonsMgr)
+ extraData.openAddonsMgr = mail3Pane.openAddonsMgr;
+
+ if (!extraData.okCallback)
+ extraData.okCallback = null;
+
+ if (!extraData.success)
+ extraData.success = false;
+
+ setTimeout(extraData.msgNewMailAccount, 0, msgWindow, okCallback, extraData);
+}
+
+function NewMailAccountProvisioner(aMsgWindow, args) {
+ if (!args)
+ args = {};
+ if (!aMsgWindow)
+ aMsgWindow = MailServices.mailSession.topmostMsgWindow;
+
+ args.msgWindow = aMsgWindow;
+
+ let mail3Pane = Services.wm.getMostRecentWindow("mail:3pane");
+
+ // If we couldn't find a 3pane, bail out.
+ if (!mail3Pane) {
+ Components.utils.reportError("Could not find a 3pane to connect to.");
+ return;
+ }
+
+ let tabmail = mail3Pane.document.getElementById("tabmail");
+
+ if (!tabmail) {
+ Components.utils.reportError("Could not find a tabmail in the 3pane!");
+ return;
+ }
+
+ // If there's already an accountProvisionerTab open, just focus it instead
+ // of opening a new dialog.
+ let apTab = tabmail.getTabInfoForCurrentOrFirstModeInstance(
+ tabmail.tabModes["accountProvisionerTab"]);
+
+ if (apTab) {
+ tabmail.switchToTab(apTab);
+ return;
+ }
+
+ // XXX make sure these are all defined in all contexts... to be on the safe
+ // side, just get a mail:3pane and borrow the functions from it?
+ if (!args.NewMailAccount)
+ args.NewMailAccount = NewMailAccount;
+
+ if (!args.msgNewMailAccount)
+ args.msgNewMailAccount = msgNewMailAccount;
+
+ if (!args.NewComposeMessage)
+ args.NewComposeMessage = mail3Pane.ComposeMessage;
+
+ if (!args.openAddonsMgr)
+ args.openAddonsMgr = mail3Pane.openAddonsMgr;
+
+ if (!args.okCallback)
+ args.okCallback = null;
+
+ let windowParams = "chrome,titlebar,centerscreen,width=640,height=480";
+
+ if (!args.success) {
+ args.success = false;
+ // If we're not opening up the success dialog, then our window should be
+ // modal.
+ windowParams = "modal," + windowParams;
+ }
+
+ // NOTE: If you're a developer, and you notice that the jQuery code in
+ // accountProvisioner.xhtml isn't throwing errors or warnings, that's due
+ // to bug 688273. Just make the window non-modal to get those errors and
+ // warnings back, and then clear this comment when bug 688273 is closed.
+ window.openDialog(
+ "chrome://messenger/content/newmailaccount/accountProvisioner.xhtml",
+ "AccountCreation",
+ windowParams,
+ args);
+}
+
+/**
+ * Open the New Mail Account Wizard, or focus it if it's already open.
+ *
+ * @param msgWindow a msgWindow for us to use to verify the accounts.
+ * @param okCallback an optional callback for us to call back to if
+ * everything's okay.
+ * @param extraData an optional param that allows us to pass data in and
+ * out. Used in the upcoming AccountProvisioner add-on.
+ * @see msgOpenAccountWizard above for the previous implementation.
+ */
+function msgNewMailAccount(msgWindow, okCallback, extraData)
+{
+ if (!msgWindow)
+ throw new Error("msgNewMailAccount must be given a msgWindow.");
+
+ let existingWindow = Services.wm.getMostRecentWindow("mail:autoconfig");
+ if (existingWindow) {
+ existingWindow.focus();
+ } else {
+ // disabling modal for the time being, see 688273 REMOVEME
+ window.openDialog("chrome://messenger/content/accountcreation/emailWizard.xul",
+ "AccountSetup", "chrome,titlebar,centerscreen",
+ {msgWindow:msgWindow,
+ okCallback:okCallback,
+ extraData:extraData});
+ }
+
+ /*
+ // TODO: Enable this block of code once the dialog above is made modal.
+ // If we started with no servers at all and "smtp servers" list selected,
+ // refresh display somehow. Bug 58506.
+ // TODO Better fix: select newly created account (in all cases)
+ let existingAccountManager =
+ Services.wm.getMostRecentWindow("mailnews:accountmanager");
+ // in AccountManager, not menu
+ if (existingAccountManager && typeof(getCurrentAccount) == "function" &&
+ !getCurrentAccount()) {
+ selectServer(null, null);
+ }
+ */
+}