home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 35 Internet / 35-Internet.zip / mozil06.zip / bin / chrome / messenger.jar / content / messenger / msgMail3PaneWindow.js < prev    next >
Text File  |  2001-02-14  |  23KB  |  916 lines

  1. /* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
  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. /* This is where functions related to the 3 pane window are kept */
  22.  
  23.  
  24. var showPerformance;
  25. var msgNavigationService;
  26.  
  27. var gFolderTree;
  28. var gThreadTree;
  29. var gMessagePane;
  30. var gThreadAndMessagePaneSplitter = null;
  31. var gUnreadCount = null;
  32. var gTotalCount = null;
  33.  
  34. var gCurrentLoadingFolderURI;
  35. var gCurrentFolderToReroot;
  36. var gCurrentLoadingFolderIsThreaded = false;
  37. var gCurrentLoadingFolderSortID ="";
  38. var gCurrentLoadingFolderSortDirection = null;
  39.  
  40. var gCurrentDisplayedMessage = null;
  41. var gNextMessageAfterDelete = null;
  42.  
  43. var gActiveThreadPaneSortColumn = "";
  44.  
  45. var gStartFolderUri = null;
  46.  
  47. //If we've loaded a message, set to true.  Helps us keep the start page around.
  48. var gHaveLoadedMessage;
  49.  
  50. // the folderListener object
  51. var folderListener = {
  52.     OnItemAdded: function(parentItem, item, view) {},
  53.  
  54.     OnItemRemoved: function(parentItem, item, view){},
  55.  
  56.     OnItemPropertyChanged: function(item, property, oldValue, newValue) {},
  57.  
  58.     OnItemIntPropertyChanged: function(item, property, oldValue, newValue)
  59.     {
  60.         var currentLoadedFolder = GetThreadTreeFolder();
  61.         var currentURI = currentLoadedFolder.getAttribute('ref');
  62.  
  63.         //if we don't have a folder loaded, don't bother.
  64.         if(currentURI)
  65.         {
  66.             if(property.GetUnicode() == "TotalMessages" || property.GetUnicode() == "TotalUnreadMessages")
  67.             {
  68.                 var folder = item.QueryInterface(Components.interfaces.nsIMsgFolder);
  69.                 if(folder)
  70.                 {
  71.                     var folderResource = folder.QueryInterface(Components.interfaces.nsIRDFResource);
  72.                     if(folderResource)
  73.                     {
  74.                         var folderURI = folderResource.Value;
  75.                         if(currentURI == folderURI)
  76.                         {
  77.                             UpdateStatusMessageCounts(folder);
  78.                         }
  79.                     }
  80.  
  81.  
  82.                 }
  83.  
  84.  
  85.  
  86.             }
  87.         }
  88.     },
  89.  
  90.     OnItemBoolPropertyChanged: function(item, property, oldValue, newValue) {},
  91.  
  92.     OnItemUnicharPropertyChanged: function(item, property, oldValue, newValue){},
  93.     OnItemPropertyFlagChanged: function(item, property, oldFlag, newFlag) {},
  94.  
  95.     OnItemEvent: function(folder, event) {
  96.         if (event.GetUnicode() == "FolderLoaded") {
  97.             
  98.         if(folder)
  99.         {
  100.             var resource = folder.QueryInterface(Components.interfaces.nsIRDFResource);
  101.             if(resource)
  102.             {
  103.                 var uri = resource.Value;
  104.                 //dump("In OnFolderLoaded for " + uri +"\n");
  105.                 if(uri == gCurrentFolderToReroot)
  106.                 {
  107.                     gCurrentFolderToReroot="";
  108.                     var msgFolder = folder.QueryInterface(Components.interfaces.nsIMsgFolder);
  109.                     if(msgFolder)
  110.                     {
  111.                         msgFolder.endFolderLoading();
  112.                         RerootFolder(uri, msgFolder, gCurrentLoadingFolderIsThreaded, gCurrentLoadingFolderSortID, gCurrentLoadingFolderSortDirection);
  113.                         gCurrentLoadingFolderIsThreaded = false;
  114.                         gCurrentLoadingFolderSortID = "";
  115.                         gCurrentLoadingFolderSortDirection = null;
  116.  
  117.                     }
  118.                 }
  119.                 if(uri == gCurrentLoadingFolderURI)
  120.                 {
  121.                   gCurrentLoadingFolderURI = "";
  122.                   //Now let's select the first new message if there is one
  123.                   var beforeScrollToNew = new Date();
  124.                   msgNavigationService.EnsureDocumentIsLoaded(document);
  125.  
  126.                   ScrollToFirstNewMessage();
  127.                   var afterScrollToNew = new Date();
  128.                   var timeToScroll = (afterScrollToNew.getTime() - beforeScrollToNew.getTime())/1000;
  129.  
  130.  
  131.                   var afterFolderLoadTime = new Date();
  132.                   var timeToLoad = (afterFolderLoadTime.getTime() - gBeforeFolderLoadTime.getTime())/1000;
  133.                   if(showPerformance)
  134.                   {
  135.                       dump("Time to load " + uri + " is " +  timeToLoad + " seconds\n");
  136.                         dump("of which scrolling to new is" + timeToScroll + "seconds\n");
  137.                   }
  138.                     SetBusyCursor(window, false);
  139.                 }
  140.             }
  141.  
  142.         }
  143.         } else if (event.GetUnicode() == "DeleteOrMoveMsgCompleted") {
  144.             HandleDeleteOrMoveMsgCompleted(folder);
  145.         }     
  146.           else if (event.GetUnicode() == "DeleteOrMoveMsgFailed") {
  147.                         HandleDeleteOrMoveMsgFailed(folder);
  148.         }
  149.  
  150.     }
  151. }
  152.  
  153. function HandleDeleteOrMoveMsgFailed(folder)
  154. {
  155.  
  156.         if(IsCurrentLoadedFolder(folder))
  157.         {
  158.                 if(gNextMessageAfterDelete)
  159.                 {
  160.                         gNextMessageAfterDelete = null;
  161.         }
  162.         }
  163.  
  164. }
  165.  
  166.  
  167. function HandleDeleteOrMoveMsgCompleted(folder)
  168. {
  169.  
  170.     if(IsCurrentLoadedFolder(folder))
  171.     {
  172.         msgNavigationService.EnsureDocumentIsLoaded(document);
  173.         if(gNextMessageAfterDelete)
  174.         {
  175.             var nextMessage = document.getElementById(gNextMessageAfterDelete);
  176.             gNextMessageAfterDelete = null;
  177.             SelectNextMessage(nextMessage);
  178.             var threadTree = GetThreadTree();
  179.             if(threadTree)
  180.                 threadTree.ensureElementIsVisible(nextMessage);
  181.         }
  182.         //if there's nothing to select then see if the tree has any messages.
  183.         //if not, then clear the message pane.
  184.         else
  185.         {
  186.             var tree = GetThreadTree();
  187.             var topmost = msgNavigationService.FindFirstMessage(tree);
  188.             if(!topmost)
  189.                 ClearMessagePane()
  190.         }
  191.     }
  192.  
  193. }
  194.  
  195.  
  196. function IsCurrentLoadedFolder(folder)
  197. {
  198.     var msgfolder = folder.QueryInterface(Components.interfaces.nsIMsgFolder);
  199.     if(msgfolder)
  200.     {
  201.         var folderResource = msgfolder.QueryInterface(Components.interfaces.nsIRDFResource);
  202.         if(folderResource)
  203.         {
  204.             var folderURI = folderResource.Value;
  205.             var currentLoadedFolder = GetThreadTreeFolder();
  206.             var currentURI = currentLoadedFolder.getAttribute('ref');
  207.             return(currentURI == folderURI);
  208.         }
  209.     }
  210.  
  211.     return false;
  212. }
  213.  
  214. /* Functions related to startup */
  215. function OnLoadMessenger()
  216. {
  217.   var beforeLoadMessenger = new Date();
  218.  
  219.   CreateMailWindowGlobals();
  220.   Create3PaneGlobals();
  221.   verifyAccounts();
  222.     
  223.   loadStartPage();
  224.     InitMsgWindow();
  225.  
  226.     messenger.SetWindow(window, msgWindow);
  227.  
  228.     InitializeDataSources();
  229.     InitPanes();
  230.  
  231.     accountManager.SetSpecialFoldersForIdentities();
  232.  
  233.   AddToSession();
  234.   //need to add to session before trying to load start folder otherwise listeners aren't
  235.   //set up correctly.
  236.   if(window.arguments && window.arguments[0])
  237.   {
  238.     gStartFolderUri = window.arguments[0];
  239.   }
  240.   else
  241.   {
  242.     gStartFolderUri = null;
  243.   }
  244.  
  245.   setTimeout("loadStartFolder(gStartFolderUri);", 0);
  246.  
  247.   // FIX ME - later we will be able to use onload from the overlay
  248.   OnLoadMsgHeaderPane();
  249.  
  250.     var id = null;
  251.     var headerchoice = null;
  252.  
  253.     try {
  254.         headerchoice = pref.GetIntPref("mail.show_headers");
  255.     }
  256.     catch (ex) {
  257.         dump("failed to get the header pref\n");
  258.     }
  259.  
  260.     switch (headerchoice) {
  261.         case 2:    
  262.             id = "viewallheaders";
  263.             break;
  264.         case 0:
  265.             id = "viewbriefheaders";
  266.             break;
  267.         case 1:    
  268.             id = "viewnormalheaders";
  269.             break;
  270.         default:
  271.             id = "viewnormalheaders";
  272.             break;
  273.     }
  274.  
  275.     var menuitem = document.getElementById(id);
  276.  
  277.     try {
  278.         // not working right yet.  see bug #??????
  279.         // menuitem.setAttribute("checked", "true"); 
  280.     }
  281.     catch (ex) {
  282.         dump("failed to set the view headers menu item\n");
  283.     }
  284.  
  285.     gHaveLoadedMessage = false;
  286.  
  287.     //Set focus to the Thread Pane the first time the window is opened.
  288.     SetFocusThreadPane();
  289.  
  290.     var afterLoadMessenger = new Date();
  291.  
  292.     var timeToLoad = (afterLoadMessenger.getTime() - beforeLoadMessenger.getTime())/1000;
  293.     if(showPerformance)
  294.     {
  295.       dump("Time in OnLoadMessger is " +  timeToLoad + " seconds\n");
  296.     }
  297.     
  298. }
  299.  
  300. function OnUnloadMessenger()
  301. {
  302.     dump("\nOnUnload from XUL\nClean up ...\n");
  303.     
  304.     OnMailWindowUnload();
  305. }
  306.  
  307.  
  308. function Create3PaneGlobals()
  309. {
  310.     showPerformance = pref.GetBoolPref('mail.showMessengerPerformance');
  311.  
  312.     msgNavigationService = Components.classes['@mozilla.org/messenger/msgviewnavigationservice;1'].getService();
  313.     msgNavigationService= msgNavigationService.QueryInterface(Components.interfaces.nsIMsgViewNavigationService);
  314.  
  315. }
  316.  
  317.  
  318. function PerformExpandForAllOpenServers(tree)
  319. {
  320.     //dump("PerformExpandForAllOpenServers()\n");
  321.  
  322.     var uri = null;
  323.     var open = null;
  324.     var treechild = null;
  325.     var server = null;
  326.  
  327.     if ( tree && tree.childNodes ) {
  328.         for ( var i = tree.childNodes.length - 1; i >= 0; i-- ) {
  329.             treechild = tree.childNodes[i];
  330.             if (treechild.localName == 'treechildren') {
  331.                 var treeitems = treechild.childNodes;
  332.                 for ( var j = treeitems.length - 1; j >= 0; j--) {
  333.                     open = treeitems[j].getAttribute('open');
  334.                     //dump("open="+open+"\n");
  335.                     if (open == "true") {
  336.                         var isServer = (treeitems[j].getAttribute('IsServer') == "true");
  337.                         //dump("isServer="+isServer+"\n");
  338.                         if (isServer) {
  339.                             uri = treeitems[j].getAttribute('id');
  340.                             //dump("uri="+uri+"\n");
  341.                             server = GetServer(uri);
  342.                             if (server) {
  343.                                 // don't do this for imap servers.
  344.                                 // see bug #41943
  345.                                 if (server.type != "imap") {
  346.                                     //dump("PerformExpand on " + uri + "\n");
  347.                                     server.PerformExpand(msgWindow);
  348.                                 }
  349.                             }
  350.                         }
  351.                     }
  352.                 }
  353.             }
  354.         }
  355.     }
  356. }
  357.  
  358. function loadStartFolder(startFolderUri)
  359. {
  360.     //First get default account
  361.     try
  362.     {
  363.         if(!startFolderUri)
  364.         {
  365.             var defaultAccount = accountManager.defaultAccount;
  366.  
  367.             var server = defaultAccount.incomingServer;
  368.             var rootFolder = server.RootFolder;
  369.             var rootMsgFolder = rootFolder.QueryInterface(Components.interfaces.nsIMsgFolder);
  370.  
  371.             //now find Inbox
  372.             var outNumFolders = new Object();
  373.             var inboxFolder = rootMsgFolder.getFoldersWithFlag(0x1000, 1, outNumFolders); 
  374.             if(!inboxFolder) return;
  375.  
  376.             var resource = inboxFolder.QueryInterface(Components.interfaces.nsIRDFResource);
  377.             startFolderUri = resource.Value;
  378.  
  379.             //first, let's see if it's already in the dom.  This will make life easier.
  380.             //We need to make sure content is built by this time
  381.         }
  382.         msgNavigationService.EnsureDocumentIsLoaded(document);
  383.  
  384.         var startFolder = document.getElementById(startFolderUri);
  385.  
  386.         //if it's not here we will have to make sure it's open.
  387.         if(!startFolder)
  388.         {
  389.  
  390.         }
  391.  
  392.         var folderTree= GetFolderTree();
  393.         ChangeSelection(folderTree, startFolder);
  394.  
  395.         // because the "open" state persists, we'll call
  396.         // PerformExpand() for all servers that are open at startup.
  397.         PerformExpandForAllOpenServers(folderTree);
  398.     }
  399.     catch(ex)
  400.     {
  401.         dump(ex);
  402.         dump('Exception in LoadStartFolder caused by no default account.  We know about this\n');
  403.     }
  404.  
  405. }
  406.  
  407. function AddToSession()
  408. {
  409.     try {
  410.         var mailSession = Components.classes[mailSessionContractID].getService(Components.interfaces.nsIMsgMailSession);
  411.         
  412.         mailSession.AddFolderListener(folderListener);
  413.     } catch (ex) {
  414.         dump("Error adding to session\n");
  415.     }
  416. }
  417.  
  418.  
  419. function InitPanes()
  420. {
  421.     var threadTree = GetThreadTree();
  422.     if(threadTree);
  423.         OnLoadThreadPane(threadTree);
  424.  
  425.     var folderTree = GetFolderTree();
  426.     if(folderTree)
  427.         OnLoadFolderPane(folderTree);
  428.         
  429.     SetupCommandUpdateHandlers();
  430. }
  431.  
  432. function InitializeDataSources()
  433. {
  434.     //Setup common mailwindow stuff.
  435.     AddDataSources();
  436.  
  437.     //To threadpane move context menu
  438.     SetupMoveCopyMenus('threadPaneContext-moveMenu', accountManagerDataSource, folderDataSource);
  439.  
  440.     //To threadpane copy content menu
  441.     SetupMoveCopyMenus('threadPaneContext-copyMenu', accountManagerDataSource, folderDataSource);
  442. }
  443.  
  444. function OnLoadFolderPane(folderTree)
  445. {
  446.     gFolderTree = folderTree;
  447.     SortFolderPane('FolderColumn', 'http://home.netscape.com/NC-rdf#FolderTreeName');
  448.  
  449.     //Add folderDataSource and accountManagerDataSource to folderPane
  450.     accountManagerDataSource = accountManagerDataSource.QueryInterface(Components.interfaces.nsIRDFDataSource);
  451.     folderDataSource = folderDataSource.QueryInterface(Components.interfaces.nsIRDFDataSource);
  452.     var database = GetFolderDatasource();
  453.  
  454.     database.AddDataSource(accountManagerDataSource);
  455.     database.AddDataSource(folderDataSource);
  456.     folderTree.setAttribute('ref', 'msgaccounts:/');
  457. }
  458.  
  459. function GetFolderDatasource()
  460. {
  461.     var folderTree = GetFolderTree();
  462.     var db = folderTree.database;
  463.     if (!db) return false;
  464.     return db;
  465. }
  466.  
  467. function OnLoadThreadPane(threadTree)
  468. {
  469.     gThreadTree = threadTree;
  470.     //Sort by date by default
  471.  
  472.     //Add message data source
  473.     messageDataSource = messageDataSource.QueryInterface(Components.interfaces.nsIRDFDataSource);
  474.     threadTree.database.AddDataSource(messageDataSource);
  475.  
  476.     //FIX ME: Tempory patch for bug 24182
  477.     //ShowThreads(false);
  478.     setTimeout("ShowThreads(false);", 0);
  479. }
  480.  
  481. /* Functions for accessing particular parts of the window*/
  482. function GetFolderTree()
  483. {
  484.     if (gFolderTree) return gFolderTree;
  485.     
  486.     var folderTree = document.getElementById('folderTree');
  487.     gFolderTree = folderTree;
  488.     return folderTree;
  489. }
  490.  
  491. function GetMessagePane()
  492. {
  493.     if (gMessagePane) return gMessagePane;
  494.     gMessagePane = document.getElementById("messagepanebox");
  495.     return gMessagePane;
  496. }
  497.  
  498. function FindInSidebar(currentWindow, id)
  499. {
  500.     var item = currentWindow.document.getElementById(id);
  501.     if(item)
  502.         return item;
  503.  
  504.     for(var i = 0; i < currentWindow.frames.length; i++)
  505.     {
  506.         var frameItem = FindInSidebar(currentWindow.frames[i], id);
  507.         if(frameItem)
  508.             return frameItem;
  509.     }
  510.  
  511.     return null;
  512. }
  513.  
  514. function GetThreadAndMessagePaneSplitter()
  515. {
  516.     if(gThreadAndMessagePaneSplitter) return gThreadAndMessagePaneSplitter;
  517.     var splitter = document.getElementById('threadpane-splitter');
  518.     gThreadAndMessagePaneSplitter = splitter;
  519.     return splitter;
  520. }
  521.  
  522. function GetUnreadCountElement()
  523. {
  524.     if(gUnreadCount) return gUnreadCount;
  525.     var unreadCount = document.getElementById('unreadMessageCount');
  526.     gUnreadCount = unreadCount;
  527.     return unreadCount;
  528. }
  529. function GetTotalCountElement()
  530. {
  531.     if(gTotalCount) return gTotalCount;
  532.     var totalCount = document.getElementById('totalMessageCount');
  533.     gTotalCount = totalCount;
  534.     return totalCount;
  535. }
  536. function IsThreadAndMessagePaneSplitterCollapsed()
  537. {
  538.     var splitter = GetThreadAndMessagePaneSplitter();
  539.     if(splitter)
  540.     {
  541.         var state  = splitter.getAttribute('state');
  542.         return (state == "collapsed");
  543.     }
  544.     else
  545.         return false;
  546. }
  547.  
  548. function FindMessenger()
  549. {
  550.   return messenger;
  551. }
  552.  
  553. function RefreshThreadTreeView()
  554. {
  555.     SetBusyCursor(window, true);
  556.  
  557.     var selection = SaveThreadPaneSelection();
  558.  
  559.     var currentFolder = GetThreadTreeFolder();  
  560.     var currentFolderID = currentFolder.getAttribute('ref');
  561.     ClearThreadTreeSelection();
  562.     currentFolder.setAttribute('ref', currentFolderID);
  563.  
  564.     RestoreThreadPaneSelection(selection);
  565.     SetBusyCursor(window, false);
  566.  
  567. }
  568.  
  569. function ClearThreadTreeSelection()
  570. {
  571.     var tree = GetThreadTree();
  572.     if(tree)
  573.     {
  574.         tree.clearItemSelection();
  575.     }
  576.  
  577. }
  578.  
  579. function ClearMessagePane()
  580. {
  581.     if(gHaveLoadedMessage)
  582.     {    
  583.         gCurrentDisplayedMessage = null;
  584.         if (window.frames["messagepane"].location != "about:blank")
  585.             window.frames["messagepane"].location = "about:blank";
  586.         // hide the message header view AND the message pane...
  587.         HideMessageHeaderPane();
  588.     }
  589. }
  590.  
  591.  
  592. function GetSelectedFolder()
  593. {
  594.     var tree = GetFolderTree();
  595.     var selection = tree.selectedItems;
  596.     if(selection.length > 0)
  597.         return selection[0];
  598.     else
  599.         return null;
  600.  
  601. }
  602.  
  603. function GetServer(uri)
  604. {
  605.     if (!uri) return null;
  606.     try {
  607.         var folder = GetMsgFolderFromUri(uri);
  608.         return folder.server;
  609.     }
  610.     catch (ex) {
  611.         dump("GetServer("+uri+") failed, ex="+ex+"\n");
  612.     }
  613.  
  614.     return null;
  615. }
  616.  
  617. function FolderPaneOnClick(event)
  618. {
  619.     debug("in FolderPaneClick()\n");
  620.  
  621.   var t = event.originalTarget;
  622.   var item;
  623.   var uri;
  624.  
  625.     if (t.getAttribute('twisty') == 'true') {
  626.         // The twisty is nested three below the treeitem:
  627.         // <treeitem>
  628.         //   <treerow>
  629.         //     <treecell>
  630.         //         <titledbutton class="tree-cell-twisty"> <!-- anonymous -->
  631.         var treeitem = t.parentNode.parentNode.parentNode;
  632.         var open = treeitem.getAttribute('open');
  633.         if(open == "true") {
  634.             //dump("twisty open\n");
  635.  
  636.             item = t.parentNode.parentNode.parentNode;
  637.             if (item.localName == "treeitem") {
  638.                 var isServer = (treeitem.getAttribute('IsServer') == "true");
  639.                 if (isServer) {
  640.                     uri = treeitem.getAttribute("id");
  641.                     var server = GetServer(uri);
  642.                     if (server) {
  643.                         server.PerformExpand(msgWindow);
  644.                     }
  645.                 }
  646.                 else {
  647.                     var isImap = (treeitem.getAttribute('ServerType') == "imap");
  648.                     if (isImap) {
  649.                         uri = treeitem.getAttribute("id");
  650.                         var folder = GetMsgFolderFromUri(uri);
  651.                         if (folder) {
  652.                             var imapFolder = folder.QueryInterface(Components.interfaces.nsIMsgImapMailFolder);
  653.                             if (imapFolder) {
  654.                                 imapFolder.PerformExpand(msgWindow);
  655.                             }
  656.                         }
  657.                     }
  658.                 }
  659.             }
  660.         }
  661.     }
  662.     else if(event.detail == 2)
  663.     {
  664.         item = t.parentNode.parentNode;
  665.         if (item.localName == "treeitem")
  666.             FolderPaneDoubleClick(item);
  667.     }
  668. }
  669.  
  670. function FolderPaneDoubleClick(treeitem)
  671. {
  672.     var isServer = false;
  673.  
  674.     if (treeitem) {
  675.         isServer = (treeitem.getAttribute('IsServer') == "true");
  676.         if (isServer) {
  677.             var open = treeitem.getAttribute('open');
  678.             if (open == "true") {
  679.                 var uri = treeitem.getAttribute("id");
  680.                 server = GetServer(uri);
  681.                 if (server) {
  682.                     //dump("double clicking open, PerformExpand()\n");
  683.                     server.PerformExpand(msgWindow);
  684.                 }
  685.             }
  686.             else {
  687.                 //dump("double clicking close, don't PerformExpand()\n");
  688.             }
  689.         }
  690.     }
  691.  
  692.     // don't open a new msg window if we are double clicking on a server.
  693.     // only do it for folders or newsgroups
  694.     if (!isServer) {
  695.         MsgOpenNewWindowForFolder(treeitem.getAttribute('id'));
  696.     }
  697. }
  698.  
  699. function ChangeSelection(tree, newSelection)
  700. {
  701.     if(newSelection)
  702.     {
  703.         tree.clearItemSelection();
  704.         tree.selectItem(newSelection);
  705.         tree.ensureElementIsVisible(newSelection);
  706.     }
  707. }
  708.  
  709. function SetActiveThreadPaneSortColumn(column)
  710. {
  711.     gActiveThreadPaneSortColumn = column;
  712. }
  713.  
  714. function GetActiveThreadPaneSortColumn()
  715. {
  716.     return gActiveThreadPaneSortColumn;
  717. }
  718.  
  719. function ClearActiveThreadPaneSortColumn()
  720. {
  721.     var activeColumn = document.getElementById(gActiveThreadPaneSortColumn);
  722.     if(activeColumn)
  723.     {
  724.         activeColumn.removeAttribute("sortActive");
  725.         activeColumn = "";
  726.     }
  727.  
  728. }
  729.  
  730.  
  731. function GetSelectedMsgFolders()
  732. {
  733.     var folderTree = GetFolderTree();
  734.     var selectedFolders = folderTree.selectedItems;
  735.     var numFolders = selectedFolders.length;
  736.  
  737.     var folderArray = new Array(numFolders);
  738.  
  739.     for(var i = 0; i < numFolders; i++)
  740.     {
  741.         var folder = selectedFolders[i];
  742.         var folderUri = folder.getAttribute("id");
  743.         var folderResource = RDF.GetResource(folderUri);
  744.         var msgFolder = folderResource.QueryInterface(Components.interfaces.nsIMsgFolder);
  745.         if(msgFolder)
  746.         {
  747.             folderArray[i] = msgFolder;    
  748.         }
  749.     }
  750.     return folderArray;
  751. }
  752.  
  753. function GetSelectedMessage(index)
  754. {
  755.     var threadTree = GetThreadTree();
  756.     var selectedMessages = threadTree.selectedItems;
  757.     var numMessages = selectedMessages.length;
  758.     if(index <0 || index > (numMessages - 1))
  759.         return null;
  760.  
  761.     var messageNode = selectedMessages[index];
  762.     var messageUri = messageNode.getAttribute("id");
  763.     var messageResource = RDF.GetResource(messageUri);
  764.     var message = messageResource.QueryInterface(Components.interfaces.nsIMessage);
  765.     return message;
  766.  
  767. }
  768.  
  769. function GetNumSelectedMessages()
  770. {
  771.     var threadTree = GetThreadTree();
  772.     var selectedMessages = threadTree.selectedItems;
  773.     var numMessages = selectedMessages.length;
  774.     return numMessages;
  775. }
  776.  
  777. function GetSelectedMessages()
  778. {
  779.     var threadTree = GetThreadTree();
  780.     var selectedMessages = threadTree.selectedItems;
  781.     var numMessages = selectedMessages.length;
  782.  
  783.     var messageArray = new Array(numMessages);
  784.  
  785.     for(var i = 0; i < numMessages; i++)
  786.     {
  787.         var messageNode = selectedMessages[i];
  788.         var messageUri = messageNode.getAttribute("id");
  789.         var messageResource = RDF.GetResource(messageUri);
  790.         var message = messageResource.QueryInterface(Components.interfaces.nsIMessage);
  791.         if(message)
  792.         {
  793.             messageArray[i] = message;    
  794.         }
  795.     }
  796.     return messageArray;
  797. }
  798.  
  799. function GetLoadedMsgFolder()
  800. {
  801.     var loadedFolder = GetThreadTreeFolder();
  802.     var folderUri = loadedFolder.getAttribute("ref");
  803.     if(folderUri && folderUri != "" && folderUri !="null")
  804.     {
  805.         var folderResource = RDF.GetResource(folderUri);
  806.         if(folderResource)
  807.         {
  808.             try {
  809.                 var msgFolder = folderResource.QueryInterface(Components.interfaces.nsIMsgFolder);
  810.                 return msgFolder;
  811.             }
  812.             catch (ex) {
  813.                 dump(ex + "\n");
  814.                 dump("we know about this.  see bug #35591\n");
  815.             }
  816.         }
  817.     }
  818.     return null;
  819. }
  820.  
  821. function GetLoadedMessage()
  822. {
  823.     if(gCurrentDisplayedMessage)
  824.     {
  825.         var messageResource = RDF.GetResource(gCurrentDisplayedMessage);
  826.         if(messageResource)
  827.         {
  828.             var message = messageResource.QueryInterface(Components.interfaces.nsIMessage);
  829.             return message;
  830.         }
  831.     }
  832.     return null;
  833.  
  834. }
  835.  
  836. //Clear everything related to the current message. called after load start page.
  837. function ClearMessageSelection()
  838. {
  839.     ClearThreadTreeSelection();
  840. }
  841.  
  842. function GetCompositeDataSource(command)
  843. {
  844.     if(command == "GetNewMessages" || command == "DeleteMessages" || command == "Copy"  || 
  845.        command == "Move" ||  command == "NewFolder" ||  command == "MarkAllMessagesRead")
  846.     {
  847.         return GetFolderDatasource();
  848.     }
  849.     else if(command == "MarkMessageRead" || 
  850.             command == "MarkMessageFlagged" || command == "MarkThreadAsRead" ||
  851.             command == "MessageProperty")
  852.     {
  853.         var threadTree = GetThreadTree();
  854.         return threadTree.database;
  855.     }
  856.  
  857.     return null;
  858.  
  859. }
  860.  
  861. //Sets the next message after a delete.  If useSelection is true then use the
  862. //current selection to determine this.  Otherwise use messagesToCheck which will
  863. //be an array of nsIMessage's.
  864. function SetNextMessageAfterDelete(messagesToCheck, useSelection)
  865. {
  866.     if(useSelection)
  867.     {
  868.         var tree = GetThreadTree();
  869.         var nextMessage = GetNextMessageAfterDelete(tree.selectedItems);
  870.         if(nextMessage)
  871.             gNextMessageAfterDelete = nextMessage.getAttribute('id');
  872.         else
  873.             gNextMessageAfterDelete = null;
  874.     }
  875. }
  876.  
  877. function SelectFolder(folderUri)
  878. {
  879.     var tree = GetFolderTree();
  880.     var treeitem = document.getElementById(folderUri);
  881.     if(tree && treeitem)
  882.         ChangeSelection(tree, treeitem);
  883. }
  884.  
  885. function SelectMessage(messageUri)
  886. {
  887.     var tree = GetThreadTree();
  888.     var treeitem = document.getElementById(messageUri);
  889.     if(tree && treeitem)
  890.         ChangeSelection(tree, treeitem);
  891.  
  892. }
  893.  
  894. function ReloadMessage()
  895. {
  896.     var msgToLoad = gCurrentDisplayedMessage;
  897.     //null it out so it will work.
  898.     gCurrentDisplayedMessage = null;
  899.     LoadMessageByUri(msgToLoad);
  900. }
  901.  
  902.  
  903. function SetBusyCursor(window, enable)
  904. {
  905.     if(enable)
  906.         window.setCursor("wait");
  907.     else
  908.         window.setCursor("auto");
  909.  
  910.     var numFrames = window.frames.length;
  911.     for(var i = 0; i < numFrames; i++)
  912.     {
  913.         SetBusyCursor(window.frames[i], enable);
  914.     }
  915. }
  916.