/* -*- 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); } */ }