summaryrefslogtreecommitdiffstats
path: root/comm/suite/mailnews/components/addrbook/content/addressbook.js
diff options
context:
space:
mode:
Diffstat (limited to 'comm/suite/mailnews/components/addrbook/content/addressbook.js')
-rw-r--r--comm/suite/mailnews/components/addrbook/content/addressbook.js581
1 files changed, 581 insertions, 0 deletions
diff --git a/comm/suite/mailnews/components/addrbook/content/addressbook.js b/comm/suite/mailnews/components/addrbook/content/addressbook.js
new file mode 100644
index 0000000000..e1bce6a868
--- /dev/null
+++ b/comm/suite/mailnews/components/addrbook/content/addressbook.js
@@ -0,0 +1,581 @@
+/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
+/* 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/. */
+
+const {encodeABTermValue, getModelQuery} = ChromeUtils.import("resource:///modules/ABQueryUtils.jsm");
+const {MailServices} = ChromeUtils.import("resource:///modules/MailServices.jsm");
+const {PluralForm} = ChromeUtils.import("resource://gre/modules/PluralForm.jsm");
+var {Services} = ChromeUtils.import("resource://gre/modules/Services.jsm");
+
+const nsIAbListener = Ci.nsIAbListener;
+const kPrefMailAddrBookLastNameFirst = "mail.addr_book.lastnamefirst";
+const kPersistCollapseMapStorage = "directoryTree.json";
+
+var gSearchTimer = null;
+var gStatusText = null;
+var gQueryURIFormat = null;
+var gSearchInput;
+var gSearchBox;
+var gCardViewBox;
+var gCardViewBoxEmail1;
+
+var msgWindow = Cc["@mozilla.org/messenger/msgwindow;1"]
+ .createInstance(Ci.nsIMsgWindow);
+
+// Constants that correspond to choices
+// in Address Book->View -->Show Name as
+const kDisplayName = 0;
+const kLastNameFirst = 1;
+const kFirstNameFirst = 2;
+const kLDAPDirectory = 0; // defined in nsDirPrefs.h
+const kPABDirectory = 2; // defined in nsDirPrefs.h
+
+function OnUnloadAddressBook()
+{
+ MailServices.ab.removeAddressBookListener(gDirectoryTreeView);
+
+ // Shutdown the tree view - this will also save the open/collapsed
+ // state of the tree view to a JSON file.
+ gDirectoryTreeView.shutdown(kPersistCollapseMapStorage);
+
+ MailServices.mailSession.RemoveMsgWindow(msgWindow);
+
+ CloseAbView();
+}
+
+var gAddressBookAbViewListener = {
+ onSelectionChanged: function() {
+ ResultsPaneSelectionChanged();
+ },
+ onCountChanged: function(total) {
+ SetStatusText(total);
+ }
+};
+
+function GetAbViewListener()
+{
+ return gAddressBookAbViewListener;
+}
+
+function OnLoadAddressBook()
+{
+ gSearchInput = document.getElementById("searchInput");
+
+ verifyAccounts(null, false); // this will do migration, if we need to.
+
+ InitCommonJS();
+
+ UpgradeAddressBookResultsPaneUI("mailnews.ui.addressbook_results.version");
+
+ GetCurrentPrefs();
+
+ // FIX ME - later we will be able to use onload from the overlay
+ OnLoadCardView();
+
+ // Before and after callbacks for the customizeToolbar code
+ var abToolbox = getAbToolbox();
+ abToolbox.customizeInit = AbToolboxCustomizeInit;
+ abToolbox.customizeDone = AbToolboxCustomizeDone;
+ abToolbox.customizeChange = AbToolboxCustomizeChange;
+
+ // Initialize the Address Book tree view
+ gDirectoryTreeView.init(gDirTree, kPersistCollapseMapStorage);
+
+ SelectFirstAddressBook();
+
+ // if the pref is locked disable the menuitem New->LDAP directory
+ if (Services.prefs.prefIsLocked("ldap_2.disable_button_add"))
+ document.getElementById("addLDAP").setAttribute("disabled", "true");
+
+ // Add a listener, so we can switch directories if the current directory is
+ // deleted. This listener cares when a directory (= address book), or a
+ // directory item is/are removed. In the case of directory items, we are
+ // only really interested in mailing list changes and not cards but we have
+ // to have both.
+ MailServices.ab.addAddressBookListener(gDirectoryTreeView, nsIAbListener.all);
+
+ gDirTree.controllers.appendController(DirPaneController);
+
+ // Ensure we don't load xul error pages into the main window
+ window.QueryInterface(Ci.nsIInterfaceRequestor)
+ .getInterface(Ci.nsIWebNavigation)
+ .QueryInterface(Ci.nsIDocShell)
+ .useErrorPages = false;
+
+ MailServices.mailSession.AddMsgWindow(msgWindow);
+}
+
+function GetCurrentPrefs()
+{
+ // check "Show Name As" menu item based on pref
+ var menuitemID;
+ switch (Services.prefs.getIntPref(kPrefMailAddrBookLastNameFirst))
+ {
+ case kFirstNameFirst:
+ menuitemID = 'firstLastCmd';
+ break;
+ case kLastNameFirst:
+ menuitemID = 'lastFirstCmd';
+ break;
+ case kDisplayName:
+ default:
+ menuitemID = 'displayNameCmd';
+ break;
+ }
+
+ var menuitem = top.document.getElementById(menuitemID);
+ if ( menuitem )
+ menuitem.setAttribute('checked', 'true');
+
+ // show phonetic fields if indicated by the pref
+ if (GetLocalizedStringPref("mail.addr_book.show_phonetic_fields") == "true")
+ document.getElementById("cmd_SortBy_PhoneticName")
+ .setAttribute("hidden", "false");
+}
+
+function SetNameColumn(cmd)
+{
+ var prefValue;
+
+ switch (cmd)
+ {
+ case 'firstLastCmd':
+ prefValue = kFirstNameFirst;
+ break;
+ case 'lastFirstCmd':
+ prefValue = kLastNameFirst;
+ break;
+ case 'displayNameCmd':
+ prefValue = kDisplayName;
+ break;
+ }
+
+ Services.prefs.setIntPref(kPrefMailAddrBookLastNameFirst, prefValue);
+}
+
+function CommandUpdate_AddressBook()
+{
+ goUpdateCommand('cmd_delete');
+ goUpdateCommand('button_delete');
+ goUpdateCommand('cmd_printcardpreview');
+ goUpdateCommand('cmd_printcard');
+ goUpdateCommand('cmd_print');
+ goUpdateCommand('cmd_properties');
+ goUpdateCommand('cmd_newlist');
+}
+
+function ResultsPaneSelectionChanged()
+{
+ UpdateCardView();
+}
+
+function UpdateCardView()
+{
+ var cards = GetSelectedAbCards();
+
+ // display the selected card, if exactly one card is selected.
+ // either no cards, or more than one card is selected, clear the pane.
+ if (cards.length == 1)
+ OnClickedCard(cards[0])
+ else
+ ClearCardViewPane();
+}
+
+function OnClickedCard(card)
+{
+ if (card)
+ DisplayCardViewPane(card);
+ else
+ ClearCardViewPane();
+}
+
+function AbClose()
+{
+ top.close();
+}
+
+function AbPrintCardInternal(doPrintPreview, msgType)
+{
+ var selectedItems = GetSelectedAbCards();
+ var numSelected = selectedItems.length;
+
+ if (!numSelected)
+ return;
+
+ let statusFeedback;
+ statusFeedback = Cc["@mozilla.org/messenger/statusfeedback;1"].createInstance();
+ statusFeedback = statusFeedback.QueryInterface(Ci.nsIMsgStatusFeedback);
+
+ let selectionArray = [];
+
+ for (let i = 0; i < numSelected; i++) {
+ let card = selectedItems[i];
+ let printCardUrl = CreatePrintCardUrl(card);
+ if (printCardUrl) {
+ selectionArray.push(printCardUrl);
+ }
+ }
+
+ printEngineWindow = window.openDialog("chrome://messenger/content/msgPrintEngine.xul",
+ "",
+ "chrome,dialog=no,all",
+ selectionArray.length, selectionArray,
+ statusFeedback, doPrintPreview, msgType);
+
+ return;
+}
+
+function AbPrintCard()
+{
+ AbPrintCardInternal(false, Ci.nsIMsgPrintEngine.MNAB_PRINT_AB_CARD);
+}
+
+function AbPrintPreviewCard()
+{
+ AbPrintCardInternal(true, Ci.nsIMsgPrintEngine.MNAB_PRINTPREVIEW_AB_CARD);
+}
+
+function CreatePrintCardUrl(card)
+{
+ return "data:application/xml;base64," + card.translateTo("base64xml");
+}
+
+function AbPrintAddressBookInternal(doPrintPreview, msgType)
+{
+ let uri = getSelectedDirectoryURI();
+ if (!uri)
+ return;
+
+ var statusFeedback;
+ statusFeedback = Cc["@mozilla.org/messenger/statusfeedback;1"].createInstance();
+ statusFeedback = statusFeedback.QueryInterface(Ci.nsIMsgStatusFeedback);
+
+ /*
+ turn "moz-abmdbdirectory://abook.mab" into
+ "addbook://moz-abmdbdirectory/abook.mab?action=print"
+ */
+
+ var abURIArr = uri.split("://");
+ var printUrl = "addbook://" + abURIArr[0] + "/" + abURIArr[1] + "?action=print"
+
+ printEngineWindow = window.openDialog("chrome://messenger/content/msgPrintEngine.xul",
+ "",
+ "chrome,dialog=no,all",
+ 1, [printUrl],
+ statusFeedback, doPrintPreview, msgType);
+
+ return;
+}
+
+function AbPrintAddressBook()
+{
+ AbPrintAddressBookInternal(false, Ci.nsIMsgPrintEngine.MNAB_PRINT_ADDRBOOK);
+}
+
+function AbPrintPreviewAddressBook()
+{
+ AbPrintAddressBookInternal(true, Ci.nsIMsgPrintEngine.MNAB_PRINTPREVIEW_ADDRBOOK);
+}
+
+/**
+ * Export the currently selected addressbook.
+ */
+function AbExportSelection() {
+ let selectedDirURI = getSelectedDirectoryURI();
+ if (!selectedDirURI)
+ return;
+
+ if (selectedDirURI == (kAllDirectoryRoot + "?"))
+ AbExportAll();
+ else
+ AbExport(selectedDirURI);
+}
+
+/**
+ * Export all found addressbooks, each in a separate file.
+ */
+function AbExportAll()
+{
+ let directories = MailServices.ab.directories;
+
+ while (directories.hasMoreElements()) {
+ let directory = directories.getNext();
+ // Do not export LDAP ABs.
+ if (directory.URI.startsWith(kLdapUrlPrefix))
+ continue;
+
+ AbExport(directory.URI);
+ }
+}
+
+/**
+ * Export the specified addressbook to a file.
+ *
+ * @param aSelectedDirURI The URI of the addressbook to export.
+ */
+function AbExport(aSelectedDirURI)
+{
+ if (!aSelectedDirURI)
+ return;
+
+ try {
+ let directory = GetDirectoryFromURI(aSelectedDirURI);
+ MailServices.ab.exportAddressBook(window, directory);
+ }
+ catch (ex) {
+ var message;
+ switch (ex.result) {
+ case Cr.NS_ERROR_FILE_ACCESS_DENIED:
+ message = gAddressBookBundle.getString("failedToExportMessageFileAccessDenied");
+ break;
+ case Cr.NS_ERROR_FILE_NO_DEVICE_SPACE:
+ message = gAddressBookBundle.getString("failedToExportMessageNoDeviceSpace");
+ break;
+ default:
+ message = ex.message;
+ break;
+ }
+
+ Services.prompt.alert(window,
+ gAddressBookBundle.getString("failedToExportTitle"),
+ message);
+ }
+}
+
+function SetStatusText(total)
+{
+ if (!gStatusText)
+ gStatusText = document.getElementById('statusText');
+
+ try {
+ let statusText;
+
+ if (gSearchInput.value) {
+ if (total == 0) {
+ statusText = gAddressBookBundle.getString("noMatchFound");
+ } else {
+ statusText = PluralForm
+ .get(total, gAddressBookBundle.getString("matchesFound1"))
+ .replace("#1", total);
+ }
+ }
+ else
+ statusText =
+ gAddressBookBundle.getFormattedString(
+ "totalContactStatus",
+ [getSelectedDirectory().dirName, total]);
+
+ gStatusText.setAttribute("label", statusText);
+ }
+ catch(ex) {
+ dump("failed to set status text: " + ex + "\n");
+ }
+}
+
+function AbResultsPaneDoubleClick(card)
+{
+ AbEditCard(card);
+}
+
+function onAdvancedAbSearch()
+{
+ let selectedDirURI = getSelectedDirectoryURI();
+ if (!selectedDirURI)
+ return;
+
+ var existingSearchWindow = Services.wm.getMostRecentWindow("mailnews:absearch");
+ if (existingSearchWindow)
+ existingSearchWindow.focus();
+ else
+ window.openDialog("chrome://messenger/content/ABSearchDialog.xul", "",
+ "chrome,resizable,status,centerscreen,dialog=no",
+ {directory: selectedDirURI});
+}
+
+function onEnterInSearchBar()
+{
+ ClearCardViewPane();
+ if (!gQueryURIFormat) {
+ // Get model query from pref. We don't want the query starting with "?"
+ // as we have to prefix "?and" to this format.
+ gQueryURIFormat = getModelQuery("mail.addr_book.quicksearchquery.format");
+ }
+
+ let searchURI = getSelectedDirectoryURI();
+ if (!searchURI) return;
+
+ /*
+ XXX todo, handle the case where the LDAP url
+ already has a query, like
+ moz-abldapdirectory://nsdirectory.netscape.com:389/ou=People,dc=netscape,dc=com?(or(Department,=,Applications))
+ */
+ // Use helper method to split up search query to multi-word search
+ // query against multiple fields.
+ let searchWords = getSearchTokens(gSearchInput.value);
+ searchURI += generateQueryURI(gQueryURIFormat, searchWords);
+
+ if (searchURI == kAllDirectoryRoot)
+ searchURI += "?";
+
+ document.getElementById("localResultsOnlyMessage")
+ .setAttribute("hidden",
+ !gDirectoryTreeView.hasRemoteAB ||
+ searchURI != kAllDirectoryRoot + "?");
+
+ SetAbView(searchURI);
+
+ // XXX todo
+ // this works for synchronous searches of local addressbooks,
+ // but not for LDAP searches
+ SelectFirstCard();
+}
+
+function SwitchPaneFocus(event)
+{
+ var focusedElement = WhichPaneHasFocus();
+ var cardViewBox = GetCardViewBox();
+ var cardViewBoxEmail1 = GetCardViewBoxEmail1();
+ var searchBox = GetSearchBox();
+ var dirTree = GetDirTree();
+
+ if (event && event.shiftKey)
+ {
+ if (focusedElement == gAbResultsTree && searchBox.getAttribute('hidden') != 'true')
+ searchInput.focus();
+ else if ((focusedElement == gAbResultsTree || focusedElement == searchBox) && !IsDirPaneCollapsed())
+ dirTree.focus();
+ else if (focusedElement != cardViewBox && !IsCardViewAndAbResultsPaneSplitterCollapsed())
+ {
+ if(cardViewBoxEmail1)
+ cardViewBoxEmail1.focus();
+ else
+ cardViewBox.focus();
+ }
+ else
+ gAbResultsTree.focus();
+ }
+ else
+ {
+ if (focusedElement == searchBox)
+ gAbResultsTree.focus();
+ else if (focusedElement == gAbResultsTree && !IsCardViewAndAbResultsPaneSplitterCollapsed())
+ {
+ if(cardViewBoxEmail1)
+ cardViewBoxEmail1.focus();
+ else
+ cardViewBox.focus();
+ }
+ else if (focusedElement != dirTree && !IsDirPaneCollapsed())
+ dirTree.focus();
+ else if (searchBox.getAttribute('hidden') != 'true')
+ gSearchInput.focus();
+ else
+ gAbResultsTree.focus();
+ }
+}
+
+function WhichPaneHasFocus()
+{
+ var cardViewBox = GetCardViewBox();
+ var searchBox = GetSearchBox();
+ var dirTree = GetDirTree();
+
+ var currentNode = top.document.commandDispatcher.focusedElement;
+ while (currentNode)
+ {
+ var nodeId = currentNode.getAttribute('id');
+
+ if(currentNode == gAbResultsTree ||
+ currentNode == cardViewBox ||
+ currentNode == searchBox ||
+ currentNode == dirTree)
+ return currentNode;
+
+ currentNode = currentNode.parentNode;
+ }
+
+ return null;
+}
+
+function GetDirTree()
+{
+ if (!gDirTree)
+ gDirTree = document.getElementById('dirTree');
+ return gDirTree;
+}
+
+function GetSearchBox()
+{
+ if (!gSearchBox)
+ gSearchBox = document.getElementById('searchBox');
+ return gSearchBox;
+}
+
+function GetCardViewBox()
+{
+ if (!gCardViewBox)
+ gCardViewBox = document.getElementById('CardViewBox');
+ return gCardViewBox;
+}
+
+function GetCardViewBoxEmail1()
+{
+ if (!gCardViewBoxEmail1)
+ {
+ try {
+ gCardViewBoxEmail1 = document.getElementById('cvEmail1');
+ }
+ catch (ex) {
+ gCardViewBoxEmail1 = null;
+ }
+ }
+ return gCardViewBoxEmail1;
+}
+
+function IsDirPaneCollapsed()
+{
+ var dirPaneBox = GetDirTree().parentNode;
+ return dirPaneBox.getAttribute("collapsed") == "true" ||
+ dirPaneBox.getAttribute("hidden") == "true";
+}
+
+function IsCardViewAndAbResultsPaneSplitterCollapsed()
+{
+ var cardViewBox = document.getElementById('CardViewOuterBox');
+ try {
+ return (cardViewBox.getAttribute("collapsed") == "true");
+ }
+ catch (ex) {
+ return false;
+ }
+}
+
+function LaunchUrl(url)
+{
+ // Doesn't matter if this bit fails, window.location contains its own prompts
+ try {
+ window.location = url;
+ }
+ catch (ex) {}
+}
+
+function getAbToolbox()
+{
+ return document.getElementById("ab-toolbox");
+}
+
+function AbToolboxCustomizeInit()
+{
+ toolboxCustomizeInit("ab-menubar");
+}
+
+function AbToolboxCustomizeDone(aToolboxChanged)
+{
+ toolboxCustomizeDone("ab-menubar", getAbToolbox(), aToolboxChanged);
+}
+
+function AbToolboxCustomizeChange(event)
+{
+ toolboxCustomizeChange(getAbToolbox(), event);
+}