home *** CD-ROM | disk | FTP | other *** search
/ Chip 2002 January / 01_02.iso / software / netscape62win / mail.xpi / bin / chrome / messenger.jar / content / messenger / commandglue.js < prev    next >
Text File  |  2001-08-26  |  24KB  |  796 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.  * Contributors(s):
  21.  *   Jan Varga <varga@utcru.sk>
  22.  *   Hσkan Waara (hwaara@chello.se)
  23.  */
  24.  
  25.  
  26. /*
  27.  * Command-specific code. This stuff should be called by the widgets
  28.  */
  29.  
  30. //NOTE: gMessengerBundle and gBrandBundle must be defined and set
  31. //      for this Overlay to work properly
  32.  
  33. var gFolderJustSwitched = false;
  34. var gBeforeFolderLoadTime;
  35. var gRDFNamespace = "http://www.w3.org/1999/02/22-rdf-syntax-ns#";
  36.  
  37. /* keep in sync with nsMsgFolderFlags.h */
  38. var MSG_FOLDER_FLAG_TRASH = 0x0100;
  39. var MSG_FOLDER_FLAG_SENTMAIL = 0x0200;
  40. var MSG_FOLDER_FLAG_DRAFTS = 0x0400;
  41. var MSG_FOLDER_FLAG_QUEUE = 0x0800;
  42. var MSG_FOLDER_FLAG_INBOX = 0x1000;
  43. var MSG_FOLDER_FLAG_TEMPLATES = 0x400000;
  44.  
  45. function OpenURL(url)
  46. {
  47.   //dump("\n\nOpenURL from XUL\n\n\n");
  48.   messenger.SetWindow(window, msgWindow);
  49.   messenger.OpenURL(url);
  50. }
  51.  
  52. function GetMsgFolderFromResource(folderResource)
  53. {
  54.   if (!folderResource)
  55.      return null;
  56.  
  57.   var msgFolder = folderResource.QueryInterface(Components.interfaces.nsIMsgFolder);
  58.   return msgFolder;
  59. }
  60.  
  61. function GetMsgFolderFromURI(folderURI)
  62. {
  63.   var folderResource = RDF.GetResource(folderURI);
  64.   return GetMsgFolderFromResource(folderResource);
  65. }
  66.  
  67. function GetServer(uri)
  68. {
  69.     if (!uri) return null;
  70.     try {
  71.         var folder = GetMsgFolderFromUri(uri);
  72.         return folder.server;
  73.     }
  74.     catch (ex) {
  75.         dump("GetServer("+uri+") failed, ex="+ex+"\n");
  76.     }
  77.     return null;
  78. }
  79.  
  80. function LoadMessageByUri(uri)
  81. {
  82.     dump("XXX LoadMessageByUri " + uri + " vs " + gCurrentDisplayedMessage + "\n");
  83.   if(uri != gCurrentDisplayedMessage)
  84.   {
  85.         dump("fix this, get the nsIMsgDBHdr and the nsIMsgFolder from the uri...\n");
  86. /*
  87.     var resource = RDF.GetResource(uri);
  88.     var message = resource.QueryInterface(Components.interfaces.nsIMessage);
  89.     if (message)
  90.       setTitleFromFolder(message.msgFolder, message.mimef2DecodedSubject);
  91.  
  92.     var nsIMsgFolder = Components.interfaces.nsIMsgFolder;
  93.     if (message.msgFolder.server.downloadOnBiff)
  94.       message.msgFolder.biffState = nsIMsgFolder.nsMsgBiffState_NoMail;
  95. */
  96.  
  97.     gCurrentDisplayedMessage = uri;
  98.     gHaveLoadedMessage = true;
  99.     OpenURL(uri);
  100.   }
  101.  
  102. }
  103.  
  104. function setTitleFromFolder(msgfolder, subject)
  105. {
  106.     if (!msgfolder) return;
  107.  
  108.     var title;
  109.     var server = msgfolder.server;
  110.  
  111.     if (null != subject)
  112.       title = subject+" - ";
  113.     else
  114.       title = "";
  115.  
  116.     if (msgfolder.isServer) {
  117.             // <hostname>
  118.             title += server.hostName;
  119.     }
  120.     else {
  121.         var middle;
  122.         var end;
  123.         if (server.type == "nntp") {
  124.             // <folder> on <hostname>
  125.             middle = gMessengerBundle.getString("titleNewsPreHost");
  126.             end = server.hostName;
  127.         } else {
  128.             var identity;
  129.             try {
  130.                 var identities = accountManager.GetIdentitiesForServer(server);
  131.  
  132.                 identity = identities.QueryElementAt(0, Components.interfaces.nsIMsgIdentity);
  133.                 // <folder> for <email>
  134.                 middle = gMessengerBundle.getString("titleMailPreHost");
  135.                 end = identity.email;
  136.             } catch (ex) {
  137.             }
  138.  
  139.         }
  140.  
  141.         title += msgfolder.prettyName;
  142.         if (middle) title += " " + middle;
  143.         if (end) title += " " + end;
  144.     }
  145.  
  146.     title += " - " + gBrandBundle.getString("brandShortName");
  147.     window.title = title;
  148. }
  149.  
  150. function ChangeFolderByURI(uri, viewType, viewFlags, sortType, sortOrder)
  151. {
  152.   //dump("In ChangeFolderByURI uri = " + uri + " sortType = " + sortType + "\n");
  153.   if (uri == gCurrentLoadingFolderURI)
  154.     return;
  155.   var resource = RDF.GetResource(uri);
  156.   var msgfolder =
  157.       resource.QueryInterface(Components.interfaces.nsIMsgFolder);
  158.  
  159.   try {
  160.       setTitleFromFolder(msgfolder, null);
  161.   } catch (ex) {
  162.       dump("error setting title: " + ex + "\n");
  163.   }
  164.  
  165.   //if it's a server, clear the threadpane and don't bother trying to load.
  166.   if(msgfolder.isServer) {
  167.     msgWindow.openFolder = null;
  168.  
  169.     ClearThreadPane();
  170.  
  171.     // Load AccountCentral page here.
  172.     ShowAccountCentral();
  173.  
  174.     return;
  175.   }
  176.   else
  177.   {
  178.     if (msgfolder.server.displayStartupPage)
  179.     {
  180.       gDisplayStartupPage = true;
  181.       msgfolder.server.displayStartupPage = false;
  182.     }
  183.   }
  184.  
  185.   // If the user clicks on msgfolder, time to display thread pane and message pane.
  186.   // Hide AccountCentral page
  187.   if (gAccountCentralLoaded)
  188.   {
  189.       HideAccountCentral();
  190.   }
  191.  
  192.   if (showPerformance) {
  193.     gBeforeFolderLoadTime = new Date();
  194.   }
  195.  
  196.   gCurrentLoadingFolderURI = uri;
  197.   gNextMessageAfterDelete = null; // forget what message to select, if any
  198.  
  199.   if(msgfolder.manyHeadersToDownload())
  200.   {
  201.   try
  202.   {
  203.     SetBusyCursor(window, true);
  204.     gCurrentFolderToReroot = uri;
  205.     gCurrentLoadingFolderViewFlags = viewFlags;
  206.     gCurrentLoadingFolderViewType = viewType;
  207.     gCurrentLoadingFolderSortType = sortType;
  208.     gCurrentLoadingFolderSortOrder = sortOrder;
  209.     msgfolder.startFolderLoading();
  210.     msgfolder.updateFolder(msgWindow);
  211.   }
  212.   catch(ex)
  213.   {
  214.         SetBusyCursor(window, false);
  215.         dump("Error loading with many headers to download: " + ex + "\n");
  216.   }
  217.   }
  218.   else
  219.   {
  220.     SetBusyCursor(window, true);
  221.     gCurrentFolderToReroot = "";
  222.     gCurrentLoadingFolderViewFlags = 0;  // is this correct?
  223.     gCurrentLoadingFolderSortType = 0;  // is this correct?
  224.     gCurrentLoadingFolderSortOrder = 0;  // is this correct?
  225.     gCurrentLoadingFolderViewType = 0;  // is this correct?
  226.     RerootFolder(uri, msgfolder, viewType, viewFlags, sortType, sortOrder);
  227.  
  228.     //Need to do this after rerooting folder.  Otherwise possibility of receiving folder loaded
  229.     //notification before folder has actually changed.
  230.     msgfolder.updateFolder(msgWindow);
  231.   }
  232.  
  233.   document.commandDispatcher.updateCommands('mail-toolbar');
  234. }
  235.  
  236. function isNewsURI(uri)
  237. {
  238.     if (!uri || uri[0] != 'n') {
  239.         return false;
  240.     }
  241.     else {
  242.         return ((uri.substring(0,6) == "news:/") || (uri.substring(0,14) == "news_message:/"));
  243.     }
  244. }
  245.  
  246. function RerootFolder(uri, newFolder, viewType, viewFlags, sortType, sortOrder)
  247. {
  248.   //dump("In reroot folder, sortType = " +  sortType + "\n");
  249.  
  250.   // workaround for #39655
  251.   gFolderJustSwitched = true;
  252.  
  253.   ClearThreadPaneSelection();
  254.  
  255.   //Clear the new messages of the old folder
  256.   var oldFolder = msgWindow.openFolder;
  257.   if (oldFolder) {
  258.     if (oldFolder.hasNewMessages) {
  259.       oldFolder.clearNewMessages();
  260.     }
  261.   }
  262.  
  263.   //Set the window's new open folder.
  264.   msgWindow.openFolder = newFolder;
  265.  
  266.   SetViewFlags(viewFlags);
  267.  
  268.   //the new folder being selected should have its biff state get cleared.
  269.   if(newFolder)
  270.   {
  271.     newFolder.biffState =
  272.           Components.interfaces.nsIMsgFolder.nsMsgBiffState_NoMail;
  273.   }
  274.  
  275.   //Clear out the thread pane so that we can sort it with the new sort id without taking any time.
  276.   // folder.setAttribute('ref', "");
  277.   // show "Lines" for news, "Size" for mail
  278.   SetNewsFolderColumns(isNewsURI(uri));
  279.  
  280.   // null this out, so we don't try sort.
  281.   if (gDBView) {
  282.     gDBView.close();
  283.     gDBView = null;
  284.   }
  285.  
  286.   // if this is the drafts, sent, or send later folder,
  287.   // we show "Recipient" instead of "Author"
  288.   SetSentFolderColumns(IsSpecialFolder(newFolder, MSG_FOLDER_FLAG_SENTMAIL | MSG_FOLDER_FLAG_DRAFTS | MSG_FOLDER_FLAG_QUEUE));
  289.  
  290.   // now create the db view, which will sort it.
  291.   CreateDBView(newFolder, viewType, viewFlags, sortType, sortOrder);
  292.   // that should have initialized gDBView, now re-root the thread pane
  293.   var outlinerView = gDBView.QueryInterface(Components.interfaces.nsIOutlinerView);
  294.   if (outlinerView)
  295.   {
  296.     var outliner = GetThreadOutliner();
  297.     outliner.boxObject.QueryInterface(Components.interfaces.nsIOutlinerBoxObject).view = outlinerView;
  298.   }
  299.  
  300.   SetUpToolbarButtons(uri);
  301.   UpdateStatusMessageCounts(newFolder);
  302. }
  303.  
  304. function SwitchView(command)
  305. {
  306.   var oldSortType = gDBView ? gDBView.sortType : nsMsgViewSortType.byThread;
  307.   var oldSortOrder = gDBView ? gDBView.sortOrder : nsMsgViewSortOrder.ascending;
  308.   var viewFlags = gCurViewFlags;
  309.  
  310.   // close existing view.
  311.   if (gDBView) {
  312.     gDBView.close();
  313.     gDBView = null; 
  314.   }
  315.  
  316.   switch(command)
  317.   {
  318.     case "cmd_viewUnreadMsgs":
  319.  
  320.       viewFlags = viewFlags | nsMsgViewFlagsType.kUnreadOnly;
  321.       CreateDBView(msgWindow.openFolder, nsMsgViewType.eShowAllThreads, viewFlags,
  322.             oldSortType, oldSortOrder );
  323.     break;
  324.     case "cmd_viewAllMsgs":
  325.       viewFlags = viewFlags & ~nsMsgViewFlagsType.kUnreadOnly;
  326.       CreateDBView(msgWindow.openFolder, nsMsgViewType.eShowAllThreads, viewFlags,
  327.             oldSortType, oldSortOrder);
  328.     break;
  329.     case "cmd_viewThreadsWithUnread":
  330.       CreateDBView(msgWindow.openFolder, nsMsgViewType.eShowThreadsWithUnread, nsMsgViewFlagsType.kThreadedDisplay,
  331.             nsMsgViewSortType.byThread, oldSortOrder);
  332.  
  333.     break;
  334.     case "cmd_viewWatchedThreadsWithUnread":
  335.       CreateDBView(msgWindow.openFolder, nsMsgViewType.eShowWatchedThreadsWithUnread, nsMsgViewFlagsType.kThreadedDisplay,
  336.             nsMsgViewSortType.byThread, oldSortOrder);
  337.    break;
  338.     case "cmd_viewIgnoredThreads":
  339.       if (viewFlags & nsMsgViewFlagsType.kShowIgnored)
  340.         viewFlags = viewFlags & ~nsMsgViewFlagsType.kShowIgnored;
  341.       else
  342.         viewFlags = viewFlags | nsMsgViewFlagsType.kShowIgnored;
  343.       CreateDBView(msgWindow.openFolder, nsMsgViewType.eShowAllThreads, viewFlags,
  344.             oldSortType, oldSortOrder);
  345.     break;
  346.   }
  347.  
  348.   // that should have initialized gDBView, now re-root the thread pane
  349.   var outlinerView = gDBView.QueryInterface(Components.interfaces.nsIOutlinerView);
  350.   if (outlinerView)
  351.   {
  352.     var outliner = GetThreadOutliner();
  353.     outliner.boxObject.QueryInterface(Components.interfaces.nsIOutlinerBoxObject).view = outlinerView;
  354.   }
  355. }
  356.  
  357. function SetSentFolderColumns(isSentFolder)
  358. {
  359.   var senderOrRecipientColumn = document.getElementById("senderOrRecipientCol");
  360.  
  361.   if(isSentFolder)
  362.   {
  363.     senderOrRecipientColumn.setAttribute("label", gMessengerBundle.getString("recipientColumnHeader"));
  364.   }
  365.   else
  366.   {
  367.     senderOrRecipientColumn.setAttribute("label", gMessengerBundle.getString("senderColumnHeader"));
  368.   }
  369. }
  370.  
  371. function SetNewsFolderColumns(isNewsFolder)
  372. {
  373.   var sizeColumn = document.getElementById("sizeCol");
  374.  
  375.   if (isNewsFolder) {
  376.      sizeColumn.setAttribute("label",gMessengerBundle.getString("linesColumnHeader"));
  377.   }
  378.   else {
  379.      sizeColumn.setAttribute("label", gMessengerBundle.getString("sizeColumnHeader"));
  380.   }
  381. }
  382.  
  383. function UpdateStatusMessageCounts(folder)
  384. {
  385.   var unreadElement = GetUnreadCountElement();
  386.   var totalElement = GetTotalCountElement();
  387.   if(folder && unreadElement && totalElement)
  388.   {
  389.     var numUnread =
  390.             gMessengerBundle.getFormattedString("unreadMsgStatus",
  391.                                                 [ folder.getNumUnread(false)]);
  392.     var numTotal =
  393.             gMessengerBundle.getFormattedString("totalMsgStatus",
  394.                                                 [folder.getTotalMessages(false)]);
  395.  
  396.     unreadElement.setAttribute("label", numUnread);
  397.     totalElement.setAttribute("label", numTotal);
  398.  
  399.   }
  400.  
  401. }
  402.  
  403. function ConvertColumnIDToSortType(columnID)
  404. {
  405.   var sortKey;
  406.  
  407.   switch (columnID) {
  408.     case "dateCol":
  409.       sortKey = nsMsgViewSortType.byDate;
  410.       break;
  411.     case "senderOrRecipientCol":
  412.       if (IsSpecialFolderSelected(MSG_FOLDER_FLAG_SENTMAIL | MSG_FOLDER_FLAG_DRAFTS | MSG_FOLDER_FLAG_QUEUE)) {
  413.           sortKey = nsMsgViewSortType.byRecipient;
  414.       }
  415.       else {
  416.           sortKey = nsMsgViewSortType.byAuthor;
  417.       }
  418.       break;
  419.     case "subjectCol":
  420.       sortKey = nsMsgViewSortType.bySubject;
  421.       break;
  422.     case "locationCol":
  423.       sortKey = nsMsgViewSortType.byLocation;
  424.       break;
  425.     case "unreadButtonColHeader":
  426.       sortKey = nsMsgViewSortType.byUnread;
  427.       break;
  428.     case "statusCol":
  429.       sortKey = nsMsgViewSortType.byStatus;
  430.       break;
  431.     case "sizeCol":
  432.       sortKey = nsMsgViewSortType.bySize;
  433.       break;
  434.     case "priorityCol":
  435.       sortKey = nsMsgViewSortType.byPriority;
  436.       break;
  437.     case "flaggedCol":
  438.       sortKey = nsMsgViewSortType.byFlagged;
  439.       break;
  440.     case "threadCol":
  441.       sortKey = nsMsgViewSortType.byThread;
  442.       break;
  443.     default:
  444.       dump("unsupported sort column: " + columnID + "\n");
  445.       sortKey = 0;
  446.       break;
  447.   }
  448.   return sortKey;
  449. }
  450.  
  451. function ConvertSortTypeToColumnID(sortKey)
  452. {
  453.   var columnID;
  454.  
  455.   // hack to turn this into an integer, if it was a string
  456.   // it would be a string if it came from localStore.rdf
  457.   sortKey = sortKey - 0;
  458.  
  459.   switch (sortKey) {
  460.     case nsMsgViewSortType.byDate:
  461.       columnID = "dateCol";
  462.       break;
  463.     case nsMsgViewSortType.byAuthor:
  464.     case nsMsgViewSortType.byRecipient:
  465.       columnID = "senderOrRecipientCol";
  466.       break;
  467.     case nsMsgViewSortType.bySubject:
  468.       columnID = "subjectCol";
  469.       break;
  470.     case nsMsgViewSortType.byLocation:
  471.       columnID = "locationCol";
  472.       break;
  473.     case nsMsgViewSortType.byUnread:
  474.       columnID = "unreadButtonColHeader";
  475.       break;
  476.     case nsMsgViewSortType.byStatus:
  477.       columnID = "statusCol";
  478.       break;
  479.     case nsMsgViewSortType.bySize:
  480.       columnID = "sizeCol";
  481.       break;
  482.     case nsMsgViewSortType.byPriority:
  483.       columnID = "priorityCol";
  484.       break;
  485.     case nsMsgViewSortType.byFlagged:
  486.       columnID = "flaggedCol";
  487.       break;
  488.     case nsMsgViewSortType.byThread:
  489.       columnID = "threadCol";
  490.       break;
  491.     case nsMsgViewSortType.byId:
  492.       // there is no orderReceivedCol, so return null
  493.       columnID = null;
  494.       break;
  495.     default:
  496.       dump("unsupported sort key: " + sortKey + "\n");
  497.       columnID = null;
  498.       break;
  499.   }
  500.   return columnID;
  501. }
  502.  
  503. var nsMsgViewSortType = Components.interfaces.nsMsgViewSortType;
  504. var nsMsgViewSortOrder = Components.interfaces.nsMsgViewSortOrder;
  505. var nsMsgViewFlagsType = Components.interfaces.nsMsgViewFlagsType;
  506. var nsMsgViewCommandType = Components.interfaces.nsMsgViewCommandType;
  507. var nsMsgViewType = Components.interfaces.nsMsgViewType;
  508. var nsMsgNavigationType = Components.interfaces.nsMsgNavigationType;
  509.  
  510. var gDBView = null;
  511. var gCurViewFlags;
  512. var gCurSortType;
  513.  
  514. // CreateDBView is called when we have a thread pane. CreateBareDBView is called when there is no
  515. // outliner associated with the view. CreateDBView will call into CreateBareDBView...
  516.  
  517. function CreateBareDBView(msgFolder, viewType, viewFlags, sortType, sortOrder)
  518. {
  519.   var dbviewContractId = "@mozilla.org/messenger/msgdbview;1?type=";
  520.  
  521.   // hack to turn this into an integer, if it was a string
  522.   // it would be a string if it came from localStore.rdf
  523.   viewType = viewType - 0;
  524.  
  525.   switch (viewType) {
  526.       case nsMsgViewType.eShowThreadsWithUnread:
  527.           dbviewContractId += "threadswithunread";
  528.           break;
  529.       case nsMsgViewType.eShowWatchedThreadsWithUnread:
  530.           dbviewContractId += "watchedthreadswithunread";
  531.           break;
  532.       case nsMsgViewType.eShowAllThreads:
  533.       default:
  534.           dbviewContractId += "threaded";
  535.           break;
  536.   }
  537.  
  538.   gDBView = Components.classes[dbviewContractId].createInstance(Components.interfaces.nsIMsgDBView);
  539.  
  540.   gCurViewFlags = viewFlags;
  541.   var count = new Object;
  542.   if (!gThreadPaneCommandUpdater)
  543.     gThreadPaneCommandUpdater = new nsMsgDBViewCommandUpdater();
  544.  
  545.   if ((sortType == nsMsgViewSortType.byAuthor) && IsSpecialFolder(msgFolder, MSG_FOLDER_FLAG_SENTMAIL | MSG_FOLDER_FLAG_DRAFTS | MSG_FOLDER_FLAG_QUEUE)) {
  546.     gCurSortType = nsMsgViewSortType.byRecipient;
  547.   }
  548.   else {
  549.     gCurSortType = sortType;
  550.   }
  551.  
  552.   gDBView.init(messenger, msgWindow, gThreadPaneCommandUpdater);
  553.   gDBView.open(msgFolder, gCurSortType, sortOrder, viewFlags, count);
  554. }
  555.  
  556. function CreateDBView(msgFolder, viewType, viewFlags, sortType, sortOrder)
  557. {
  558.   // call the inner create method
  559.   CreateBareDBView(msgFolder, viewType, viewFlags, sortType, sortOrder);
  560.  
  561.   // now do outliner specific work
  562.  
  563.   // based on the collapsed state of the thread pane/message pane splitter,
  564.   // supress message display if appropriate.
  565.   gDBView.supressMsgDisplay = IsThreadAndMessagePaneSplitterCollapsed();
  566.  
  567.   UpdateSortIndicators(gCurSortType, sortOrder);
  568. }
  569.  
  570. function SetViewFlags(viewFlags)
  571. {
  572.     if (!gDBView) return;
  573.     gDBView.viewFlags = viewFlags;
  574. }
  575.  
  576. //------------------------------------------------------------
  577. // Sets the column header sort icon based on the requested
  578. // column and direction.
  579. //
  580. // Notes:
  581. // (1) This function relies on the first part of the
  582. //     <treecell id> matching the <treecol id>.  The treecell
  583. //     id must have a "Header" suffix.
  584. // (2) By changing the "sortDirection" attribute, a different
  585. //     CSS style will be used, thus changing the icon based on
  586. //     the "sortDirection" parameter.
  587. //------------------------------------------------------------
  588. function UpdateSortIndicator(column,sortDirection)
  589. {
  590.   // this is obsolete
  591. }
  592.  
  593. function SortFolderPane(column)
  594. {
  595.   var node = FindInSidebar(window, column);
  596.   if(!node)
  597.   {
  598.     dump('Couldnt find sort column\n');
  599.     return false;
  600.   }
  601.  
  602.   try 
  603.   {
  604.     var folderOutliner = GetFolderOutliner();
  605.     folderOutliner.outlinerBoxObject.view.cycleHeader(column, node);
  606.   }
  607.   catch (ex) 
  608.   {
  609.     dump("failed to cycle header: " + ex + "\n");
  610.   }
  611. }
  612.  
  613. function GetSelectedFolderResource()
  614. {
  615.     var folderOutliner = GetFolderOutliner();
  616.     var startIndex = {};
  617.     var endIndex = {};
  618.     folderOutliner.outlinerBoxObject.selection.getRangeAt(0, startIndex, endIndex);
  619.     return GetFolderResource(folderOutliner, startIndex.value);
  620. }
  621.  
  622. function OnMouseUpThreadAndMessagePaneSplitter()
  623.   {
  624.   if (gDBView) {
  625.     // the collapsed state is the state after we released the mouse 
  626.     // so we take it as it is
  627.     gDBView.supressMsgDisplay = IsThreadAndMessagePaneSplitterCollapsed();
  628.   }
  629.   }
  630.  
  631. function OnClickThreadAndMessagePaneSplitterGrippy()
  632.   {
  633.   if (gDBView) {
  634.     // the collapsed state is the state when we clicked on the grippy
  635.     // not when afterwards, so we need to reverse this value
  636.     gDBView.supressMsgDisplay = !IsThreadAndMessagePaneSplitterCollapsed();
  637.    }
  638. }
  639.  
  640. function FolderPaneSelectionChange()
  641. {
  642.     var folderOutliner = GetFolderOutliner();
  643.     if (folderOutliner.outlinerBoxObject.selection.count == 1)
  644.     {
  645.         var startIndex = {};
  646.         var endIndex = {};
  647.         folderOutliner.outlinerBoxObject.selection.getRangeAt(0, startIndex, endIndex);
  648.         var folderResource = GetFolderResource(folderOutliner, startIndex.value);
  649.         var msgFolder = folderResource.QueryInterface(Components.interfaces.nsIMsgFolder);
  650.         if (msgFolder == msgWindow.openFolder)
  651.             return;
  652.         else
  653.         {
  654.             var sortType = 0;
  655.             var sortOrder = 0;
  656.             var viewFlags = 0;
  657.             var viewType = 0;
  658.  
  659.             // don't get the db if this folder is a server
  660.             // we're going to be display account central
  661.             if (!(msgFolder.isServer)) 
  662.             {
  663.               try 
  664.               {
  665.                 var msgDatabase = msgFolder.getMsgDatabase(msgWindow);
  666.                 if (msgDatabase)
  667.                 {
  668.                   var dbFolderInfo = msgDatabase.dBFolderInfo;
  669.                   sortType = dbFolderInfo.sortType;
  670.                   sortOrder = dbFolderInfo.sortOrder;
  671.                   viewFlags = dbFolderInfo.viewFlags;
  672.                   viewType = dbFolderInfo.viewType;
  673.                 }
  674.               }
  675.               catch (ex)
  676.               {
  677.                 dump("failed to get view & sort values.  ex = " + ex +"\n");
  678.               }
  679.             }
  680.             ChangeFolderByURI(folderResource.Value, viewType, viewFlags, sortType, sortOrder);
  681.         }
  682.     }
  683.     else
  684.     {
  685.         msgWindow.openFolder = null;
  686.         ClearThreadPane();
  687.     }
  688.  
  689.     if (! gAccountCentralLoaded)
  690.         ClearMessagePane();
  691.  
  692.     if (gDisplayStartupPage)
  693.     {
  694.         loadStartPage();
  695.         gDisplayStartupPage = false;
  696.     }
  697. }
  698.  
  699. function ClearThreadPane()
  700. {
  701.   if (gDBView) {
  702.     gDBView.close();
  703.     gDBView = null; 
  704.   }
  705. }
  706.  
  707. function IsSpecialFolder(msgFolder, flags)
  708. {
  709.     if (!msgFolder) {
  710.         return false;
  711.     }
  712.     else if ((msgFolder.flags & flags) == 0) {
  713.         var folder = msgFolder.QueryInterface(Components.interfaces.nsIFolder);
  714.  
  715.         if (folder && folder.parent) {
  716.             var parentMsgFolder = folder.parent.QueryInterface(Components.interfaces.nsIMsgFolder);
  717.  
  718.             if(!parentMsgFolder) {
  719.                 return false;
  720.             }
  721.  
  722.             return IsSpecialFolder(parentMsgFolder, flags);
  723.         }
  724.         else {
  725.             return false;
  726.         }
  727.     }
  728.     else {
  729.         // the user can set their INBOX to be their SENT folder.
  730.         // in that case, we want this folder to act like an INBOX, 
  731.         // and not a SENT folder
  732.         if ((flags & MSG_FOLDER_FLAG_SENTMAIL) && (msgFolder.flags & MSG_FOLDER_FLAG_INBOX)) {
  733.           return false;
  734.         }
  735.         else {
  736.           return true;
  737.         }
  738.     }
  739. }
  740.  
  741. function SelectNextMessage(nextMessage)
  742. {
  743.     dump("XXX implement SelectNextMessage()\n");
  744. }
  745.  
  746. function GetSelectTrashUri(folder)
  747. {
  748.     if (!folder) return null;
  749.     var uri = folder.getAttribute('id');
  750.     var resource = RDF.GetResource(uri);
  751.     var msgFolder =
  752.         resource.QueryInterface(Components.interfaces.nsIMsgFolder);
  753.     if (msgFolder)
  754.     {
  755.         var rootFolder = msgFolder.rootFolder;
  756.         var numFolder;
  757.         var out = new Object();
  758.         var trashFolder = rootFolder.getFoldersWithFlag(MSG_FOLDER_FLAG_TRASH, 1, out);
  759.         numFolder = out.value;
  760.         if (trashFolder) {
  761.             return trashFolder.URI;
  762.         }
  763.     }
  764.     return null;
  765. }
  766.  
  767. function Undo()
  768. {
  769.     messenger.Undo(msgWindow);
  770. }
  771.  
  772. function Redo()
  773. {
  774.     messenger.Redo(msgWindow);
  775. }
  776. var mailOfflineObserver = {
  777.   Observe: function(subject, topic, state) {
  778.     // sanity checks
  779.     if (topic != "network:offline-status-changed") return;
  780.     MailOfflineStateChanged(state == "offline");
  781.   }
  782. }
  783.  
  784. function AddMailOfflineObserver() 
  785. {
  786.   var observerService = Components.classes["@mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService); 
  787.   observerService.AddObserver(mailOfflineObserver, "network:offline-status-changed");
  788. }
  789.  
  790. function RemoveMailOfflineObserver()
  791. {
  792.   var observerService = Components.classes["@mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService); 
  793.   observerService.RemoveObserver(mailOfflineObserver,"network:offline-status-changed");
  794. }
  795.  
  796.