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 / commandglue.js < prev    next >
Text File  |  2000-09-20  |  25KB  |  885 lines

  1. /* -*- Mode: C++; 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.  
  22. /*
  23.  * Command-specific code. This stuff should be called by the widgets
  24.  */
  25.  
  26. //The eventual goal is for this file to go away and for the functions to either be brought into
  27. //mailCommands.js or into 3pane specific code.
  28.  
  29. var gBeforeFolderLoadTime;
  30. var gRDFNamespace = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
  31. function OpenURL(url)
  32. {
  33.   dump("\n\nOpenURL from XUL\n\n\n");
  34.   messenger.SetWindow(window, msgWindow);
  35.   messenger.OpenURL(url);
  36. }
  37.  
  38.  
  39.  
  40.  
  41. function GetMsgFolderFromNode(folderNode)
  42. {
  43.     var folderURI = folderNode.getAttribute("id");
  44.     return GetMsgFolderFromURI(folderURI);
  45. }
  46.  
  47. function GetMsgFolderFromURI(folderURI)
  48. {
  49.     var folderResource = RDF.GetResource(folderURI);
  50.     if(folderResource)
  51.     {
  52.         var msgFolder = folderResource.QueryInterface(Components.interfaces.nsIMsgFolder);
  53.         return msgFolder;
  54.     }
  55.  
  56.     return null;
  57.  
  58.  
  59. }
  60.  
  61. function LoadMessage(messageNode)
  62. {
  63.     var uri = messageNode.getAttribute('id');
  64.     dump(uri + "\n");
  65.  
  66.     LoadMessageByUri(uri);
  67.  
  68. }
  69.  
  70. function LoadMessageByUri(uri)
  71. {  
  72.     if(uri != gCurrentDisplayedMessage)
  73.     {
  74.         var resource = RDF.GetResource(uri);
  75.         var message = resource.QueryInterface(Components.interfaces.nsIMessage); 
  76.         if (message)
  77.             setTitleFromFolder(message.msgFolder, message.mime2DecodedSubject);
  78.  
  79.         var nsIMsgFolder = Components.interfaces.nsIMsgFolder;
  80.         if (message.msgFolder.server.downloadOnBiff)
  81.             message.msgFolder.biffState = nsIMsgFolder.nsMsgBiffState_NoMail;
  82.  
  83.         gCurrentDisplayedMessage = uri;
  84.         gHaveLoadedMessage = true;
  85.         OpenURL(uri);
  86.     }
  87.  
  88. }
  89.  
  90. function ChangeFolderByDOMNode(folderNode)
  91. {
  92.   var uri = folderNode.getAttribute('id');
  93.   dump(uri + "\n");
  94.   
  95.   var isThreaded = folderNode.getAttribute('threaded');
  96.   var sortResource = folderNode.getAttribute('sortResource');
  97.   if(!sortResource)
  98.     sortResource = "";
  99.  
  100.   var sortDirection = folderNode.getAttribute('sortDirection');
  101.  
  102.   if (uri)
  103.       ChangeFolderByURI(uri, isThreaded == "true", sortResource, sortDirection);
  104. }
  105.  
  106. function setTitleFromFolder(msgfolder, subject)
  107. {
  108.     if (!msgfolder) return;
  109.  
  110.     var title;
  111.     var server = msgfolder.server;
  112.  
  113.     if (null != subject)
  114.       title = subject+" - ";
  115.     else
  116.       title = "";
  117.  
  118.     if (msgfolder.isServer) {
  119.             // <hostname>
  120.             title += server.hostName;
  121.     }
  122.     else {
  123.         var middle;
  124.         var end;
  125.         if (server.type == "nntp") {
  126.             // <folder> on <hostname>
  127.             middle = Bundle.GetStringFromName("titleNewsPreHost");
  128.             end = server.hostName;
  129.         } else {
  130.             var identity;
  131.             try {
  132.                 var identities = accountManager.GetIdentitiesForServer(server);
  133.  
  134.                 identity = identities.QueryElementAt(0, Components.interfaces.nsIMsgIdentity);
  135.                 // <folder> for <email>
  136.                 middle = Bundle.GetStringFromName("titleMailPreHost");
  137.                 end = identity.email;
  138.             } catch (ex) {
  139.             }
  140.             
  141.         }
  142.  
  143.         title += msgfolder.prettyName;
  144.         if (middle) title += " " + middle;
  145.         if (end) title += " " + end;
  146.     }
  147.  
  148.     title += " - " + BrandBundle.GetStringFromName("brandShortName");
  149.     window.title = title;
  150. }
  151.  
  152. function ChangeFolderByURI(uri, isThreaded, sortID, sortDirection)
  153. {
  154.   dump('In ChangeFolderByURI uri = ' + uri + "\n");
  155.   if (uri == gCurrentLoadingFolderURI)
  156.     return;
  157.   var resource = RDF.GetResource(uri);
  158.   var msgfolder =
  159.       resource.QueryInterface(Components.interfaces.nsIMsgFolder);
  160.  
  161.   try {
  162.       setTitleFromFolder(msgfolder, null);
  163.   } catch (ex) {
  164.       dump("error setting title: " + ex + "\n");
  165.   }
  166.  
  167.   
  168.   //if it's a server, clear the threadpane and don't bother trying to load.
  169.   if(msgfolder.isServer)
  170.   {
  171.     ClearThreadPane();
  172.     return;
  173.   }
  174.     
  175.   gBeforeFolderLoadTime = new Date();
  176.   gCurrentLoadingFolderURI = uri;
  177.   gNextMessageAfterDelete = null; // forget what message to select, if any
  178.  
  179.   if(msgfolder.manyHeadersToDownload())
  180.   {
  181.     try
  182.     {
  183.         SetBusyCursor(window, true);
  184.         gCurrentFolderToReroot = uri;
  185.         gCurrentLoadingFolderIsThreaded = isThreaded;
  186.         gCurrentLoadingFolderSortID = sortID;
  187.         gCurrentLoadingFolderSortDirection = sortDirection;
  188.         msgfolder.startFolderLoading();
  189.         msgfolder.updateFolder(msgWindow);
  190.     }
  191.     catch(ex)
  192.     {
  193.         dump("Error loading with many headers to download: " + ex + "\n");
  194.     }
  195.   }
  196.   else
  197.   {
  198.     SetBusyCursor(window, true);
  199.     gCurrentFolderToReroot = "";
  200.     gCurrentLoadingFolderIsThreaded = false;
  201.     gCurrentLoadingFolderSortID = "";
  202.     RerootFolder(uri, msgfolder, isThreaded, sortID, sortDirection);
  203.  
  204.     //Need to do this after rerooting folder.  Otherwise possibility of receiving folder loaded
  205.     //notification before folder has actually changed.
  206.     msgfolder.updateFolder(msgWindow);
  207.   }
  208. }
  209.  
  210. function RerootFolder(uri, newFolder, isThreaded, sortID, sortDirection)
  211. {
  212.   dump('In reroot folder\n');
  213.   var folder = GetThreadTreeFolder();
  214.   ClearThreadTreeSelection();
  215.  
  216.   //Set the window's new open folder.
  217.   msgWindow.openFolder = newFolder;
  218.  
  219.   //Set threaded state
  220.   ShowThreads(isThreaded);
  221.   
  222.  
  223.   //Clear the new messages of the old folder
  224.   var oldFolderURI = folder.getAttribute("ref");
  225.   if(oldFolderURI && (oldFolderURI != "null") && (oldFolderURI !=""))
  226.   {
  227.    var oldFolder = GetMsgFolderFromURI(oldFolderURI);
  228.    if(oldFolder)
  229.    {
  230.        if (oldFolder.hasNewMessages)
  231.            oldFolder.clearNewMessages();
  232.    }
  233.   }
  234.  
  235.   //the new folder being selected should have its biff state get cleared.   
  236.   if(newFolder)
  237.   {
  238.     newFolder.biffState = 
  239.           Components.interfaces.nsIMsgFolder.nsMsgBiffState_NoMail;
  240.   }
  241.  
  242.   //Clear out the thread pane so that we can sort it with the new sort id without taking any time.
  243.   folder.setAttribute('ref', "");
  244.  
  245.   var column = FindThreadPaneColumnBySortResource(sortID);
  246.  
  247.   if(column)
  248.     SortThreadPane(column, sortID, "http://home.netscape.com/NC-rdf#Date", false, sortDirection, false);
  249.   else
  250.     SortThreadPane("DateColumn", "http://home.netscape.com/NC-rdf#Date", "", false, null, false);
  251.  
  252.   SetSentFolderColumns(IsSpecialFolder(newFolder, "Sent"));
  253.  
  254.   // Since SetSentFolderColumns() may alter the template's structure,
  255.   // we need to explicitly force the builder to recompile its rules.
  256.   //when switching folders, switch back to closing threads
  257.   SetTemplateTreeItemOpen(false);
  258.   folder.builder.rebuild();
  259.  
  260.   folder.setAttribute('ref', uri);
  261.     msgNavigationService.EnsureDocumentIsLoaded(document);
  262.  
  263.   UpdateStatusMessageCounts(newFolder);
  264.  
  265. }
  266.  
  267. function SetSentFolderColumns(isSentFolder)
  268. {
  269.     var senderColumn = document.getElementById("SenderColumnHeader");
  270.     var senderColumnTemplate = document.getElementById("SenderColumnTemplate");
  271.     var authorColumnHeader = document.getElementById("AuthorColumn");
  272.  
  273.     if(isSentFolder)
  274.     {
  275.         senderColumn.setAttribute("value", Bundle.GetStringFromName("recipientColumnHeader"));
  276.         senderColumn.setAttribute("onclick", "return top.MsgSortByRecipient();");
  277.         senderColumnTemplate.setAttribute("value", "rdf:http://home.netscape.com/NC-rdf#Recipient");
  278.         authorColumnHeader.setAttribute("resource", "http://home.netscape.com/NC-rdf#Recipient");
  279.     }
  280.     else
  281.     {
  282.         senderColumn.setAttribute("value", Bundle.GetStringFromName("senderColumnHeader"));
  283.         senderColumn.setAttribute("onclick", "return top.MsgSortBySender();");
  284.         senderColumnTemplate.setAttribute("value", "rdf:http://home.netscape.com/NC-rdf#Sender");
  285.         authorColumnHeader.setAttribute("resource", "http://home.netscape.com/NC-rdf#Sender");
  286.     }
  287.  
  288.  
  289. }
  290.  
  291. function UpdateStatusMessageCounts(folder)
  292. {
  293.     var unreadElement = GetUnreadCountElement();
  294.     var totalElement = GetTotalCountElement();
  295.     if(folder && unreadElement && totalElement)
  296.     {
  297.         var numUnread =
  298.             Bundle.formatStringFromName("unreadMsgStatus",
  299.                                         [ folder.getNumUnread(false)], 1);
  300.         var numTotal =
  301.             Bundle.formatStringFromName("totalMsgStatus",
  302.                                         [folder.getTotalMessages(false)], 1);
  303.  
  304.         unreadElement.setAttribute("value", numUnread);
  305.         totalElement.setAttribute("value", numTotal);
  306.  
  307.     }
  308.  
  309. }
  310.  
  311. function SaveThreadPaneSelection()
  312. {
  313.     var tree = GetThreadTree();
  314.     var selectedItems = tree.selectedItems;
  315.     var numSelected = selectedItems.length;
  316.  
  317.     var selectionArray = new Array(numSelected);
  318.  
  319.     for(var i = 0; i < numSelected; i++)
  320.     {
  321.         selectionArray[i] = selectedItems[i].getAttribute("id");
  322.     }
  323.  
  324.     return selectionArray;
  325. }
  326.  
  327. function RestoreThreadPaneSelection(selectionArray)
  328. {
  329.     var tree = GetThreadTree();
  330.     var numSelected = selectionArray.length;
  331.  
  332.     msgNavigationService.EnsureDocumentIsLoaded(document);
  333.  
  334.     var messageElement;
  335.     for(var i = 0 ; i < numSelected; i++)
  336.     {
  337.         messageElement = document.getElementById(selectionArray[i]);
  338.  
  339.         if(!messageElement && messageView.showThreads)
  340.         {
  341.             var treeFolder = GetThreadTreeFolder();
  342.             var folderURI = treeFolder.getAttribute('ref');
  343.             var folderResource = RDF.GetResource(folderURI);
  344.             var folder = folderResource.QueryInterface(Components.interfaces.nsIMsgFolder);
  345.  
  346.             var messageResource = RDF.GetResource(selectionArray[i]);
  347.             var message = messageResource.QueryInterface(Components.interfaces.nsIMessage);
  348.  
  349.             var topLevelMessage = GetTopLevelMessageForMessage(message, folder);
  350.             var topLevelResource = topLevelMessage.QueryInterface(Components.interfaces.nsIRDFResource);
  351.             var topLevelURI = topLevelResource.Value;
  352.             var topElement = document.getElementById(topLevelURI);
  353.             if(topElement)
  354.             {
  355.                 msgNavigationService.OpenTreeitemAndDescendants(topElement);
  356.             }
  357.  
  358.             messageElement = document.getElementById(selectionArray[i]);
  359.  
  360.         }
  361.         if(messageElement)
  362.         {
  363.             dump("We have a messageElement\n");
  364.             tree.addItemToSelection(messageElement);
  365.             if(i==0)
  366.                 tree.ensureElementIsVisible(messageElement);
  367.         }
  368.     }
  369.  
  370. }
  371.  
  372. function FindThreadPaneColumnBySortResource(sortID)
  373. {
  374.  
  375.     if(sortID == "http://home.netscape.com/NC-rdf#Date")
  376.         return "DateColumn";
  377.     else if(sortID == "http://home.netscape.com/NC-rdf#Sender")
  378.         return "AuthorColumn";
  379.     else if(sortID == "http://home.netscape.com/NC-rdf#Recipient")
  380.         return "AuthorColumn";
  381.     else if(sortID == "http://home.netscape.com/NC-rdf#Status")
  382.         return "StatusColumn";
  383.     else if(sortID == "http://home.netscape.com/NC-rdf#Subject")
  384.         return "SubjectColumn";
  385.     else if(sortID == "http://home.netscape.com/NC-rdf#Flagged")
  386.         return "FlaggedButtonColumn";
  387.     else if(sortID == "http://home.netscape.com/NC-rdf#Priority")
  388.         return "PriorityColumn";
  389.     else if(sortID == "http://home.netscape.com/NC-rdf#Size")
  390.         return "SizeColumn";
  391.     else if(sortID == "http://home.netscape.com/NC-rdf#IsUnread")
  392.         return "UnreadButtonColumn";
  393.     else if(sortID == "http://home.netscape.com/NC-rdf#TotalUnreadMessages")
  394.         return "UnreadColumn";
  395.     else if(sortID == "http://home.netscape.com/NC-rdf#TotalMessages")
  396.         return "TotalColumn";
  397.     else if(sortID == "http://home.netscape.com/NC-rdf#OrderReceived")
  398.         return "OrderReceivedColumn";
  399.  
  400.     return null;
  401.  
  402.  
  403. }
  404.  
  405. //If toggleCurrentDirection is true, then get current direction and flip to opposite.
  406. //If it's not true then use the direction passed in.
  407. function SortThreadPane(column, sortKey, secondarySortKey, toggleCurrentDirection, direction, changeCursor)
  408. {
  409.     //dump("In SortThreadPane\n");
  410.     var node = document.getElementById(column);
  411.     if(!node)
  412.         return false;
  413.  
  414.     if(!direction)
  415.     {
  416.         direction = "ascending";
  417.         //If we just clicked on the same column, then change the direction
  418.         if(toggleCurrentDirection)
  419.         {
  420.             var currentDirection = node.getAttribute('sortDirection');
  421.             if (currentDirection == "ascending")
  422.                     direction = "descending";
  423.             else if (currentDirection == "descending")
  424.                     direction = "ascending";
  425.         }
  426.     }
  427.  
  428.     UpdateSortIndicator(column, direction);
  429.     UpdateSortMenu(column);
  430.  
  431.    var folder = GetSelectedFolder();
  432.     if(folder)
  433.     {
  434.         folder.setAttribute("sortResource", sortKey);
  435.         folder.setAttribute("sortDirection", direction);
  436.     }
  437.  
  438.     SetActiveThreadPaneSortColumn(column);
  439.  
  440.     var selection = SaveThreadPaneSelection();
  441.     var beforeSortTime = new Date();
  442.  
  443.     if(changeCursor)
  444.         SetBusyCursor(window, true);
  445.     var result = SortColumn(node, sortKey, secondarySortKey, direction);
  446.     if(changeCursor)
  447.         SetBusyCursor(window, false);
  448.     var afterSortTime = new Date();
  449.     var timeToSort = (afterSortTime.getTime() - beforeSortTime.getTime())/1000;
  450.  
  451.     if(showPerformance)
  452.         dump("timeToSort is " + timeToSort + "seconds\n");
  453.     RestoreThreadPaneSelection(selection);
  454.     return result;
  455. }
  456.  
  457. //------------------------------------------------------------
  458. // Sets the column header sort icon based on the requested 
  459. // column and direction.
  460. // 
  461. // Notes:
  462. // (1) This function relies on the first part of the 
  463. //     <treecell id> matching the <treecol id>.  The treecell
  464. //     id must have a "Header" suffix.
  465. // (2) By changing the "sortDirection" attribute, a different
  466. //     CSS style will be used, thus changing the icon based on
  467. //     the "sortDirection" parameter.
  468. //------------------------------------------------------------
  469. function UpdateSortIndicator(column,sortDirection)
  470. {
  471.     // Find the <treerow> element
  472.     var treerow = document.getElementById("headRow");
  473.  
  474.     //The SortThreadPane function calls the Sender/Recipient column 'AuthorColumn' 
  475.     //but it's treecell header id is actually 'SenderColumnHeader', so we need to flip
  476.     //it here so that the css can handle changing it's style correctly.
  477.     if(column == "AuthorColumn"){
  478.         column = "SenderColumn";
  479.     }
  480.  
  481.     var id = column + "Header";
  482.     
  483.     if (treerow)
  484.     {
  485.         // Grab all of the <treecell> elements
  486.         var treecell = treerow.getElementsByTagName("treecell");
  487.         if (treecell)
  488.         {
  489.             // Loop through each treecell...
  490.             var node_count = treecell.length;
  491.             for (var i=0; i < node_count; i++)
  492.             {
  493.                 // Is this the requested column ?
  494.                 if (id == treecell[i].getAttribute("id"))
  495.                 {
  496.                     // Set the sortDirection so the class (CSS) will add the
  497.                     // appropriate icon to the header cell
  498.                     treecell[i].setAttribute('sortDirection',sortDirection);
  499.                 }
  500.                 else
  501.                 {
  502.                     // This is not the sorted row
  503.                     treecell[i].removeAttribute('sortDirection');
  504.                 }
  505.             }
  506.         }
  507.     }
  508. }
  509.  
  510. function UpdateSortMenu(currentSortColumn)
  511. {
  512.     UpdateSortMenuitem(currentSortColumn, "sortByDateMenuitem", "DateColumn");
  513.     UpdateSortMenuitem(currentSortColumn, "sortByFlagMenuitem", "FlaggedButtonColumn");
  514.     UpdateSortMenuitem(currentSortColumn, "sortByOrderReceivedMenuitem", "OrderReceivedColumn");
  515.     UpdateSortMenuitem(currentSortColumn, "sortByPriorityMenuitem", "PriorityColumn");
  516.     UpdateSortMenuitem(currentSortColumn, "sortBySenderMenuitem", "AuthorColumn");
  517.     UpdateSortMenuitem(currentSortColumn, "sortBySizeMenuitem", "SizeColumn");
  518.     UpdateSortMenuitem(currentSortColumn, "sortByStatusMenuitem", "StatusColumn");
  519.     UpdateSortMenuitem(currentSortColumn, "sortBySubjectMenuitem", "SubjectColumn");
  520.     UpdateSortMenuitem(currentSortColumn, "sortByUnreadMenuitem", "UnreadButtonColumn");
  521.  
  522. }
  523.  
  524. function UpdateSortMenuitem(currentSortColumnID, menuItemID, columnID)
  525. {
  526.     var menuItem = document.getElementById(menuItemID);
  527.     if(menuItem)
  528.     {
  529.         menuItem.setAttribute("checked", currentSortColumnID == columnID);
  530.     }
  531. }
  532.  
  533. function SortFolderPane(column, sortKey)
  534. {
  535.     var node = FindInSidebar(window, column);
  536.     if(!node)
  537.     {
  538.         dump('Couldnt find sort column\n');
  539.         return false;
  540.     }
  541.     SortColumn(node, sortKey, null, null);
  542.     //Remove the sortActive attribute because we don't want this pane to have any
  543.     //sort styles.
  544.     node.setAttribute("sortActive", "false");
  545.     return true;
  546. }
  547.  
  548. function SortColumn(node, sortKey, secondarySortKey, direction)
  549. {
  550.     dump('In SortColumn\n');
  551.     var xulSortService = Components.classes["@mozilla.org/rdf/xul-sort-service;1"].getService();
  552.  
  553.     if (xulSortService)
  554.     {
  555.         xulSortService = xulSortService.QueryInterface(Components.interfaces.nsIXULSortService);
  556.         if (xulSortService)
  557.         {
  558.             // sort!!!
  559.             var sortDirection;
  560.             if(direction)
  561.                 sortDirection = direction;
  562.             else
  563.             {
  564.                 var currentDirection = node.getAttribute('sortDirection');
  565.                 if (currentDirection == "ascending")
  566.                         sortDirection = "descending";
  567.                 else if (currentDirection == "descending")
  568.                         sortDirection = "ascending";
  569.                 else    sortDirection = "ascending";
  570.             }
  571.  
  572.             try
  573.             {
  574.                 if(secondarySortKey)
  575.                     node.setAttribute('resource2', secondarySortKey);
  576.                 xulSortService.Sort(node, sortKey, sortDirection);
  577.             }
  578.             catch(e)
  579.             {
  580.                         //dump("Sort failed: " + e + "\n");
  581.             }
  582.         }
  583.     }
  584.  
  585. }
  586.  
  587. function GetSelectedFolderResource()
  588. {
  589.     var folderTree = GetFolderTree();
  590.     var selectedFolderList = folderTree.selectedItems;
  591.     var selectedFolder = selectedFolderList[0];
  592.     var uri = selectedFolder.getAttribute('id');
  593.  
  594.  
  595.     var folderResource = RDF.GetResource(uri);
  596.     return folderResource;
  597.  
  598. }
  599.  
  600. function SetFolderCharset(folderResource, aCharset)
  601. {
  602.     var db = GetFolderDatasource();
  603.  
  604.     var charsetResource = RDF.GetLiteral(aCharset);
  605.     var charsetProperty = RDF.GetResource("http://home.netscape.com/NC-rdf#Charset");
  606.  
  607.     db.Assert(folderResource, charsetProperty, charsetResource, true);
  608. }
  609.  
  610.  
  611.  
  612. function ToggleMessageRead(treeItem)
  613. {
  614.  
  615.     var tree = GetThreadTree();
  616.  
  617.     var messageResource = RDF.GetResource(treeItem.getAttribute('id'));
  618.  
  619.     var property = RDF.GetResource('http://home.netscape.com/NC-rdf#IsUnread');
  620.     var result = tree.database.GetTarget(messageResource, property , true);
  621.     result = result.QueryInterface(Components.interfaces.nsIRDFLiteral);
  622.     var isUnread = (result.Value == "true")
  623.  
  624.     var message = messageResource.QueryInterface(Components.interfaces.nsIMessage);
  625.     var messageArray = new Array(1);
  626.     messageArray[0] = message;
  627.  
  628.     MarkMessagesRead(tree.database, messageArray, isUnread);
  629. }
  630.  
  631. function ToggleMessageFlagged(treeItem)
  632. {
  633.  
  634.     var tree = GetThreadTree();
  635.  
  636.     var messageResource = RDF.GetResource(treeItem.getAttribute('id'));
  637.  
  638.     var property = RDF.GetResource('http://home.netscape.com/NC-rdf#Flagged');
  639.     var result = tree.database.GetTarget(messageResource, property , true);
  640.     result = result.QueryInterface(Components.interfaces.nsIRDFLiteral);
  641.     var flagged = (result.Value == "flagged")
  642.  
  643.     var message = messageResource.QueryInterface(Components.interfaces.nsIMessage);
  644.     var messageArray = new Array(1);
  645.     messageArray[0] = message;
  646.  
  647.     MarkMessagesFlagged(tree.database, messageArray, !flagged);
  648.  
  649. }
  650.  
  651. //Called when the splitter in between the thread and message panes is clicked.
  652. function OnClickThreadAndMessagePaneSplitter()
  653. {
  654.     dump("We are in OnClickThreadAndMessagePaneSplitter()\n");
  655.     var collapsed = IsThreadAndMessagePaneSplitterCollapsed();
  656.     //collapsed is the previous state so we know we are opening.
  657.     if(collapsed)
  658.         LoadSelectionIntoMessagePane();    
  659. }
  660.  
  661.  
  662. //takes the selection from the thread pane and loads it into the message pane
  663. function LoadSelectionIntoMessagePane()
  664. {
  665.     var tree = GetThreadTree();
  666.     
  667.     var selArray = tree.selectedItems;
  668.     if (!gNextMessageAfterDelete && selArray && (selArray.length == 1) )
  669.         LoadMessage(selArray[0]);
  670.     else
  671.   {
  672.     // don't necessarily clear the message pane...if you uncomment this,
  673.     // you'll be introducing a large inefficiency when deleting messages...as deleting
  674.     // a msg brings us here twice...so we end up clearing the message pane twice for no
  675.     // good reason...
  676.         // ClearMessagePane();
  677.   }
  678. }
  679.  
  680. function FolderPaneSelectionChange()
  681. {
  682.     var tree = GetFolderTree();
  683.     if(tree)
  684.     {
  685.         var selArray = tree.selectedItems;
  686.         if ( selArray && (selArray.length == 1) )
  687.         {
  688.             ChangeFolderByDOMNode(selArray[0]);
  689.         }
  690.         else
  691.         {
  692.             ClearThreadPane();
  693.         }
  694.     }
  695.     ClearMessagePane();
  696.  
  697. }
  698.  
  699. function ClearThreadPane()
  700. {
  701.     var threadTree = GetThreadTree();
  702.     ClearThreadTreeSelection();
  703.     threadTree.setAttribute('ref', null);
  704. }
  705.  
  706. function OpenFolderTreeToFolder(folderURI)
  707. {
  708.     var tree = GetFolderTree();
  709.     return OpenToFolder(tree, folderURI);
  710.  
  711. }
  712.  
  713. function OpenToFolder(item, folderURI)
  714. {
  715.  
  716.     if(item.nodeType != Node.ELEMENT_NODE)
  717.         return null;
  718.  
  719.     var uri = item.getAttribute('id');
  720.     dump(uri);
  721.     dump('\n');
  722.     if(uri == folderURI)
  723.     {
  724.         dump('found folder: ' + uri);
  725.         dump('\n');
  726.         return item;
  727.     }
  728.  
  729.     var children = item.childNodes;
  730.     var length = children.length;
  731.     var i;
  732.     dump('folder ' + uri);
  733.     dump('has ' + length);
  734.     dump('children\n');
  735.     for(i = 0; i < length; i++)
  736.     {
  737.         var child = children[i];
  738.         var folder = OpenToFolder(child, folderURI);
  739.         if(folder)
  740.         {
  741.             child.setAttribute('open', 'true');
  742.             return folder;
  743.         }
  744.     }
  745.     return null;
  746. }
  747.  
  748.  
  749. function IsSpecialFolder(msgFolder, specialFolderName)
  750. {
  751.     var db = GetFolderDatasource();
  752.     var folderResource = msgFolder.QueryInterface(Components.interfaces.nsIRDFResource);
  753.     if(folderResource)
  754.     {
  755.         var property =
  756.             RDF.GetResource('http://home.netscape.com/NC-rdf#SpecialFolder');
  757.         if (!property) return false;
  758.         var result = db.GetTarget(folderResource, property , true);
  759.         if (!result) return false;
  760.         result = result.QueryInterface(Components.interfaces.nsIRDFLiteral);
  761.         if (!result) return false;
  762.         dump("We are looking for " + specialFolderName + "\n");
  763.         dump("special folder name = " + result.Value + "\n");
  764.         if(result.Value == specialFolderName)
  765.             return true;
  766.     }
  767.  
  768.     return false;
  769. }
  770.  
  771.  
  772. function ShowThreads(showThreads)
  773. {
  774.     dump('in showthreads\n');
  775.     if(messageView)
  776.     {
  777.         messageView.showThreads = showThreads;
  778.         var threadColumn = document.getElementById('ThreadColumnHeader');
  779.         if(threadColumn)
  780.         {
  781.             if(showThreads)
  782.             {
  783.                 threadColumn.setAttribute('currentView', 'threaded');
  784.             }
  785.             else
  786.             {
  787.                 threadColumn.setAttribute('currentView', 'unthreaded');
  788.             }
  789.         }
  790.     }
  791. }
  792.  
  793.  
  794. function GetNextMessageAfterDelete(messages)
  795. {
  796.     var count = messages.length;
  797.  
  798.     var curMessage = messages[0];
  799.     var nextMessage = null;
  800.     var tree = GetThreadTree();
  801.  
  802.     //search forward
  803.     while(curMessage)
  804.     {
  805.         nextMessage = msgNavigationService.FindNextMessage(navigateAny, tree, curMessage, RDF, document, false, messageView.showThreads);
  806.         if(nextMessage)
  807.         {
  808.             if(nextMessage.getAttribute("selected") != "true")
  809.             {
  810.                 break;
  811.             }
  812.         }
  813.         curMessage = nextMessage;
  814.     }
  815.     //if no nextmessage then search backwards
  816.     if(!nextMessage)
  817.     {
  818.  
  819.         curMessage = messages[0];
  820.         nextMessage = null;
  821.         //search forward
  822.         while(curMessage)
  823.         {
  824.             nextMessage = msgNavigationService.FindPreviousMessage(navigateAny, tree, curMessage, RDF, document, false, messageView.showThreads);
  825.             if(nextMessage)
  826.             {
  827.                 if(nextMessage.getAttribute("selected") != "true")
  828.                 {
  829.                     break;
  830.                 }
  831.             }
  832.             curMessage = nextMessage;
  833.         }
  834.  
  835.  
  836.  
  837.     }
  838.     return nextMessage;
  839. }
  840.  
  841.  
  842. function SelectNextMessage(nextMessage)
  843. {
  844.     var tree = GetThreadTree();
  845.     ChangeSelection(tree, nextMessage);
  846.  
  847. }
  848.  
  849. function GetSelectTrashUri(folder)
  850. {
  851.     if (!folder) return null;
  852.     var uri = folder.getAttribute('id');
  853.     dump (uri + "\n");
  854.     var resource = RDF.GetResource(uri);
  855.     var msgFolder =
  856.         resource.QueryInterface(Components.interfaces.nsIMsgFolder);
  857.     if (msgFolder)
  858.     {
  859.         dump("GetSelectTrashUri" + "\n");
  860.         var rootFolder = msgFolder.rootFolder;
  861.         var numFolder;
  862.         var out = new Object();
  863.         var trashFolder = rootFolder.getFoldersWithFlag(0x0100, 1, out); 
  864.         numFolder = out.value;
  865.         dump (numFolder + "\n");
  866.         if (trashFolder)
  867.         {
  868.             dump (trashFolder.URI + "\n");
  869.             return trashFolder.URI;
  870.         }
  871.     }
  872.     return null;
  873. }
  874.  
  875. function Undo()
  876. {
  877.     messenger.Undo(msgWindow);
  878. }
  879.  
  880. function Redo()
  881. {
  882.     messenger.Redo(msgWindow);
  883. }
  884.  
  885.