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