home *** CD-ROM | disk | FTP | other *** search
/ Chip 2002 January / 01_02.iso / software / netscape62win / mail.xpi / bin / chrome / messenger.jar / content / messenger / AccountManager.js next >
Text File  |  2001-10-08  |  26KB  |  880 lines

  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  * The contents of this file are subject to the Netscape Public
  3.  * License Version 1.1 (the "License"); you may not use this file
  4.  * except in compliance with the License. You may obtain a copy of
  5.  * the License at http://www.mozilla.org/NPL/
  6.  *
  7.  * Software distributed under the License is distributed on an "AS
  8.  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  9.  * implied. See the License for the specific language governing
  10.  * rights and limitations under the License.
  11.  *
  12.  * The Original Code is Mozilla Communicator client code, released
  13.  * March 31, 1998.
  14.  *
  15.  * The Initial Developer of the Original Code is Netscape
  16.  * Communications Corporation. Portions created by Netscape are
  17.  * Copyright (C) 1998-1999 Netscape Communications Corporation. All
  18.  * Rights Reserved.
  19.  */
  20.  
  21. /*
  22.  * here's how this dialog works:
  23.  * The main dialog contains a tree on the left (accounttree) and a
  24.  * deck on the right. Each card in the deck on the right contains an
  25.  * IFRAME which loads a particular preference document (such as am-main.xul)
  26.  *
  27.  * when the user clicks on items in the tree on the right, two things have
  28.  * to be determined before the UI can be updated:
  29.  * - the relevant account
  30.  * - the relevant page
  31.  *
  32.  * when both of these are known, this is what happens:
  33.  * - every form element of the previous page is saved in the account value
  34.  *   hashtable for the previous account
  35.  * - the card containing the relevant page is brought to the front
  36.  * - each form element in the page is filled in with an appropriate value
  37.  *   from the current account's hashtable
  38.  * - in the IFRAME inside the page, if there is an onInit() method,
  39.  *   it is called. The onInit method can further update this page based
  40.  *   on values set in the previous step.
  41.  */
  42.  
  43.  
  44. var accountArray;
  45. var accounttree;
  46.  
  47. var currentServerId;
  48. var currentPageId;
  49.  
  50. var pendingServerId;
  51. var pendingPageId;
  52. var gPrefsBundle;
  53.  
  54. // services used
  55. var RDF;
  56. var accountManager;
  57. var smtpService;
  58. var nsPrefBranch;
  59.  
  60. // widgets
  61. var duplicateButton;
  62. var deleteButton;
  63. var newAccountButton;
  64. var setDefaultButton;
  65.  
  66. // This sets an attribute in a xul element so that we can later
  67. // know what value to substitute in a prefstring.  Different
  68. // preference types set different attributes.  We get the value
  69. // in the same way as the function getAccountValue() determines it.
  70. function updateElementWithKeys(account, element, type) {
  71.     switch (type)
  72.     {
  73.     case "identity":
  74.       element["identitykey"] = account.defaultIdentity.key;
  75.       break;
  76.     case "pop3":
  77.     case "imap":
  78.     case "nntp":
  79.     case "server":
  80.       element["serverkey"] = account.incomingServer.key;
  81.       break;
  82.     case "smtp":
  83.       element["serverkey"] = smtpService.defaultServer.key;
  84.       break;
  85.     default:
  86. //      dump("unknown element type! "+type+"\n");
  87.       break;
  88.     }
  89. }
  90.  
  91. // called when the whole document loads
  92. // perform initialization here
  93. function onLoad() {
  94.   gPrefsBundle = document.getElementById("bundle_prefs");
  95.  
  96.   var selectedServer;
  97.   var selectPage = null;
  98.   if (window.arguments && window.arguments[0]) {
  99.     selectedServer = window.arguments[0].server;
  100.     selectPage = window.arguments[0].selectPage;
  101.   }
  102.  
  103.   accountArray = new Array;
  104.   RDF = Components.classes["@mozilla.org/rdf/rdf-service;1"].getService(Components.interfaces.nsIRDFService);
  105.  
  106.   accountManager = Components.classes["@mozilla.org/messenger/account-manager;1"].getService(Components.interfaces.nsIMsgAccountManager);
  107.  
  108.   smtpService =
  109.     Components.classes["@mozilla.org/messengercompose/smtp;1"].getService(Components.interfaces.nsISmtpService);
  110.   accounttree = document.getElementById("accounttree");
  111.  
  112.   var prefService = Components.classes["@mozilla.org/preferences-service;1"];
  113.   prefService = prefService.getService();
  114.   prefService=prefService.QueryInterface(Components.interfaces.nsIPrefService);
  115.   nsPrefBranch = prefService.getBranch(null);
  116.  
  117.   doSetOKCancel(onOk, 0);
  118.  
  119.   newAccountButton = document.getElementById("newAccountButton");
  120.   duplicateButton = document.getElementById("duplicateButton");
  121.   deleteButton = document.getElementById("deleteButton");
  122.   setDefaultButton = document.getElementById("setDefaultButton");
  123.  
  124.   sortAccountList(accounttree);
  125.   selectServer(selectedServer, selectPage);
  126. }
  127.  
  128. function sortAccountList(accounttree)
  129. {
  130.   var xulSortService = Components.classes["@mozilla.org/xul/xul-sort-service;1"].getService(Components.interfaces.nsIXULSortService);
  131.  
  132.   xulSortService.Sort(accounttree, 'http://home.netscape.com/NC-rdf#FolderTreeName?sort=true', 'ascending');
  133. }
  134.  
  135. function selectServer(server, selectPage)
  136. {
  137.   var selectedItem;
  138.  
  139.   if (server) {
  140.     selectedItem = document.getElementById(server.serverURI);
  141.     if (selectedItem && selectPage) 
  142.       selectedItem = findSelectPage(selectedItem, selectPage);
  143.   }
  144.  
  145.   if (!selectedItem)
  146.     selectedItem = getFirstAccount();
  147.  
  148.   accounttree.selectItem(selectedItem);
  149.  
  150.   var result = getServerIdAndPageIdFromTree(accounttree);
  151.   if (result) {
  152.     updateButtons(accounttree,result.serverId);
  153.   }
  154. }
  155.  
  156. function findSelectPage(selectServer, selectPage)
  157. {
  158.   var children = selectServer.childNodes;
  159.   for (i=0; i < children.length; i++) 
  160.   { 
  161.     if (children[i].localName == "treechildren") {
  162.       var pageNodes = children[i].childNodes;
  163.       for (j=0; j < pageNodes.length; j++) {
  164.         if (pageNodes[j].localName == "treeitem") {          
  165.           var page = pageNodes[j].getAttribute('PageTag');
  166.           if (page == selectPage) {
  167.             return pageNodes[j];
  168.           }
  169.         }
  170.       }
  171.     }
  172.   }
  173.   return null;
  174. }
  175.  
  176. function getFirstAccount()
  177. {
  178.   var tree = document.getElementById("accounttree");
  179.   var firstItem = findFirstTreeItem(tree);
  180.  
  181.   return firstItem;
  182. }
  183.  
  184. function findFirstTreeItem(tree) {
  185.   var children = tree.childNodes;
  186.  
  187.   var treechildren;
  188.   for (var i=0;i<children.length; i++) {
  189.     if (children[i].localName == "treechildren") {
  190.       treechildren = children[i];
  191.       break;
  192.     }
  193.   }
  194.  
  195.   children = treechildren.childNodes;
  196.   for (i=0; i<children.length; i++) {
  197.     if (children[i].localName == "treeitem")
  198.       return children[i];
  199.   }
  200.   return null;
  201. }
  202.  
  203. function onOk() {
  204.   onSave();
  205.     // hack hack - save the prefs file NOW in case we crash
  206.     try {
  207.         var prefs = Components.classes["@mozilla.org/preferences;1"].getService(Components.interfaces.nsIPref);
  208.         prefs.savePrefFile(null);
  209.     } catch (ex) {
  210.         dump("Error saving prefs!\n");
  211.     }
  212.   return true;
  213. }
  214.  
  215. function onSave() {
  216.  
  217.   if (pendingPageId) {
  218.     dump("ERROR: " + pendingPageId + " hasn't loaded yet! Not saving.\n");
  219.     return;
  220.   }
  221.  
  222.   // make sure the current visible page is saved
  223.   savePage(currentServerId);
  224.  
  225.   for (var accountid in accountArray) {
  226.     var account = getAccountFromServerId(accountid);
  227.     var accountValues = accountArray[accountid];
  228.  
  229.     saveAccount(accountValues, account);
  230.   }
  231. }
  232.  
  233. function onNewAccount() {
  234.   MsgAccountWizard();
  235. }
  236.  
  237. function onDuplicateAccount() {
  238.     //dump("onDuplicateAccount\n");
  239.  
  240.     if (duplicateButton.getAttribute("disabled") == "true") return;
  241.  
  242.     var result = getServerIdAndPageIdFromTree(accounttree);
  243.     if (result) {
  244.         var canDuplicate = true;
  245.         var account = getAccountFromServerId(result.serverId);
  246.         if (account) {
  247.             var server = account.incomingServer;
  248.             var type = server.type;
  249.  
  250.       var protocolinfo = Components.classes["@mozilla.org/messenger/protocol/info;1?type=" + type].getService(Components.interfaces.nsIMsgProtocolInfo);
  251.       canDuplicate = protocolinfo.canDuplicate;
  252.         }
  253.         else {
  254.             canDuplicate = false;
  255.         }
  256.  
  257.         if (canDuplicate) {
  258.       try {
  259.               accountManager.duplicateAccount(account);
  260.             }
  261.       catch (ex) {
  262.         var alertText = gPrefsBundle.getString("failedDuplicateAccount");
  263.                 window.alert(alertText);
  264.       }
  265.         }
  266.     }
  267. }
  268.  
  269. function onSetDefault(event) {
  270.   if (event.target.getAttribute("disabled") == "true") return;
  271.  
  272.   var result = getServerIdAndPageIdFromTree(accounttree);
  273.   if (!result) return;
  274.  
  275.   var account = getAccountFromServerId(result.serverId);
  276.   if (!account) return;
  277.  
  278.   accountManager.defaultAccount = account;
  279. }
  280.  
  281. function onDeleteAccount(event) {
  282.     //dump("onDeleteAccount\n");
  283.  
  284.     if (event.target.getAttribute("disabled") == "true") return;
  285.  
  286.   var result = getServerIdAndPageIdFromTree(accounttree);
  287.     if (!result) return;
  288.  
  289.     var account = getAccountFromServerId(result.serverId);
  290.     if (!account) return;
  291.  
  292.     var server = account.incomingServer;
  293.     var type = server.type;
  294.  
  295.     var protocolinfo = Components.classes["@mozilla.org/messenger/protocol/info;1?type=" + type].getService(Components.interfaces.nsIMsgProtocolInfo);
  296.     var canDelete = protocolinfo.canDelete;
  297.     if (!canDelete) {
  298.         canDelete = server.canDelete;
  299.     }
  300.     if (!canDelete) return;
  301.  
  302.     var confirmDeleteAccount =
  303.       gPrefsBundle.getString("confirmDeleteAccount");
  304.     if (!window.confirm(confirmDeleteAccount)) return;
  305.  
  306.     try {
  307.       // clear cached data out of the account array
  308.       if (accountArray[result.serverId])
  309.         accountArray[result.serverId] = null;
  310.       currentServerId = currentPageId = null;
  311.  
  312.       accountManager.removeAccount(account);
  313.       selectServer(null);
  314.     }
  315.     catch (ex) {
  316.       dump("failure to delete account: " + ex + "\n");
  317.       var alertText = gPrefsBundle.getString("failedDeleteAccount");
  318.       window.alert(alertText);
  319.     }
  320. }
  321.  
  322. function saveAccount(accountValues, account)
  323. {
  324.   var identity = null;
  325.   var server = null;
  326.  
  327.   if (account) {
  328.     identity = account.defaultIdentity;
  329.     server = account.incomingServer;
  330.   }
  331.  
  332.   for (var type in accountValues) {
  333.     var typeArray = accountValues[type];
  334.  
  335.     for (var slot in typeArray) {
  336.       var dest;
  337.       try {
  338.       if (type == "identity")
  339.         dest = identity;
  340.       else if (type == "server")
  341.         dest = server;
  342.       else if (type == "pop3")
  343.         dest = server.QueryInterface(Components.interfaces.nsIPop3IncomingServer);
  344.  
  345.       else if (type == "imap")
  346.         dest = server.QueryInterface(Components.interfaces.nsIImapIncomingServer);
  347.  
  348.       else if (type == "none")
  349.         dest = server.QueryInterface(Components.interfaces.nsINoIncomingServer);
  350.  
  351.       else if (type == "nntp")
  352.         dest = server.QueryInterface(Components.interfaces.nsINntpIncomingServer);
  353.       else if (type == "smtp")
  354.         dest = smtpService.defaultServer;
  355.  
  356.       } catch (ex) {
  357.         // don't do anything, just means we don't support that
  358.       }
  359.       if (dest == undefined) continue;
  360.  
  361.       if (dest[slot] != typeArray[slot]) {
  362.         try {
  363.           dest[slot] = typeArray[slot];
  364.         } catch (ex) {
  365.           // hrm... need to handle special types here
  366.         }
  367.       }
  368.     }
  369.   }
  370. }
  371.  
  372.  
  373. function updateButtons(tree,serverId) {
  374.   var canCreate = true;
  375.   var canDuplicate = true;
  376.   var canDelete = true;
  377.   var canSetDefault = true;
  378.  
  379.   //dump("updateButtons\n");
  380.   //dump("serverId = " + serverId + "\n");
  381.   var account = getAccountFromServerId(serverId);
  382.   //dump("account = " + account + "\n");
  383.  
  384.   if (account) {
  385.   var server = account.incomingServer;
  386.   var type = server.type;
  387.  
  388.     if (account.identities.Count() < 1)
  389.       canSetDefault = false;
  390.  
  391.   //dump("servertype = " + type + "\n");
  392.  
  393.   var protocolinfo = Components.classes["@mozilla.org/messenger/protocol/info;1?type=" + type].getService(Components.interfaces.nsIMsgProtocolInfo);
  394.     canDuplicate = protocolinfo.canDuplicate;
  395.     canDelete = protocolinfo.canDelete;
  396.     if (!canDelete) {
  397.       canDelete = server.canDelete;
  398.     }
  399.   }
  400.   else {
  401.   // HACK
  402.   // if account is null, we have either selected a SMTP server, or there is a problem
  403.   // either way, we don't want the user to be able to delete it or duplicate it
  404.     canSetDefault = false;
  405.   canDelete = false;
  406.   canDuplicate = false;
  407.   }
  408.  
  409.   if (tree.selectedItems.length < 1)
  410.     canDuplicate = canSetDefault = canDelete = false;
  411.  
  412.   // check for disabled preferences on the account buttons.  
  413.   //  Not currently handled by WSM or the main loop yet since these buttons aren't
  414.   //  under the IFRAME
  415.   if (nsPrefBranch.prefIsLocked(newAccountButton.getAttribute("prefstring")))
  416.     canCreate = false;
  417.   //if (nsPrefBranch.prefIsLocked(duplicateButton.getAttribute("prefstring")))
  418.   //  canDuplicate = false;
  419.   if (nsPrefBranch.prefIsLocked(setDefaultButton.getAttribute("prefstring")))
  420.     canSetDefault = false;
  421.   if (nsPrefBranch.prefIsLocked(deleteButton.getAttribute("prefstring")))
  422.     canDelete = false;
  423.  
  424.   setEnabled(newAccountButton, canCreate);
  425.   setEnabled(duplicateButton, canDuplicate);
  426.   setEnabled(setDefaultButton, canSetDefault);
  427.   setEnabled(deleteButton, canDelete);
  428.  
  429. }
  430.  
  431. function setEnabled(control, enabled)
  432. {
  433.   if (!control) return;
  434.   if (enabled)
  435.     control.removeAttribute("disabled");
  436.   else
  437.     control.setAttribute("disabled", true);
  438. }
  439.  
  440. // this is a workaround for bug #51546
  441. // the on click handler is getting called twice
  442. var bug51546CurrentPage = null;
  443. var bug51546CurrentServerId = null;
  444.  
  445. //
  446. // called when someone clicks on an account
  447. // figure out context by what they clicked on
  448. //
  449. function onAccountClick(tree) {
  450.   //dump("onAccountClick()\n");
  451.  
  452.   var result = getServerIdAndPageIdFromTree(tree);
  453.  
  454.   //dump("sputter:"+bug51546CurrentPage+","+bug51546CurrentServerId+":"+result.pageId+","+result.serverId+"\n");
  455.   if ((bug51546CurrentPage == result.pageId) && (bug51546CurrentServerId == result.serverId)) {
  456.   //dump("workaround for #51546\n");
  457.   return;
  458.   }
  459.  
  460.   bug51546CurrentPage = result.pageId;
  461.   bug51546CurrentServerId = result.serverId;
  462.  
  463.   if (result) {
  464.     showPage(result.serverId, result.pageId);
  465.     updateButtons(tree,result.serverId);
  466.   }
  467. }
  468.  
  469. // show the page for the given server:
  470. // - save the old values
  471. // - start loading the new page
  472. function showPage(serverId, pageId) {
  473.  
  474.   if (pageId == currentPageId &&
  475.       serverId == currentServerId)
  476.     return;
  477.  
  478.  
  479.   // save the previous page
  480.   savePage(currentServerId);
  481.  
  482.   // loading a complete different page
  483.   if (pageId != currentPageId) {
  484.  
  485.     // prevent overwriting with bad stuff
  486.     currentServerId = currentPageId = null;
  487.  
  488.     pendingServerId=serverId;
  489.     pendingPageId=pageId;
  490.     loadPage(pageId);
  491.   }
  492.  
  493.   // same page, different server
  494.   else if (serverId != currentServerId) {
  495.     restorePage(pageId, serverId);
  496.   }
  497.  
  498. }
  499.  
  500. // page has loaded
  501. function onPanelLoaded(pageId) {
  502.   if (pageId != pendingPageId) {
  503.  
  504.     // if we're reloading the current page, we'll assume the
  505.     // page has asked itself to be completely reloaded from
  506.     // the prefs. to do this, clear out the the old entry in
  507.     // the account data, and then restore theh page
  508.     if (pageId == currentPageId) {
  509.       clearAccountData(currentServerId, currentPageId);
  510.       restorePage(currentPageId, currentServerId);
  511.     }
  512.   } else {
  513.  
  514.     restorePage(pendingPageId, pendingServerId);
  515.   }
  516.  
  517.   // probably unnecessary, but useful for debugging
  518.   pendingServerId = null;
  519.   pendingPageId = null;
  520. }
  521.  
  522.  
  523. function loadPage(pageId)
  524. {
  525.   document.getElementById("contentFrame").setAttribute("src","chrome://messenger/content/" + pageId);
  526. }
  527.  
  528. //
  529. // save the values of the widgets to the given server
  530. //
  531. function savePage(serverId) {
  532.  
  533.   if (!serverId) return;
  534.  
  535.   // tell the page that it's about to save
  536.   if (top.frames["contentFrame"].onSave)
  537.       top.frames["contentFrame"].onSave();
  538.  
  539.   var accountValues = getValueArrayFor(serverId);
  540.   var pageElements = getPageFormElements();
  541.  
  542.   if (pageElements == null) return;
  543.  
  544.   // store the value in the account
  545.   for (var i=0; i<pageElements.length; i++) {
  546.       if (pageElements[i].id) {
  547.         var vals = pageElements[i].id.split(".");
  548.         var type = vals[0];
  549.         var slot = vals[1];
  550.  
  551.         setAccountValue(accountValues,
  552.                         type, slot,
  553.                         getFormElementValue(pageElements[i]));
  554.       }
  555.   }
  556.  
  557. }
  558.  
  559. function setAccountValue(accountValues, type, slot, value) {
  560.   if (!accountValues[type])
  561.     accountValues[type] = new Array;
  562.  
  563.   //dump("Form->Array: accountValues[" + type + "][" + slot + "] = " + value + "\n");
  564.  
  565.   accountValues[type][slot] = value;
  566. }
  567.  
  568. function getAccountValue(account, accountValues, type, slot) {
  569.   if (!accountValues[type])
  570.     accountValues[type] = new Array;
  571.  
  572.   // fill in the slot from the account if necessary
  573.   if (accountValues[type][slot]== undefined) {
  574.     // dump("Array->Form: lazily reading in the " + slot + " from the " + type + "\n");
  575.     var server;
  576.     if (account)
  577.       server= account.incomingServer;
  578.     var source = null;
  579.     try {
  580.     if (type == "identity")
  581.       source = account.defaultIdentity;
  582.  
  583.     else if (type == "server")
  584.       source = account.incomingServer;
  585.  
  586.     else if (type == "pop3")
  587.       source = server.QueryInterface(Components.interfaces.nsIPop3IncomingServer);
  588.  
  589.     else if (type == "imap")
  590.       source = server.QueryInterface(Components.interfaces.nsIImapIncomingServer);
  591.  
  592.     else if (type == "none")
  593.       source = server.QueryInterface(Components.interfaces.nsINoIncomingServer);
  594.  
  595.     else if (type == "nntp")
  596.       source = server.QueryInterface(Components.interfaces.nsINntpIncomingServer);
  597.  
  598.     else if (type == "smtp")
  599.         source = smtpService.defaultServer;
  600.  
  601.     } catch (ex) {
  602.     }
  603.  
  604.     if (source) {
  605.       accountValues[type][slot] = source[slot];
  606.     }
  607.   }
  608.   var value = accountValues[type][slot];
  609.   //dump("Array->Form: accountValues[" + type + "][" + slot + "] = " + value + "\n");
  610.   return value;
  611. }
  612. //
  613. // restore the values of the widgets from the given server
  614. //
  615. function restorePage(pageId, serverId) {
  616.   if (!serverId) return;
  617.   var accountValues = getValueArrayFor(serverId);
  618.   var pageElements = getPageFormElements();
  619.  
  620.   if (pageElements == null) return;
  621.  
  622.   var account = getAccountFromServerId(serverId);
  623.  
  624.   if (top.frames["contentFrame"].onPreInit)
  625.     top.frames["contentFrame"].onPreInit(account, accountValues);
  626.  
  627.   // restore the value from the account
  628.   for (var i=0; i<pageElements.length; i++) {
  629.       if (pageElements[i].id) {
  630.         var vals = pageElements[i].id.split(".");
  631.         var type = vals[0];
  632.         var slot = vals[1];
  633.         // buttons are lockable, but don't have any data so we skip that part.
  634.         // elements that do have data, we get the values at poke them in.
  635.         if (pageElements[i].localName != "button") {
  636.           var value = getAccountValue(account, accountValues, type, slot);
  637.           setFormElementValue(pageElements[i], value);
  638.         }
  639.         updateElementWithKeys(account,pageElements[i],type);
  640.         var isLocked = getAccountValueIsLocked(pageElements[i]);
  641.         setEnabled(pageElements[i],!isLocked);
  642.       }
  643.   }
  644.  
  645.   // tell the page that new values have been loaded
  646.   if (top.frames["contentFrame"].onInit)
  647.       top.frames["contentFrame"].onInit();
  648.  
  649.   // everything has succeeded, vervied by setting currentPageId
  650.   currentPageId = pageId;
  651.   currentServerId = serverId;
  652.  
  653. }
  654.  
  655. //
  656. // gets the value of a widget
  657. //
  658. function getFormElementValue(formElement) {
  659.  try {
  660.   var type = formElement.localName;
  661.   if (type=="checkbox") {
  662.     if (formElement.getAttribute("reversed"))
  663.       return !formElement.checked;
  664.     else
  665.       return formElement.checked;
  666.   }
  667.  
  668.   else if (type == "radiogroup" || type=="menulist") {
  669.     return formElement.selectedItem.value;
  670.   }
  671.  
  672.   else if (type == "textbox" &&
  673.            formElement.getAttribute("datatype") == "nsIFileSpec") {
  674.     if (formElement.value) {
  675.       var filespec = Components.classes["@mozilla.org/filespec;1"].createInstance(Components.interfaces.nsIFileSpec);
  676.       filespec.nativePath = formElement.value;
  677.       return filespec;
  678.     } else {
  679.       return null;
  680.     }
  681.   }
  682.   else if (type == "textbox" &&
  683.            formElement.getAttribute("datatype") == "nsILocalFile") {
  684.     if (formElement.value) {
  685.       var localfile = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
  686.  
  687.       localfile.initWithUnicodePath(formElement.value);
  688.       return localfile;
  689.     }
  690.     else {
  691.       return null;
  692.     }
  693.   }
  694.  
  695.   else if (type == "text") {
  696.     var val = formElement.getAttribute("value");
  697.     if (val) return val;
  698.     else return null;
  699.   }
  700.  
  701.   else {
  702.     return formElement.value;
  703.   }
  704.  }
  705.  catch (ex) {
  706.   dump("getFormElementValue failed, ex="+ex+"\n");
  707.  }
  708.  return null;
  709. }
  710.  
  711. //
  712. // sets the value of a widget
  713. //
  714. function setFormElementValue(formElement, value) {
  715.  
  716.   //formElement.value = formElement.defaultValue;
  717.   //  formElement.checked = formElement.defaultChecked;
  718.   var type = formElement.localName;
  719.   if (type == "checkbox") {
  720.     if (value == undefined) {
  721.       if (formElement.defaultChecked)
  722.         formElement.checked = formElement.defaultChecked;
  723.       else
  724.         formElement.checked = false;
  725.     } else {
  726.       if (formElement.getAttribute("reversed"))
  727.         formElement.checked = !value;
  728.       else
  729.         formElement.checked = value;
  730.     }
  731.   }
  732.  
  733.   else if (type == "radiogroup" || type =="menulist") {
  734.  
  735.     var selectedItem;
  736.     if (value == undefined) {
  737.       if (type == "radiogroup")
  738.         selectedItem = formElement.firstChild;
  739.       else
  740.         selectedItem = formElement.firstChild.firstChild;
  741.     }
  742.     else
  743.       selectedItem = formElement.getElementsByAttribute("value", value)[0];
  744.  
  745.     formElement.selectedItem = selectedItem;
  746.   }
  747.   // handle nsIFileSpec
  748.   else if (type == "textbox" &&
  749.            formElement.getAttribute("datatype") == "nsIFileSpec") {
  750.     if (value) {
  751.       var filespec = value.QueryInterface(Components.interfaces.nsIFileSpec);
  752.       try {
  753.         formElement.value = filespec.nativePath;
  754.       } catch (ex) {
  755.         dump("Still need to fix uninitialized filespec problem!\n");
  756.       }
  757.     } else {
  758.       if (formElement.defaultValue)
  759.         formElement.value = formElement.defaultValue;
  760.       else
  761.         formElement.value = "";
  762.     }
  763.   }
  764.  
  765.   else if (type == "textbox" &&
  766.            formElement.getAttribute("datatype") == "nsILocalFile") {
  767.     if (value) {
  768.       var localfile = value.QueryInterface(Components.interfaces.nsILocalFile);
  769.       try {
  770.         formElement.value = localfile.unicodePath;
  771.       } catch (ex) {
  772.         dump("Still need to fix uninitialized nsIFile problem!\n");
  773.       }
  774.  
  775.     } else {
  776.       if (formElement.defaultValue)
  777.         formElement.value = formElement.defaultValue;
  778.       else
  779.         formElement.value = "";
  780.     }
  781.   }
  782.  
  783.   else if (type == "text") {
  784.     if (value == null || value == undefined)
  785.       formElement.removeAttribute("value");
  786.     else
  787.       formElement.setAttribute("value",value);
  788.   }
  789.  
  790.   // let the form figure out what to do with it
  791.   else {
  792.     if (value == undefined) {
  793.       if (formElement.defaultValue)
  794.         formElement.value = formElement.defaultValue;
  795.     }
  796.     else
  797.       formElement.value = value;
  798.   }
  799. }
  800.  
  801. //
  802. // conversion routines - get data associated
  803. // with a given pageId, serverId, etc
  804. //
  805.  
  806. //
  807. // get the account associated with this serverId
  808. //
  809. function getAccountFromServerId(serverId) {
  810.   // get the account by dipping into RDF and then into the acount manager
  811.   var serverResource = RDF.GetResource(serverId);
  812.   try {
  813.     var serverFolder =
  814.       serverResource.QueryInterface(Components.interfaces.nsIMsgFolder);
  815.     var incomingServer = serverFolder.server;
  816.     var account = accountManager.FindAccountForServer(incomingServer);
  817.     return account;
  818.   } catch (ex) {
  819.   }
  820.   return null;
  821. }
  822.  
  823. //
  824. // get the array of form elements for the given page
  825. //
  826. function getPageFormElements() {
  827.  try {
  828.   var pageElements =
  829.       top.frames["contentFrame"].document.getElementsByAttribute("wsm_persist", "true");
  830.   return pageElements;
  831.  }
  832.  catch (ex) {
  833.   dump("getPageFormElements() failed: " + ex + "\n");
  834.  }
  835.  return null;
  836. }
  837.  
  838. //
  839. // get the value array for the given serverId
  840. //
  841. function getValueArrayFor(serverId) {
  842.   if (serverId == undefined) serverId="global";
  843.  
  844.   if (accountArray[serverId] == null) {
  845.     accountArray[serverId] = new Array;
  846.   }
  847.  
  848.   return accountArray[serverId];
  849. }
  850.  
  851. function clearAccountData(serverId, pageId)
  852. {
  853.   accountArray[serverId] = null;
  854. }
  855.  
  856. function getServerIdAndPageIdFromTree(tree)
  857. {
  858.   var serverId = null;
  859.  
  860.   if (tree.selectedItems.length < 1) return null;
  861.   var node = tree.selectedItems[0];
  862.  
  863.   // get the page to load
  864.   // (stored in the PageTag attribute of this node)
  865.   var pageId = node.getAttribute('PageTag');
  866.  
  867.   // get the server's Id
  868.   // (stored in the Id attribute of the server node)
  869.   var servernode = node.parentNode.parentNode;
  870.  
  871.   // for toplevel treeitems, we just use the current treeitem
  872.   //  dump("servernode is " + servernode + "\n");
  873.   if (servernode.localName != "treeitem") {
  874.     servernode = node;
  875.   }
  876.   serverId = servernode.getAttribute('id');
  877.  
  878.   return {"serverId": serverId, "pageId": pageId }
  879. }
  880.