home *** CD-ROM | disk | FTP | other *** search
/ GameStar 2005 October / Gamestar_77_2005-10_dvd.iso / Programy / nsb-install-8-0.exe / chrome / messenger.jar / content / messenger / addressbook / addressbook.js < prev    next >
Text File  |  2005-07-29  |  26KB  |  809 lines

  1. /* ***** BEGIN LICENSE BLOCK *****
  2.  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  3.  *
  4.  * The contents of this file are subject to the Mozilla Public License Version
  5.  * 1.1 (the "License"); you may not use this file except in compliance with
  6.  * the License. You may obtain a copy of the License at
  7.  * http://www.mozilla.org/MPL/
  8.  *
  9.  * Software distributed under the License is distributed on an "AS IS" basis,
  10.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  11.  * for the specific language governing rights and limitations under the
  12.  * License.
  13.  *
  14.  * The Original Code is Mozilla Addressbook.
  15.  *
  16.  * The Initial Developer of the Original Code is
  17.  * Netscape Communications Corp.
  18.  * Portions created by the Initial Developer are Copyright (C) 1999-2001
  19.  * the Initial Developer. All Rights Reserved.
  20.  *
  21.  * Original Author:
  22.  *   Paul Hangas <hangas@netscape.com>
  23.  *
  24.  * Contributor(s):
  25.  *   Seth Spitzer <sspitzer@netscape.com>
  26.  *
  27.  * Alternatively, the contents of this file may be used under the terms of
  28.  * either the GNU General Public License Version 2 or later (the "GPL"), or
  29.  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  30.  * in which case the provisions of the GPL or the LGPL are applicable instead
  31.  * of those above. If you wish to allow use of your version of this file only
  32.  * under the terms of either the GPL or the LGPL, and not to allow others to
  33.  * use your version of this file under the terms of the MPL, indicate your
  34.  * decision by deleting the provisions above and replace them with the notice
  35.  * and other provisions required by the GPL or the LGPL. If you do not delete
  36.  * the provisions above, a recipient may use your version of this file under
  37.  * the terms of any one of the MPL, the GPL or the LGPL.
  38.  *
  39.  * ***** END LICENSE BLOCK ***** */
  40.  
  41. var cvPrefs = 0;
  42. var addressbook = 0;
  43. var gAddressBookBundle;
  44. var gSearchTimer = null;
  45. var gStatusText = null;
  46. var gQueryURIFormat = null;
  47. var gSearchInput;
  48. var gPrintSettings = null;
  49. var gDirTree;
  50. var gSearchBox;
  51. var gCardViewBox;
  52. var gCardViewBoxEmail1;
  53.  
  54. // Constants that correspond to choices
  55. // in Address Book->View -->Show Name as
  56. const kDisplayName = 0;
  57. const kLastNameFirst = 1;
  58. const kFirstNameFirst = 2;
  59. const kLDAPDirectory = 0; // defined in nsDirPrefs.h
  60. const kPABDirectory  = 2; // defined in nsDirPrefs.h
  61.  
  62. var gAddressBookAbListener = {
  63.   onItemAdded: function(parentDir, item) {
  64.     // will not be called
  65.   },
  66.   onItemRemoved: function(parentDir, item) {
  67.     // will only be called when an addressbook is deleted
  68.     try {
  69.       var directory = item.QueryInterface(Components.interfaces.nsIAbDirectory);
  70.       // check if the item being removed is the directory
  71.       // that we are showing in the addressbook
  72.       // if so, select the personal addressbook (it can't be removed)
  73.       if (directory && directory == GetAbView().directory) {
  74.         SelectFirstAddressBook();
  75.       }
  76.     }
  77.     catch (ex) {
  78.     }
  79.   },
  80.   onItemPropertyChanged: function(item, property, oldValue, newValue) {
  81.     // will not be called
  82.   }
  83. };
  84.  
  85. function OnUnloadAddressBook()
  86. {  
  87.   var addrbookSession = Components.classes["@mozilla.org/addressbook/services/session;1"].getService().QueryInterface(Components.interfaces.nsIAddrBookSession);
  88.   addrbookSession.removeAddressBookListener(gAddressBookAbListener);
  89.  
  90.   RemovePrefObservers();
  91.   CloseAbView();
  92. }
  93.  
  94. var gAddressBookAbViewListener = {
  95.   onSelectionChanged: function() {
  96.     ResultsPaneSelectionChanged();
  97.   },
  98.   onCountChanged: function(total) {
  99.     SetStatusText(total);
  100.   }
  101. };
  102.  
  103. function GetAbViewListener()
  104. {
  105.   return gAddressBookAbViewListener;
  106. }
  107.  
  108. const kPrefMailAddrBookLastNameFirst = "mail.addr_book.lastnamefirst";
  109.  
  110. var gMailAddrBookLastNameFirstObserver = {
  111.   observe: function(subject, topic, value) {
  112.     if (topic == "nsPref:changed" && value == kPrefMailAddrBookLastNameFirst) {
  113.       UpdateCardView();
  114.     }
  115.   }
  116. }
  117.  
  118. function AddPrefObservers()
  119. {
  120.   var prefService = Components.classes["@mozilla.org/preferences-service;1"]
  121.                               .getService(Components.interfaces.nsIPrefService);
  122.   var prefBranch = prefService.getBranch(null).QueryInterface(Components.interfaces.nsIPrefBranchInternal);
  123.   prefBranch.addObserver(kPrefMailAddrBookLastNameFirst, gMailAddrBookLastNameFirstObserver, false);
  124. }
  125.  
  126. function RemovePrefObservers()
  127. {
  128.   var prefService = Components.classes["@mozilla.org/preferences-service;1"]
  129.                               .getService(Components.interfaces.nsIPrefService);
  130.   var prefBranch = prefService.getBranch(null).QueryInterface(Components.interfaces.nsIPrefBranchInternal);
  131.   prefBranch.removeObserver(kPrefMailAddrBookLastNameFirst, gMailAddrBookLastNameFirstObserver);
  132. }
  133.  
  134. function OnLoadAddressBook()
  135. {
  136.   gAddressBookBundle = document.getElementById("bundle_addressBook");
  137.   gSearchInput = document.getElementById("searchInput");
  138.  
  139.   verifyAccounts(null);     // this will do migration, if we need to.
  140.  
  141.   top.addressbook = Components.classes["@mozilla.org/addressbook;1"].createInstance(Components.interfaces.nsIAddressBook);
  142.  
  143.   InitCommonJS();
  144.  
  145.   UpgradeAddressBookResultsPaneUI("mailnews.ui.addressbook_results.version");
  146.  
  147.   //This migrates the LDAPServer Preferences from 4.x to mozilla format.
  148.   try {
  149.       gLDAPPrefsService = Components.classes["@mozilla.org/ldapprefs-service;1"].getService();       
  150.       gLDAPPrefsService = gLDAPPrefsService.QueryInterface( Components.interfaces.nsILDAPPrefsService);                  
  151.   } catch (ex) {dump ("ERROR: Cannot get the LDAP service\n" + ex + "\n");}
  152.  
  153.   GetCurrentPrefs();
  154.  
  155.   AddPrefObservers();
  156.  
  157.   // FIX ME - later we will be able to use onload from the overlay
  158.   OnLoadCardView();
  159.  
  160.   SetupAbCommandUpdateHandlers();
  161.  
  162.   //workaround - add setTimeout to make sure dynamic overlays get loaded first
  163.   setTimeout('OnLoadDirTree()', 0);
  164.  
  165.   // if the pref is locked disable the menuitem New->LDAP directory
  166.   if (gPrefs.prefIsLocked("ldap_2.disable_button_add"))
  167.     document.getElementById("addLDAP").setAttribute("disabled", "true");
  168.  
  169.   // add a listener, so we can switch directories if
  170.   // the current directory is deleted
  171.   var addrbookSession = Components.classes["@mozilla.org/addressbook/services/session;1"].getService().QueryInterface(Components.interfaces.nsIAddrBookSession);
  172.   // this listener only cares when a directory is removed
  173.   addrbookSession.addAddressBookListener(gAddressBookAbListener, Components.interfaces.nsIAbListener.directoryRemoved);
  174.  
  175.   var dirTree = GetDirTree();
  176.   dirTree.addEventListener("click",DirPaneClick,true);
  177. }
  178.  
  179. function OnLoadDirTree() {
  180.   var treeBuilder = dirTree.builder.QueryInterface(Components.interfaces.nsIXULTreeBuilder);
  181.   treeBuilder.addObserver(abDirTreeObserver);
  182.  
  183.   SelectFirstAddressBook();
  184. }
  185.  
  186. function GetCurrentPrefs()
  187. {
  188.     // prefs
  189.     if ( cvPrefs == 0 )
  190.         cvPrefs = new Object;
  191.  
  192.     cvPrefs.prefs = gPrefs;
  193.     
  194.     // check "Show Name As" menu item based on pref
  195.     var menuitemID;
  196.     switch (gPrefs.getIntPref("mail.addr_book.lastnamefirst"))
  197.     {
  198.         case kFirstNameFirst:
  199.             menuitemID = 'firstLastCmd';
  200.             break;
  201.         case kLastNameFirst:
  202.             menuitemID = 'lastFirstCmd';
  203.             break;
  204.         case kDisplayName:
  205.         default:
  206.             menuitemID = 'displayNameCmd';
  207.             break;
  208.     }
  209.  
  210.     var menuitem = top.document.getElementById(menuitemID);
  211.     if ( menuitem )
  212.         menuitem.setAttribute('checked', 'true');
  213.  
  214.   // initialize phonetic 
  215.   var showPhoneticFields =
  216.         gPrefs.getComplexValue("mail.addr_book.show_phonetic_fields", 
  217.                                Components.interfaces.nsIPrefLocalizedString).data;
  218.   // show phonetic fields if indicated by the pref
  219.   if (showPhoneticFields == "true")
  220.     document.getElementById("cmd_SortBy_PhoneticName")
  221.             .setAttribute("hidden", "false");
  222.  
  223. }
  224.  
  225.  
  226. function SetNameColumn(cmd)
  227. {
  228.     var prefValue;
  229.     
  230.     switch ( cmd )
  231.     {
  232.         case 'firstLastCmd':
  233.             prefValue = kFirstNameFirst;
  234.             break;
  235.         case 'lastFirstCmd':
  236.             prefValue = kLastNameFirst;
  237.             break;
  238.         case 'displayNameCmd':
  239.             prefValue = kDisplayName;
  240.             break;
  241.     }
  242.     
  243.     cvPrefs.prefs.setIntPref("mail.addr_book.lastnamefirst", prefValue);
  244. }
  245.  
  246. function CommandUpdate_AddressBook()
  247. {
  248.   goUpdateCommand('cmd_delete');
  249.   goUpdateCommand('button_delete');
  250. }
  251.  
  252. function ResultsPaneSelectionChanged()
  253. {
  254.   UpdateCardView();
  255. }
  256.  
  257. function UpdateCardView()
  258. {
  259.   var cards = GetSelectedAbCards();
  260.  
  261.   // display the selected card, if exactly one card is selected.
  262.   // either no cards, or more than one card is selected, clear the pane.
  263.   if (cards.length == 1)
  264.     OnClickedCard(cards[0])
  265.   else 
  266.     ClearCardViewPane();
  267. }
  268.  
  269. function OnClickedCard(card)
  270.   if (card) 
  271.     DisplayCardViewPane(card);
  272.   else
  273.     ClearCardViewPane();
  274. }
  275.  
  276. function AbClose()
  277. {
  278.   top.close();
  279. }
  280.  
  281. function AbNewLDAPDirectory()
  282. {
  283.   window.openDialog("chrome://messenger/content/addressbook/pref-directory-add.xul", 
  284.                     "", 
  285.                     "chrome,modal=yes,resizable=no,centerscreen", 
  286.                     null);
  287. }
  288.  
  289. function AbNewAddressBook()
  290. {
  291.   var strBundleService = Components.classes["@mozilla.org/intl/stringbundle;1"].
  292.       getService(Components.interfaces.nsIStringBundleService);
  293.   var bundle = strBundleService.createBundle("chrome://messenger/locale/addressbook/addressBook.properties");
  294.   var dialogTitle = bundle.GetStringFromName('newAddressBookTitle');
  295.  
  296.   var dialog = window.openDialog(
  297.     "chrome://messenger/content/addressbook/abAddressBookNameDialog.xul", 
  298.      "", "chrome,modal=yes,resizable=no,centerscreen", {title: dialogTitle, okCallback:AbOnCreateNewAddressBook});
  299. }
  300.  
  301. function AbRenameAddressBook()
  302. {
  303.   var selectedABURI = GetSelectedDirectory();
  304.  
  305.   // the rdf service
  306.   var RDF = Components.classes["@mozilla.org/rdf/rdf-service;1"].getService(Components.interfaces.nsIRDFService);
  307.  
  308.   // the RDF resource URI for LDAPDirectory will be like: "moz-abmdbdirectory://abook-3.mab"
  309.   var selectedABDirectory = RDF.GetResource(selectedABURI).QueryInterface(Components.interfaces.nsIAbDirectory);
  310.  
  311.   var strBundleService = Components.classes["@mozilla.org/intl/stringbundle;1"].
  312.       getService(Components.interfaces.nsIStringBundleService);
  313.   var bundle = strBundleService.createBundle("chrome://messenger/locale/addressbook/addressBook.properties");
  314.   var dialogTitle = bundle.GetStringFromName('renameAddressBookTitle');
  315.  
  316.   // you can't rename the PAB or the CAB
  317.   var canRename = (selectedABURI != kCollectedAddressbookURI && selectedABURI != kPersonalAddressbookURI);
  318.  
  319.   var dialog = window.openDialog(
  320.     "chrome://messenger/content/addressbook/abAddressBookNameDialog.xul", 
  321.      "", "chrome,modal=yes,resizable=no,centerscreen", {title: dialogTitle, canRename: canRename, name: selectedABDirectory.directoryProperties.description,
  322.       okCallback:AbOnRenameAddressBook});
  323. }
  324.  
  325. function AbOnCreateNewAddressBook(aName)
  326. {
  327.   var properties = Components.classes["@mozilla.org/addressbook/properties;1"].createInstance(Components.interfaces.nsIAbDirectoryProperties);
  328.   properties.description = aName;
  329.   properties.dirType = kPABDirectory;
  330.   top.addressbook.newAddressBook(properties);
  331. }
  332.  
  333. function AbOnRenameAddressBook(aName)
  334. {
  335.   // When the UI code for renaming addrbooks (bug #17230) is ready, just 
  336.   // change 'properties.description' setting below and it should just work.
  337.   // get select ab
  338.   var selectedABURI = GetSelectedDirectory();
  339.   //dump("In AbRenameAddressBook() selectedABURI=" + selectedABURI + "\n");
  340.  
  341.   // the rdf service
  342.   var RDF = Components.classes["@mozilla.org/rdf/rdf-service;1"].getService(Components.interfaces.nsIRDFService);
  343.   // get the datasource for the addressdirectory
  344.   var addressbookDS = RDF.GetDataSource("rdf:addressdirectory");
  345.  
  346.   // moz-abdirectory:// is the RDF root to get all types of addressbooks.
  347.   var parentDir = RDF.GetResource("moz-abdirectory://").QueryInterface(Components.interfaces.nsIAbDirectory);
  348.  
  349.   // the RDF resource URI for LDAPDirectory will be like: "moz-abmdbdirectory://abook-3.mab"
  350.   var selectedABDirectory = RDF.GetResource(selectedABURI).QueryInterface(Components.interfaces.nsIAbDirectory);
  351.  
  352.   // Copy existing dir type category id and mod time so they won't get reset.
  353.   var oldProperties = selectedABDirectory.directoryProperties;
  354.  
  355.   // Create and fill in properties info
  356.   var properties = Components.classes["@mozilla.org/addressbook/properties;1"].createInstance(Components.interfaces.nsIAbDirectoryProperties);
  357.   properties.URI = selectedABURI;
  358.   properties.dirType = oldProperties.dirType;
  359.   properties.categoryId = oldProperties.categoryId;
  360.   properties.syncTimeStamp = oldProperties.syncTimeStamp;
  361.   properties.description = aName;
  362.  
  363.   // Now do the modification.
  364.   addressbook.modifyAddressBook(addressbookDS, parentDir, selectedABDirectory, properties);
  365. }
  366.  
  367. function GetPrintSettings()
  368. {
  369.   var prevPS = gPrintSettings;
  370.  
  371.   try {
  372.     if (gPrintSettings == null) {
  373.       var useGlobalPrintSettings = true;
  374.       var pref = Components.classes["@mozilla.org/preferences-service;1"]
  375.                            .getService(Components.interfaces.nsIPrefBranch);
  376.       if (pref) {
  377.         useGlobalPrintSettings = pref.getBoolPref("print.use_global_printsettings", false);
  378.       }
  379.  
  380.       // I would rather be using nsIWebBrowserPrint API
  381.       // but I really don't have a document at this point
  382.       var printSettingsService = Components.classes["@mozilla.org/gfx/printsettings-service;1"]
  383.                                            .getService(Components.interfaces.nsIPrintSettingsService);
  384.       if (useGlobalPrintSettings) {
  385.         gPrintSettings = printSettingsService.globalPrintSettings;
  386.       } else {
  387.         gPrintSettings = printSettingsService.CreatePrintSettings();
  388.       }
  389.     }
  390.   } catch (e) {
  391.     dump("GetPrintSettings "+e);
  392.   }
  393.  
  394.   return gPrintSettings;
  395. }
  396.  
  397. function AbPrintCardInternal(doPrintPreview, msgType)
  398. {
  399.   var selectedItems = GetSelectedAbCards();
  400.   var numSelected = selectedItems.length;
  401.  
  402.   if (!numSelected)
  403.     return;
  404.  
  405.   var addressbook = Components.classes["@mozilla.org/addressbook;1"].createInstance(Components.interfaces.nsIAddressBook);
  406.   var uri = GetSelectedDirectory();
  407.   if (!uri)
  408.     return;
  409.  
  410.    var statusFeedback;
  411.    statusFeedback = Components.classes["@mozilla.org/messenger/statusfeedback;1"].createInstance();
  412.    statusFeedback = statusFeedback.QueryInterface(Components.interfaces.nsIMsgStatusFeedback);
  413.  
  414.    var selectionArray = new Array(numSelected);
  415.  
  416.    var totalCard = 0;
  417.  
  418.    for (var i = 0; i < numSelected; i++)
  419.    {
  420.      var card = selectedItems[i];
  421.      var printCardUrl = CreatePrintCardUrl(card);
  422.      if (printCardUrl)
  423.      {
  424.         selectionArray[totalCard++] = printCardUrl;
  425.      }
  426.   }
  427.  
  428.   if (!gPrintSettings)
  429.   {
  430.     gPrintSettings = GetPrintSettings();
  431.   }
  432.  
  433.   printEngineWindow = window.openDialog("chrome://messenger/content/msgPrintEngine.xul",
  434.                                          "",
  435.                                          "chrome,dialog=no,all",
  436.                                           totalCard, selectionArray, statusFeedback, 
  437.                                           gPrintSettings, doPrintPreview, msgType);
  438.  
  439.   return;
  440. }
  441.  
  442. function AbPrintCard()
  443. {
  444.   AbPrintCardInternal(false, Components.interfaces.nsIMsgPrintEngine.MNAB_PRINT_AB_CARD);
  445. }
  446.  
  447. function AbPrintPreviewCard()
  448. {
  449.   AbPrintCardInternal(true, Components.interfaces.nsIMsgPrintEngine.MNAB_PRINTPREVIEW_AB_CARD);
  450. }
  451.  
  452. function CreatePrintCardUrl(card)
  453. {
  454.   var url = "data:text/xml;base64," + card.convertToBase64EncodedXML();
  455.   return url;
  456. }
  457.  
  458. function AbPrintAddressBookInternal(doPrintPreview, msgType)
  459. {
  460.   var addressbook = Components.classes["@mozilla.org/addressbook;1"].createInstance(Components.interfaces.nsIAddressBook);
  461.   var uri = GetSelectedDirectory();
  462.   if (!uri)
  463.     return;
  464.  
  465.   var statusFeedback;
  466.     statusFeedback = Components.classes["@mozilla.org/messenger/statusfeedback;1"].createInstance();
  467.     statusFeedback = statusFeedback.QueryInterface(Components.interfaces.nsIMsgStatusFeedback);
  468.  
  469.   /*
  470.     turn "moz-abmdbdirectory://abook.mab" into
  471.     "addbook://moz-abmdbdirectory/abook.mab?action=print"
  472.    */
  473.  
  474.   var abURIArr = uri.split("://");
  475.   var printUrl = "addbook://" + abURIArr[0] + "/" + abURIArr[1] + "?action=print"
  476.  
  477.   if (!gPrintSettings) {
  478.     gPrintSettings = GetPrintSettings();
  479.   }
  480.  
  481.     printEngineWindow = window.openDialog("chrome://messenger/content/msgPrintEngine.xul",
  482.                                         "",
  483.                                         "chrome,dialog=no,all",
  484.                                         1, [printUrl], statusFeedback, gPrintSettings, doPrintPreview, msgType);
  485.  
  486.     return;
  487. }
  488.  
  489. function AbPrintAddressBook()
  490. {
  491.   AbPrintAddressBookInternal(false, Components.interfaces.nsIMsgPrintEngine.MNAB_PRINT_ADDRBOOK);
  492. }
  493.  
  494. function AbPrintPreviewAddressBook()
  495. {
  496.   AbPrintAddressBookInternal(true, Components.interfaces.nsIMsgPrintEngine.MNAB_PRINTPREVIEW_ADDRBOOK);
  497. }
  498.  
  499. function AbExport()
  500. {
  501.   try {
  502.     var selectedABURI = GetSelectedDirectory();
  503.     if (!selectedABURI) return;
  504.     
  505.     var directory = GetDirectoryFromURI(selectedABURI);
  506.     addressbook.exportAddressBook(directory);
  507.   }
  508.   catch (ex) {
  509.     var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService(Components.interfaces.nsIPromptService);
  510.  
  511.     if (promptService) {
  512.       var message;
  513.       switch (ex.result) {
  514.         case Components.results.NS_ERROR_FILE_ACCESS_DENIED:
  515.           message = gAddressBookBundle.getString("failedToExportMessageFileAccessDenied");
  516.           break;
  517.         case Components.results.NS_ERROR_FILE_NO_DEVICE_SPACE:
  518.           message = gAddressBookBundle.getString("failedToExportMessageNoDeviceSpace");
  519.           break;
  520.         default:
  521.           message = ex.message;
  522.           break;
  523.       }
  524.  
  525.       promptService.alert(window,
  526.         gAddressBookBundle.getString("failedToExportTitle"), 
  527.         message);
  528.     }
  529.   }
  530. }
  531.  
  532. function AbDeleteDirectory()
  533. {
  534.   var selectedABURI = GetSelectedDirectory();
  535.   if (!selectedABURI)
  536.     return;
  537.  
  538.   var parentArray = Components.classes["@mozilla.org/supports-array;1"].createInstance(Components.interfaces.nsISupportsArray);
  539.   if (!parentArray) 
  540.     return; 
  541.  
  542.   var promptService = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService(Components.interfaces.nsIPromptService);
  543.  
  544.   var parentRow = GetParentRow(dirTree, dirTree.currentIndex);
  545.   var parentId = (parentRow == -1) ? "moz-abdirectory://" : dirTree.builderView.getResourceAtIndex(parentRow).Value;
  546.   var parentDir = GetDirectoryFromURI(parentId);
  547.   parentArray.AppendElement(parentDir);
  548.     
  549.   var directory = GetDirectoryFromURI(selectedABURI);
  550.   var confirmDeleteMessage = gAddressBookBundle.getString(directory.isMailList ? "confirmDeleteMailingList" : "confirmDeleteAddressbook");
  551.  
  552.   if (!promptService.confirm(window, null, confirmDeleteMessage))
  553.     return;
  554.  
  555.   var resourceArray = Components.classes["@mozilla.org/supports-array;1"].createInstance(Components.interfaces.nsISupportsArray);
  556.   var selectedABResource = GetDirectoryFromURI(selectedABURI).QueryInterface(Components.interfaces.nsIRDFResource);
  557.  
  558.   resourceArray.AppendElement(selectedABResource);
  559.  
  560.   top.addressbook.deleteAddressBooks(dirTree.database, parentArray, resourceArray);
  561.   SelectFirstAddressBook();
  562. }
  563.  
  564. function SetStatusText(total)
  565. {
  566.   if (!gStatusText)
  567.     gStatusText = document.getElementById('statusText');
  568.  
  569.   try {
  570.     var statusText;
  571.  
  572.     if (gSearchInput.value) {
  573.       if (total == 0)
  574.         statusText = gAddressBookBundle.getString("noMatchFound");
  575.       else
  576.       {
  577.         if (total == 1)
  578.           statusText = gAddressBookBundle.getString("matchFound");
  579.         else  
  580.           statusText = gAddressBookBundle.getFormattedString("matchesFound", [total]);
  581.       }
  582.     } 
  583.     else
  584.       statusText = gAddressBookBundle.getFormattedString("totalCardStatus", [gAbView.directory.dirName, total]);   
  585.  
  586.     gStatusText.setAttribute("label", statusText);
  587.   }
  588.   catch(ex) {
  589.     dump("failed to set status text:  " + ex + "\n");
  590.   }
  591. }
  592.  
  593. function AbResultsPaneDoubleClick(card)
  594. {
  595.   AbEditCard(card);
  596. }
  597.  
  598. function onAdvancedAbSearch()
  599. {
  600.   var selectedABURI = GetSelectedDirectory();
  601.   if (!selectedABURI) return;
  602.  
  603.   window.openDialog("chrome://messenger/content/ABSearchDialog.xul", "", 
  604.                     "chrome,resizable,status,centerscreen,dialog=no", {directory: selectedABURI} );
  605. }
  606.  
  607. function onEnterInSearchBar()
  608. {
  609.   ClearCardViewPane();  
  610.  
  611.   if (!gQueryURIFormat)
  612.     gQueryURIFormat = gPrefs.getComplexValue("mail.addr_book.quicksearchquery.format", 
  613.                                               Components.interfaces.nsIPrefLocalizedString).data;
  614.  
  615.   var searchURI = GetSelectedDirectory();
  616.   if (!searchURI) return;
  617.  
  618.   var sortColumn = gAbView.sortColumn;
  619.   var sortDirection = gAbView.sortDirection;
  620.  
  621.   /*
  622.    XXX todo, handle the case where the LDAP url
  623.    already has a query, like 
  624.    moz-abldapdirectory://nsdirectory.netscape.com:389/ou=People,dc=netscape,dc=com?(or(Department,=,Applications))
  625.   */
  626.   if (gSearchInput.value != "") {
  627.     // replace all instances of @V with the escaped version
  628.     // of what the user typed in the quick search text input
  629.     searchURI += gQueryURIFormat.replace(/@V/g, encodeURIComponent(gSearchInput.value));
  630.   }
  631.  
  632.   SetAbView(searchURI, gSearchInput.value != "", sortColumn, sortDirection);
  633.   
  634.   // XXX todo 
  635.   // this works for synchronous searches of local addressbooks, 
  636.   // but not for LDAP searches
  637.   SelectFirstCard();
  638. }
  639.  
  640. function SwitchPaneFocus(event)
  641. {
  642.   var focusedElement    = WhichPaneHasFocus();
  643.   var cardViewBox       = GetCardViewBox();
  644.   var cardViewBoxEmail1 = GetCardViewBoxEmail1();
  645.   var searchBox         = GetSearchBox();
  646.   var dirTree           = GetDirTree();
  647.   var searchInput       = GetSearchInput();
  648.  
  649.   if (event && event.shiftKey)
  650.   {
  651.     if (focusedElement == gAbResultsTree && searchBox.getAttribute('hidden') != 'true')
  652.       searchInput.focus();
  653.     else if ((focusedElement == gAbResultsTree || focusedElement == searchBox) && !IsDirPaneCollapsed())
  654.       dirTree.focus();
  655.     else if (focusedElement != cardViewBox && !IsCardViewAndAbResultsPaneSplitterCollapsed())
  656.     {
  657.       if(cardViewBoxEmail1)
  658.         cardViewBoxEmail1.focus();
  659.       else
  660.         cardViewBox.focus();    
  661.     }
  662.     else 
  663.       gAbResultsTree.focus();
  664.   }
  665.   else
  666.   {
  667.     if (focusedElement == searchBox)
  668.       gAbResultsTree.focus();
  669.     else if (focusedElement == gAbResultsTree && !IsCardViewAndAbResultsPaneSplitterCollapsed())
  670.     {
  671.       if(cardViewBoxEmail1)
  672.         cardViewBoxEmail1.focus();
  673.       else
  674.         cardViewBox.focus();    
  675.     }
  676.     else if (focusedElement != dirTree && !IsDirPaneCollapsed())
  677.       dirTree.focus();
  678.     else if (searchBox.getAttribute('hidden') != 'true')
  679.       searchInput.focus();
  680.     else
  681.       gAbResultsTree.focus();
  682.   }
  683. }
  684.  
  685. function WhichPaneHasFocus()
  686. {
  687.   var cardViewBox       = GetCardViewBox();
  688.   var searchBox         = GetSearchBox();
  689.   var dirTree           = GetDirTree();
  690.     
  691.   var currentNode = top.document.commandDispatcher.focusedElement;
  692.   while (currentNode)
  693.   {
  694.     var nodeId = currentNode.getAttribute('id');
  695.  
  696.     if(currentNode == gAbResultsTree ||
  697.        currentNode == cardViewBox ||
  698.        currentNode == searchBox ||
  699.        currentNode == dirTree)
  700.       return currentNode;
  701.  
  702.     currentNode = currentNode.parentNode;
  703.   }
  704.  
  705.   return null;
  706. }
  707.  
  708. function GetDirTree()
  709. {
  710.   if (!gDirTree)
  711.     gDirTree = document.getElementById('dirTree');
  712.   return gDirTree;
  713. }
  714.  
  715. function GetSearchInput()
  716. {
  717.   if (!gSearchInput)
  718.     gSearchInput = document.getElementById('searchInput');
  719.   return gSearchInput;
  720. }
  721.  
  722. function GetSearchBox()
  723. {
  724.   if (!gSearchBox)
  725.     gSearchBox = document.getElementById('searchBox');
  726.   return gSearchBox;
  727. }
  728.  
  729. function GetCardViewBox()
  730. {
  731.   if (!gCardViewBox)
  732.     gCardViewBox = document.getElementById('CardViewBox');
  733.   return gCardViewBox;
  734. }
  735.  
  736. function GetCardViewBoxEmail1()
  737. {
  738.   if (!gCardViewBoxEmail1)
  739.   {
  740.     try {
  741.       gCardViewBoxEmail1 = document.getElementById('cvEmail1');
  742.     }
  743.     catch (ex) {
  744.       gCardViewBoxEmail1 = null;
  745.     }
  746.   }
  747.   return gCardViewBoxEmail1;
  748. }
  749.  
  750. function IsDirPaneCollapsed()
  751. {
  752.   var dirPaneBox = GetDirTree().parentNode;
  753.   return dirPaneBox.getAttribute("collapsed") == "true" ||
  754.          dirPaneBox.getAttribute("hidden") == "true";
  755. }
  756.  
  757. function IsCardViewAndAbResultsPaneSplitterCollapsed()
  758. {
  759.   var cardViewBox = document.getElementById('CardViewOuterBox');
  760.   try {
  761.     return (cardViewBox.getAttribute("collapsed") == "true");
  762.   }
  763.   catch (ex) {
  764.     return false;
  765.   }
  766. }
  767.  
  768. function LaunchUrl(url)
  769. {
  770.   var messenger = Components.classes["@mozilla.org/messenger;1"].createInstance(Components.interfaces.nsIMessenger);
  771.   messenger.SetWindow(window, null);
  772.   messenger.OpenURL(url);
  773. }
  774.  
  775. function AbIMSelected()
  776. {
  777.   var cards = GetSelectedAbCards();
  778.   var count = cards.length;
  779.  
  780.   var screennames;
  781.   var screennameCount = 0;
  782.  
  783.   for (var i=0;i<count;i++) {
  784.     var screenname = cards[i].aimScreenName;
  785.     if (screenname) {
  786.       if (screennameCount == 0)
  787.         screennames = screenname;
  788.       else
  789.         screennames += "," + screenname;
  790.  
  791.       screennameCount++
  792.     }
  793.   }
  794.  
  795.   var url = "aim:";
  796.  
  797.   if (screennameCount == 0)
  798.     url += "goim";
  799.   else if (screennameCount == 1)
  800.     url += "goim?screenname=" + screennames;
  801.   else {
  802.     url += "SendChatInvite?listofscreennames=" + screennames;
  803.     url += "&message=" + gAddressBookBundle.getString("joinMeInThisChat");
  804.   }
  805.  
  806.   LaunchUrl(url);
  807. }
  808.