home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / winfe / thrdfrm.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  52.8 KB  |  1,957 lines

  1. /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  *
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  *
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18.  
  19. #include "stdafx.h"
  20. #include "prefapi.h"
  21. #include "msgcom.h"
  22. #include "intl_csi.h"
  23. #include "feutil.h"
  24. #include "netsvw.h"
  25. #include "fldrfrm.h"
  26. #include "thrdfrm.h"
  27. #include "srchfrm.h"
  28. #include "msgfrm.h"
  29. #include "wfemsg.h"
  30. #include "msgview.h"
  31. #include "filter.h"
  32. #include "mailmisc.h"
  33. #include "template.h"
  34. #include "custom.h"
  35. #include "subnews.h"
  36. #include "mailpriv.h"
  37. #include "mailqf.h"
  38. #include "dspppage.h"
  39.  
  40. #ifdef DEBUG_WHITEBOX
  41. #include "qa.h"
  42. #endif 
  43.  
  44.  
  45. #ifndef _AFXDLL
  46. #undef new
  47. #endif
  48. IMPLEMENT_DYNCREATE(C3PaneMailFrame, CMsgListFrame)
  49. #ifndef _AFXDLL
  50. #define new DEBUG_NEW
  51. #endif
  52.  
  53. #ifdef _DEBUG
  54. #undef THIS_FILE
  55. static char BASED_CODE THIS_FILE[] = __FILE__;
  56. #endif
  57.  
  58. static C3PaneMailFrame *g_pLast3PaneMailFrame = NULL;
  59.  
  60. ///////////////////////////////////////////////////////////////////////////
  61. // C3PaneMailFrame
  62.  
  63. static BOOL s_bHintNews = FALSE;
  64. static BOOL s_bGetMail = FALSE;
  65.  
  66. UINT MailCodes[10] = {
  67.     ID_FILE_GETNEWMAIL,
  68.     ID_FILE_NEWMESSAGE,
  69.     ID_MESSAGE_REPLYBUTTON,
  70.     ID_MESSAGE_FORWARD,
  71.     ID_MESSAGE_FILE,
  72.     ID_MESSAGE_NEXTUNREAD,
  73.     ID_FILE_PRINT,
  74.     ID_SECURITY,
  75.     ID_EDIT_DELETEMESSAGE,
  76.     ID_NAVIGATE_INTERRUPT
  77. };
  78.  
  79. int MailIndices[10] = { 0, 1, 2, 3, 4, 5, 6, 10, 11, 13 };
  80.  
  81. UINT NewsCodes[10] = {
  82.     ID_FILE_GETNEWMAIL,
  83.     ID_NEWS_POSTNEW,
  84.     ID_MESSAGE_REPLYBUTTON,
  85.     ID_MESSAGE_FORWARD,
  86.     ID_MESSAGE_FILE,
  87.     ID_MESSAGE_NEXTUNREAD,
  88.     ID_FILE_PRINT,
  89.     ID_SECURITY,
  90.     ID_MESSAGE_MARKBUTTON,
  91.     ID_NAVIGATE_INTERRUPT
  92. };
  93.  
  94. int NewsIndices[10] = { 0, 1, 2, 3, 4, 5, 6, 10, 11, 13 };
  95.  
  96. //status bar format
  97. static const UINT BASED_CODE indicators[] =
  98. {
  99.     IDS_EXPANDO,
  100.     IDS_SECURITY_STATUS,
  101.     IDS_SIGNED_STATUS,
  102.     IDS_TRANSFER_STATUS,    
  103.     ID_SEPARATOR,
  104.     IDS_TASKBAR
  105. };
  106.  
  107. C3PaneMailFrame::C3PaneMailFrame()
  108. {
  109.     m_bNews = FALSE;
  110.     m_bWantToGetMail = FALSE;
  111.     m_pMessagePane = NULL;
  112.     m_pOutlinerParent = NULL;
  113.     m_pFolderPane = NULL;
  114.     m_pFolderOutliner = NULL;
  115.     m_pFolderOutlinerParent = NULL;
  116.     m_pFolderSplitter = NULL;
  117.     m_pThreadSplitter = NULL;
  118.     m_nLoadingFolder = 0;
  119.     m_bDragCopying = FALSE;
  120.  
  121.     m_bNoScrollHack = FALSE;
  122.  
  123.    // All our favorite hotkeys
  124.    LoadAccelerators( IDR_ONEKEYMESSAGE );
  125. }
  126.  
  127. C3PaneMailFrame::~C3PaneMailFrame()
  128. {
  129.     delete m_pOutlinerParent;
  130.     delete m_pFolderOutlinerParent;
  131. }
  132.  
  133. void C3PaneMailFrame::UIForFolder( MSG_FolderInfo *folderInfo )
  134. {
  135.     MSG_FolderLine folderLine;
  136.     if (MSG_GetFolderLineById(WFE_MSGGetMaster(), folderInfo, &folderLine)) {
  137.  
  138.         SetIsNews( folderLine.flags & MSG_FOLDER_FLAG_NEWSGROUP ? TRUE : FALSE );
  139.  
  140.         MSG_FolderInfo *parentFolder = folderInfo;
  141.                                     
  142.         int16 doc_csid = MSG_GetFolderCSID( parentFolder );
  143.         if (!doc_csid)
  144.             doc_csid = INTL_DefaultWinCharSetID(0);
  145.  
  146.         RefreshNewEncoding( doc_csid, FALSE );
  147.  
  148.         CString csFullString, csTitle, cs;
  149.         if ( m_bNews ) {
  150.             csFullString.LoadString( IDR_NEWSTHREAD );
  151.         } else {
  152.             csFullString.LoadString( IDR_MAILTHREAD );
  153.         }
  154.  
  155.         AfxExtractSubString( csTitle, csFullString, 0 );
  156.  
  157.         cs = folderLine.prettyName && folderLine.prettyName[0] ? 
  158.              folderLine.prettyName :
  159.              folderLine.name;
  160.  
  161.         cs += _T(" - ");
  162.         cs += csTitle;
  163.         m_pChrome->SetWindowTitle(cs);
  164.  
  165.         m_pInfoBar->Update();
  166.  
  167.         // Refresh the headers, which may change
  168.         if ( m_pOutliner )
  169.             m_pOutliner->GetParent()->Invalidate();
  170.  
  171.         UpdateFolderPane(folderInfo);
  172.     }
  173. }
  174.  
  175. void C3PaneMailFrame::PaneChanged( MSG_Pane *pane, XP_Bool asynchronous, 
  176.                                 MSG_PANE_CHANGED_NOTIFY_CODE notify, int32 value)
  177. {
  178.     if ( pane ==m_pFolderPane && notify == MSG_PaneNotifySelectNewFolder ) {
  179.         if ( value >= 0 ) {
  180.             m_pFolderOutliner->SelectItem( CASTINT(value) );
  181.         }
  182.         return;
  183.     }
  184.     if ( notify == MSG_PaneNotifyFolderLoaded ) {
  185.  
  186.         if (m_nLoadingFolder > 0) {
  187.             // This load was initiated through our LoadFolder method
  188.             m_pOutliner->BlockSelNotify(FALSE);
  189.             m_nLoadingFolder--;
  190.         }
  191.         else
  192.             return; // must be blocked by select top level host
  193.  
  194.         // Update the UI
  195.         MSG_FolderInfo *folderInfo = MSG_GetCurFolder( m_pPane );
  196.  
  197.         UIForFolder( folderInfo );
  198.  
  199.         // Safety Dance
  200.         m_pOutliner->SetTotalLines( (int) MSG_GetNumLines( m_pPane ) );
  201.         m_pOutliner->Invalidate();
  202.  
  203.         // Select something based on previously set hints.
  204.  
  205.         switch ( m_actionOnLoad ) {
  206.         case actionSelectFirst: 
  207.             {
  208.                 m_pOutliner->SelectItem( m_pOutliner->GetTotalLines() > 0 ? 0 : -1 );
  209.                 m_bNoScrollHack = TRUE;
  210.                 OnDoneGettingMail();
  211.             }
  212.             break;
  213.  
  214.         case actionSelectKey:
  215.             SelectMessage( m_selPending );
  216.             break;
  217.  
  218.         case actionNavigation:
  219.             switch ( m_navPending ) {
  220.             case MSG_Forward:
  221.             case MSG_Back:
  222.             case MSG_EditUndo:
  223.             case MSG_EditRedo:
  224.                 SelectMessage( m_selPending );
  225.                 break;
  226.  
  227.             case MSG_NextFolder:
  228.             case MSG_NextMessage:
  229.                 m_pOutliner->SelectItem( -1 );
  230.                 DoNavigate(MSG_FirstMessage);
  231.                 break;
  232.  
  233.             case MSG_NextUnreadMessage:
  234.             case MSG_NextUnreadThread:
  235.             case MSG_NextUnreadGroup:
  236.             case MSG_LaterMessage:
  237.                 m_navPending = MSG_NextUnreadMessage;
  238.  
  239.             default:
  240.                 m_pOutliner->SelectItem( -1 );
  241.                 DoNavigate( m_navPending );
  242.                 break;
  243.             }
  244.             break;
  245.  
  246.         case actionNone:
  247.             break;
  248.  
  249.         }
  250.         // Sort might have changed, redraw column headers
  251.         m_pOutliner->GetParent()->Invalidate();
  252.  
  253.         m_actionOnLoad = actionSelectFirst;
  254.  
  255.         if (m_bWantToGetMail && !NET_IsOffline() &&
  256.             !MSG_GetMailServerIsIMAP4(g_MsgPrefs.m_pMsgPrefs)) {
  257.             PostMessage(WM_COMMAND, (WPARAM) ID_FILE_GETNEWMAIL, (LPARAM) 0);
  258.         }
  259.         m_bWantToGetMail = FALSE;
  260.     } else if ( notify == MSG_PaneNotifyFolderDeleted ) {
  261.         OnSelectFolder();
  262.     } else if ( notify == MSG_PaneNotifyMessageLoaded ) {
  263.         MSG_FolderInfo *curFolder = GetCurFolder();
  264.         MSG_FolderInfo *folderInfo = MSG_GetCurFolder(m_pMessagePane);
  265.         MessageKey key = (MessageKey) value;
  266.  
  267.         if (folderInfo != curFolder) {
  268.             C3PaneMailFrame::Open(folderInfo, key);
  269.         } else {
  270.             MSG_ViewIndex index = MSG_GetMessageIndexForKey(m_pPane, key, TRUE);
  271.  
  272.             if (index != MSG_VIEWINDEXNONE) {
  273.                 m_pOutliner->BlockSelNotify(TRUE); // Tail don't wag dog
  274.                 m_pOutliner->SelectItem(CASTINT(index));
  275.                 m_pOutliner->BlockSelNotify(FALSE);
  276.             }
  277.         }
  278.         if (MSG_GetBacktrackState(m_pPane) == MSG_BacktrackIdle)
  279.             MSG_AddBacktrackMessage(m_pPane, folderInfo, key);
  280.         else
  281.             MSG_SetBacktrackState(m_pPane, MSG_BacktrackIdle);
  282.     } else if ( notify == MSG_PaneNotifyCopyFinished && m_bDragCopying) {
  283.         // Allow the UI to update and be interacted with
  284.         m_pOutliner->BlockSelNotify(FALSE);
  285.         m_bDragCopying = FALSE;
  286.         // Post message to allow BE to return first.
  287.         PostMessage(WM_COMMAND, (WPARAM) ID_MESSAGE_SELECT, 0);
  288.     }
  289.     // We get notified of message deletes individually, so lets
  290.     // ignore it.
  291.     if ( notify != MSG_PaneNotifyMessageDeleted ) {
  292.         m_pInfoBar->Update();
  293.     }
  294. #ifdef DEBUG_WHITEBOX
  295.     if ( notify == MSG_PaneNotifyMessageLoaded ) // previous MSG_PaneNotifyMessageLoaded 
  296.     {
  297.         bWaitForInbox = FALSE;
  298.     }
  299.     if ( notify == MSG_PaneNotifyMessageDeleted) 
  300.     {
  301.         QADoDeleteMessageEventHandler2();
  302.     }
  303.  
  304. #endif
  305. }
  306.  
  307. void C3PaneMailFrame::ListChangeStarting( MSG_Pane* pane, XP_Bool asynchronous,
  308.                                         MSG_NOTIFY_CODE notify, MSG_ViewIndex where,
  309.                                         int32 num)
  310. {
  311.     if ( pane == m_pFolderPane ) {
  312.         if ( m_pFolderOutliner ) {
  313.             m_pFolderOutliner->MysticStuffStarting( asynchronous, notify,
  314.                                                    where, num );
  315.         }
  316.     } else {
  317.         CMsgListFrame::ListChangeStarting( pane, asynchronous, notify,
  318.                                            where, num );
  319.     }
  320. }
  321.  
  322. void C3PaneMailFrame::ListChangeFinished( MSG_Pane* pane, XP_Bool asynchronous,
  323.                                         MSG_NOTIFY_CODE notify, MSG_ViewIndex where,
  324.                                         int32 num)
  325. {
  326.     if ( pane == m_pFolderPane ) {
  327.         if ( m_pFolderOutliner ) {
  328.             m_pFolderOutliner->MysticStuffFinishing( asynchronous, notify,
  329.                                                    where, num );
  330.         }
  331.     } else {
  332.         CMsgListFrame::ListChangeFinished( pane, asynchronous, notify,
  333.                                            where, num );
  334.     }
  335. }
  336.  
  337. void C3PaneMailFrame::CopyMessagesInto( MSG_Pane *pane, MSG_ViewIndex *indices, int count,
  338.                                      MSG_FolderInfo *folderInfo)
  339. {
  340.     ASSERT(pane);
  341.     m_bDragCopying = TRUE;
  342.     m_pOutliner->BlockSelNotify(TRUE);
  343.     MSG_CopyMessagesIntoFolder(pane, indices, count, folderInfo);
  344. }
  345.  
  346. void C3PaneMailFrame::MoveMessagesInto( MSG_Pane *pane, MSG_ViewIndex *indices, int count,
  347.                                      MSG_FolderInfo *folderInfo)
  348. {
  349.     ASSERT(pane);
  350.     m_bDragCopying = TRUE;
  351.     m_pOutliner->BlockSelNotify(TRUE);
  352.     MSG_FolderLine folderLine;
  353.     MSG_GetFolderLineById( WFE_MSGGetMaster(), GetCurFolder(), &folderLine );
  354.  
  355.     // We want to make file behave for newsgroups
  356.     if ( folderLine.flags & MSG_FOLDER_FLAG_NEWSGROUP ) {
  357.         MSG_CopyMessagesIntoFolder(pane, indices, count, folderInfo);
  358.     } else {
  359.         MSG_MoveMessagesIntoFolder(pane, indices, count, folderInfo);
  360.     }
  361. }
  362.  
  363. void C3PaneMailFrame::GetSelection( MSG_Pane* pane, MSG_ViewIndex **indices, int *count, 
  364.                                   int *focus)
  365. {
  366.     if ( pane == m_pFolderPane ) {
  367.         if ( m_pFolderOutliner ) {
  368.             m_pFolderOutliner->GetSelection(*indices, *count);
  369.             *focus = m_pFolderOutliner->GetFocusLine();
  370.         }
  371.     } else {
  372.         CMsgListFrame::GetSelection( pane, indices, count, focus );
  373.     }
  374. }
  375.  
  376. void C3PaneMailFrame::SelectItem( MSG_Pane* pane, int item )
  377. {
  378.     if ( pane == m_pFolderPane ) {
  379.         if ( m_pFolderOutliner ) {
  380.             m_pFolderOutliner->SelectItem(item);
  381.             m_pFolderOutliner->ScrollIntoView(item);
  382.         }
  383.     } else {
  384.         CMsgListFrame::SelectItem( pane, item );
  385.     }
  386. }
  387.  
  388. #define IS_IN_WINDOW(hParent,hChild)\
  389.     (((hParent) == (hChild)) || ::IsChild(hParent, hChild))
  390.  
  391. BOOL C3PaneMailFrame::PreTranslateMessage(MSG* pMsg)
  392. {
  393.     if ( pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_DELETE)
  394.     {
  395.         CWnd* pFocusWnd = GetFocus();
  396.         if (pFocusWnd == m_pFolderOutliner)
  397.             OnDeleteFolder();
  398.         else 
  399.         {
  400.             if (GetKeyState(VK_SHIFT) & 0x8000)
  401.                 OnReallyDeleteMessage();
  402.             else
  403.                 OnDeleteMessage();
  404.         }
  405.         return TRUE;
  406.     }
  407.     if ( pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_TAB && 
  408.          !(GetKeyState(VK_MENU) & 0x8000) && 
  409.          !(GetKeyState(VK_CONTROL) & 0x8000)) { 
  410.         HWND hwndFocus = ::GetFocus();
  411.  
  412.         HWND hwndFolder = m_pFolderOutliner ? m_pFolderOutliner->m_hWnd : NULL;
  413.         HWND hwndOutliner = m_pOutliner ? m_pOutliner->m_hWnd : NULL;
  414.         HWND hwndView = m_pMessageView ? m_pMessageView->m_hWnd : NULL;
  415.  
  416.         HWND hwndNext = NULL;
  417.  
  418.         if (GetKeyState(VK_SHIFT) & 0x8000) {
  419.             if ( hwndView && IS_IN_WINDOW(hwndView, hwndFocus) ) {
  420.                 // Don't steal the event if the tab is destined for a child window of
  421.                 // the active view, because the child window may want the tab itself
  422.                 hwndNext = hwndOutliner;
  423.             } else if ( hwndFocus == hwndOutliner ) {
  424.                 hwndNext = hwndFolder;
  425.             } else { // hwndFocus == hwndFolder
  426.                 hwndNext = hwndView;
  427.             }
  428.         } else {
  429.             if ( hwndView && IS_IN_WINDOW(hwndView, hwndFocus) ) {
  430.                 // Don't steal the event if the tab is destined for a child window of
  431.                 // the active view, because the child window may want the tab itself
  432.                 hwndNext = hwndFolder;
  433.             } else if ( hwndFocus == hwndFolder ) {
  434.                 hwndNext = hwndOutliner;
  435.             } else { // hwndFocus == hwndOutliner
  436.                 hwndNext = hwndView;
  437.             }
  438.         }
  439.  
  440.         if ( hwndNext ) {
  441.             ::SetFocus( hwndNext );
  442.             return TRUE;
  443.         }
  444.     }
  445.  
  446.     return CMsgListFrame::PreTranslateMessage( pMsg );
  447. }
  448.  
  449. BOOL C3PaneMailFrame::OnCreateClient( LPCREATESTRUCT lpcs, CCreateContext* pContext )
  450. {
  451.     BOOL res = CMsgListFrame::OnCreateClient(lpcs, pContext);
  452.     if (res) {
  453.         m_pMaster = WFE_MSGGetMaster();
  454.         m_bNews = s_bHintNews;
  455.  
  456.         m_pFolderSplitter = DYNAMIC_DOWNCAST(CMailNewsSplitter, GetDescendantWindow(AFX_IDW_PANE_FIRST, TRUE));
  457.         ASSERT(m_pFolderSplitter);
  458.  
  459. #ifdef _WIN32
  460.         m_pFolderSplitter->ModifyStyleEx(WS_EX_CLIENTEDGE, 0, SWP_FRAMECHANGED);
  461. #endif
  462.  
  463.         m_pThreadSplitter = (CMailNewsSplitter *) RUNTIME_CLASS(CMailNewsSplitter)->CreateObject();
  464.         ASSERT(m_pThreadSplitter); 
  465.  
  466. #ifdef _WIN32
  467.         m_pThreadSplitter->CreateEx(0, NULL, NULL,
  468.                                   WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS,
  469.                                   0,0,0,0, m_pFolderSplitter->m_hWnd, (HMENU)99, NULL );
  470. #else
  471.         m_pThreadSplitter->Create( NULL, NULL,
  472.                                  WS_BORDER|WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS,
  473.                                  CRect(0,0,0,0), m_pFolderSplitter, 99, pContext ); 
  474. #endif
  475.  
  476.         m_pMessageView = (CMessageView *) RUNTIME_CLASS(CMessageView)->CreateObject();
  477. #ifdef _WIN32
  478.         if (sysInfo.m_bWin4)
  479.             m_pMessageView->CreateEx( WS_EX_CLIENTEDGE, NULL, NULL, 
  480.                                       WS_CHILD|WS_VISIBLE|WS_CLIPCHILDREN|WS_CLIPSIBLINGS,
  481.                                       0,0,0,0, m_pThreadSplitter->m_hWnd, (HMENU) IDW_MESSAGE_VIEW, pContext );
  482.         else
  483. #endif
  484.             m_pMessageView->Create( NULL, NULL, 
  485.                                     WS_BORDER|WS_CHILD|WS_VISIBLE|WS_CLIPCHILDREN|WS_CLIPSIBLINGS,
  486.                                     CRect(0,0,0,0), m_pThreadSplitter, IDW_MESSAGE_VIEW, pContext );
  487.  
  488.         m_pMessageView->SendMessage(WM_INITIALUPDATE);
  489.  
  490.         CWnd *pView = GetDescendantWindow(IDW_MESSAGE_PANE, TRUE);
  491.         ASSERT(pView);
  492.         CWinCX *pWinCX;
  493.  
  494.         pWinCX = new CWinCX(DYNAMIC_DOWNCAST(CGenericDoc, pContext->m_pCurrentDoc), 
  495.                             this, (CGenericView *)pView);
  496.  
  497.         SetMainContext(pWinCX);
  498.         SetActiveContext(pWinCX);
  499.  
  500.         RECT rect;
  501.         GetClientRect(&rect);
  502.         pWinCX->Initialize(FALSE, &rect);
  503.         pWinCX->GetContext()->type = MWContextMail;
  504.         pWinCX->GetContext()->fancyFTP = TRUE;
  505.         pWinCX->GetContext()->fancyNews = TRUE;
  506.         pWinCX->GetContext()->intrupt = FALSE;
  507.         pWinCX->GetContext()->reSize = FALSE;
  508.                 
  509.         m_pOutlinerParent = new CMessageOutlinerParent;
  510. #ifdef _WIN32
  511.         m_pOutlinerParent->CreateEx(WS_EX_CLIENTEDGE, NULL, NULL,
  512.                                   WS_CHILD|WS_VISIBLE|WS_CLIPCHILDREN|WS_CLIPSIBLINGS,
  513.                                   0,0,0,0, m_pThreadSplitter->m_hWnd, (HMENU) IDW_THREAD_PANE, NULL );
  514. #else
  515.         m_pOutlinerParent->Create( NULL, NULL,
  516.                                  WS_BORDER|WS_CHILD|WS_VISIBLE|WS_CLIPCHILDREN|WS_CLIPSIBLINGS,
  517.                                  CRect(0,0,0,0), m_pThreadSplitter, IDW_THREAD_PANE );
  518. #endif
  519.         m_pOutlinerParent->EnableFocusFrame(TRUE);
  520.         CreateFolderOutliner();
  521.  
  522.         m_pOutliner = DOWNCAST(CMailNewsOutliner, m_pOutlinerParent->m_pOutliner);
  523.         DOWNCAST(CMessageOutliner, m_pOutliner)->SetNews(m_bNews);
  524.         m_pOutlinerParent->CreateColumns ( );
  525.  
  526.         m_pMessagePane = MSG_CreateMessagePane( pWinCX->GetContext(), m_pMaster );
  527.  
  528.         int32 prefInt = -1;
  529.         PREF_GetIntPref("mailnews.3pane_thread_height", &prefInt);
  530.         m_pThreadSplitter->AddPanes(m_pOutlinerParent, m_pMessageView, prefInt, FALSE);
  531.  
  532.         prefInt = -1;
  533.         PREF_GetIntPref("mailnews.3pane_folder_width", &prefInt);
  534.         m_pFolderSplitter->AddPanes(m_pFolderOutlinerParent, m_pThreadSplitter, prefInt);
  535.  
  536.         CreateThreadPane();
  537.         MSG_SetFEData( m_pFolderPane, (LPVOID) (LPUNKNOWN) (LPMSGLIST) this );
  538.         MSG_SetFEData( m_pMessagePane, (LPVOID) (LPUNKNOWN) (LPMSGLIST) this );
  539.         MSG_SetMessagePaneCallbacks(m_pMessagePane, &MsgPaneCB, NULL);
  540.  
  541.         m_pOutlinerParent->SetFocus();
  542.  
  543.         // Don't call CMsgListFrame, since we create our list
  544.         // differently
  545.     }
  546.     return res;
  547. }
  548.  
  549. void C3PaneMailFrame::GetMessageString( UINT nID, CString& rMessage ) const
  550. {
  551.     switch (nID) {
  552.     case ID_MESSAGE_KILL:
  553.         rMessage.LoadString(ID_MESSAGE_KILL);
  554.         break;
  555.  
  556.     default:
  557.         CMsgListFrame::GetMessageString( nID, rMessage );
  558.     }
  559. }
  560.  
  561. BEGIN_MESSAGE_MAP(C3PaneMailFrame, CMailNewsFrame)
  562.     ON_WM_CREATE()
  563.     ON_WM_CLOSE()
  564.     ON_WM_DESTROY()
  565.  
  566.     // Edit Menu Items
  567.     ON_COMMAND(ID_EDIT_UNDO, OnEditUndo)
  568.     ON_COMMAND(ID_EDIT_REDO, OnEditRedo)
  569.     ON_COMMAND(ID_EDIT_SELECTTHREAD, OnSelectThread)
  570.     ON_UPDATE_COMMAND_UI(ID_EDIT_SELECTTHREAD, OnUpdateSelectThread)
  571.     ON_COMMAND(ID_EDIT_SELECTMARKEDMESSAGES, OnSelectFlagged)
  572.     ON_UPDATE_COMMAND_UI(ID_EDIT_SELECTMARKEDMESSAGES, OnUpdateSelectFlagged)
  573.     ON_COMMAND(ID_EDIT_SELECTALL, OnSelectAll)
  574.     ON_UPDATE_COMMAND_UI(ID_EDIT_SELECTALL, OnUpdateSelectAll)
  575.     ON_UPDATE_COMMAND_UI(ID_VIEW_PROPERTIES, OnUpdateProperties)
  576.     ON_COMMAND(ID_VIEW_PROPERTIES,OnEditProperties)
  577.  
  578.     // View Menu Items
  579.     ON_COMMAND(ID_VIEW_MESSAGE, OnViewMessage)         
  580.     ON_UPDATE_COMMAND_UI(ID_VIEW_MESSAGE, OnUpdateViewMessage)
  581.  
  582.     // Message Menu Items
  583. #ifdef ON_COMMAND_RANGE
  584.     ON_COMMAND_RANGE(FIRST_MOVE_MENU_ID, LAST_MOVE_MENU_ID, OnMove )
  585.     ON_COMMAND_RANGE(FIRST_COPY_MENU_ID, LAST_COPY_MENU_ID, OnCopy )
  586.     ON_UPDATE_COMMAND_UI_RANGE( FIRST_MOVE_MENU_ID, LAST_MOVE_MENU_ID, OnUpdateFile )
  587.     ON_UPDATE_COMMAND_UI_RANGE( FIRST_COPY_MENU_ID, LAST_COPY_MENU_ID, OnUpdateFile )
  588. #endif
  589.     ON_COMMAND(ID_MESSAGE_KILL, OnIgnore)
  590.     ON_UPDATE_COMMAND_UI(ID_MESSAGE_KILL, OnUpdateIgnore)
  591.  
  592.     // Non Menu Items    
  593.     ON_COMMAND( ID_MESSAGE_CONTINUE, OnContinue )
  594.     ON_COMMAND( ID_MESSAGE_SELECT, OnSelect )
  595.     ON_COMMAND( ID_FOLDER_SELECT, OnSelectFolder )
  596.     ON_COMMAND( ID_FILE_OPENMESSAGE, OnOpen )
  597.     ON_UPDATE_COMMAND_UI( ID_FILE_OPENMESSAGE, OnUpdateOpen)
  598.     ON_COMMAND( ID_FILE_OPENMESSAGENEW, OnOpenNew )
  599.     ON_UPDATE_COMMAND_UI( ID_FILE_OPENMESSAGENEW, OnUpdateOpen)
  600.     ON_COMMAND( ID_FILE_OPENMESSAGEREUSE, OnOpenReuse )
  601.     ON_UPDATE_COMMAND_UI( ID_FILE_OPENMESSAGEREUSE, OnUpdateOpen)
  602.     ON_COMMAND(ID_NAVIGATE_CONTAINER, OnContainer )
  603.     ON_UPDATE_COMMAND_UI( ID_MESSAGE_FILE, OnUpdateFile )
  604.     ON_COMMAND(ID_FILE_OPENFOLDER, OnOpenNewFrame )
  605.     ON_COMMAND(ID_VIEW_FOLDER, OnViewFolder)    
  606.  
  607.     ON_COMMAND(ID_HOTLIST_ADDCURRENTTOHOTLIST, OnFileBookmark)
  608.     ON_UPDATE_COMMAND_UI(ID_HOTLIST_ADDCURRENTTOHOTLIST, OnUpdateFileBookmark)
  609.  
  610.     ON_COMMAND(ID_PRIORITY_LOWEST, OnPriorityLowest)
  611.     ON_UPDATE_COMMAND_UI(ID_PRIORITY_LOWEST, OnUpdatePriority)
  612.     ON_COMMAND(ID_PRIORITY_LOW, OnPriorityLow)
  613.     ON_UPDATE_COMMAND_UI(ID_PRIORITY_LOW, OnUpdatePriority)
  614.     ON_COMMAND(ID_PRIORITY_NORMAL, OnPriorityNormal)
  615.     ON_UPDATE_COMMAND_UI(ID_PRIORITY_NORMAL, OnUpdatePriority)
  616.     ON_COMMAND(ID_PRIORITY_HIGH, OnPriorityHigh)
  617.     ON_UPDATE_COMMAND_UI(ID_PRIORITY_HIGH, OnUpdatePriority)
  618.     ON_COMMAND(ID_PRIORITY_HIGHEST, OnPriorityHighest)
  619.     ON_UPDATE_COMMAND_UI(ID_PRIORITY_HIGHEST, OnUpdatePriority)
  620.  
  621.     ON_COMMAND(ID_DONEGETTINGMAIL, OnDoneGettingMail)
  622. END_MESSAGE_MAP()
  623.  
  624.  
  625. void C3PaneMailFrame::SwitchUI( )
  626. {
  627.  
  628.     LPNSTOOLBAR pIToolBar;
  629.     m_pChrome->QueryInterface( IID_INSToolBar, (LPVOID *) &pIToolBar );
  630.     if ( pIToolBar ) {
  631.         CWnd *pToolWnd = CWnd::FromHandlePermanent( pIToolBar->GetHWnd() );
  632.  
  633.         if ( pToolWnd ) {
  634.             pIToolBar->RemoveAllButtons();
  635.  
  636.             UINT *aidButtons = m_bNews ? NewsCodes : MailCodes;
  637.             int *aidxButtons = m_bNews ? NewsIndices : MailIndices;
  638.  
  639.             int nButtons = (m_bNews ? sizeof(NewsCodes) : sizeof(MailCodes)) /sizeof(UINT);
  640.             for(int i = 0; i < nButtons; i++)
  641.             {
  642.                 if ( aidButtons[i] == ID_MESSAGE_FILE ) {
  643.                     CMailQFButton *pFileButton = new CMailQFButton;
  644.                     pFileButton->Create( CRect(0,0,0,0), pToolWnd, ID_MESSAGE_FILE);
  645.                     pIToolBar->AddButton(pFileButton, i);
  646.                 } else {
  647.                     CString statusStr, toolTipStr, textStr;
  648.                     CCommandToolbarButton *pCommandButton = new CCommandToolbarButton;
  649.                  
  650.                     WFE_ParseButtonString( aidButtons[i], statusStr, toolTipStr, textStr );
  651.                     DWORD dwButtonStyle = 0;
  652.  
  653.                     switch (aidButtons[i]) {
  654.                     case ID_MESSAGE_REPLYBUTTON:
  655.                     case ID_MESSAGE_MARKBUTTON:
  656.                         dwButtonStyle |= TB_HAS_IMMEDIATE_MENU;
  657.                         break;
  658.  
  659.                     case ID_MESSAGE_NEXTUNREAD:
  660.                         dwButtonStyle |= TB_HAS_TIMED_MENU;
  661.                         break;
  662.  
  663.                     case ID_NAVIGATE_MSG_BACK:
  664.                         break;
  665.                     default:
  666.                         break;
  667.                     }
  668.  
  669.                     pCommandButton->Create( pToolWnd, theApp.m_pToolbarStyle, 
  670.                                             CSize(44, 37), CSize(25, 25),
  671.                                             textStr, toolTipStr, statusStr,
  672.                                             m_bNews ? IDR_NEWSTHREAD : IDR_MAILTHREAD,
  673.                                             aidxButtons[i], CSize(23,21), 
  674.                                             aidButtons[i], -1, dwButtonStyle);
  675.  
  676.                     pIToolBar->AddButton(pCommandButton, i);
  677.                 }
  678.             }
  679.         }
  680.         pIToolBar->Release();
  681.     }
  682. #ifdef _WIN32
  683.     if (sysInfo.m_bWin4) {
  684.         UINT nIDIcon = m_bNews ? IDR_NEWSTHREAD : IDR_MAILTHREAD;
  685.         HINSTANCE hInst = AfxFindResourceHandle(MAKEINTRESOURCE(nIDIcon), RT_GROUP_ICON);
  686.         HICON hLargeIcon = ::LoadIcon(hInst, MAKEINTRESOURCE(nIDIcon));
  687.         SetIcon(hLargeIcon, TRUE);
  688.  
  689.         HICON hSmallIcon = (HICON) ::LoadImage(hInst, 
  690.                                                MAKEINTRESOURCE(nIDIcon),
  691.                                                IMAGE_ICON, 
  692.                                                GetSystemMetrics(SM_CXSMICON),
  693.                                                GetSystemMetrics(SM_CYSMICON),
  694.                                                LR_SHARED);
  695.         SetIcon(hSmallIcon, FALSE);
  696.     }
  697. #endif
  698. }
  699.  
  700. void C3PaneMailFrame::SetIsNews( BOOL bNews )
  701. {
  702.     if ( bNews != m_bNews ) {
  703.         m_bNews = bNews;
  704.         SwitchUI();
  705.     }
  706. }
  707.  
  708. void C3PaneMailFrame::SetSort( int idSort )
  709. {
  710.     if ( m_pOutliner ) {
  711.         m_pOutliner->GetParent()->Invalidate();
  712.         m_pOutliner->ScrollIntoView(m_pOutliner->GetFocusLine());
  713.     }
  714. }
  715.  
  716. void C3PaneMailFrame::DoNavigate( MSG_MotionType msgCommand )
  717. {
  718.     ASSERT( m_pPane && m_pOutliner );
  719.     if ( !m_pPane || !m_pOutliner )
  720.         return;
  721.  
  722.     if ( m_nLoadingFolder > 0 )
  723.         return;
  724.  
  725.     MSG_ViewIndex    viewIndex = (MSG_ViewIndex) m_pOutliner->GetFocusLine();
  726.     // Back end really wants -1 if there are no messages.
  727.     if ( m_pOutliner->GetTotalLines() < 1 ) {
  728.         viewIndex = (MSG_ViewIndex)-1;
  729.     }
  730.  
  731.     MSG_ViewIndex    resultIndex = viewIndex;
  732.     MessageKey        key = MSG_GetMessageKey( m_pPane, viewIndex );
  733.     MessageKey        resultId = key;
  734.     MSG_ViewIndex    threadIndex;
  735.     MSG_FolderInfo    *pFolderInfo = NULL;
  736.  
  737.     if ((int) viewIndex >= -1) {
  738.         // We don't want to be informed of a selection change if the BE does 
  739.         // something weird like collapse a thread as part of navigation, since
  740.         // we're probably going to select something ourselves.
  741.  
  742.         XP_Bool enable = FALSE;
  743.         MSG_NavigateStatus(m_pPane, msgCommand, viewIndex, &enable, NULL);
  744.         if (!enable)
  745.             return;
  746.  
  747.         m_pOutliner->BlockSelNotify(TRUE);
  748.  
  749.         MSG_ViewNavigate(m_pPane, msgCommand, viewIndex,
  750.                          &resultId, &resultIndex, &threadIndex, &pFolderInfo);
  751.  
  752.         m_pOutliner->BlockSelNotify(FALSE);
  753.  
  754.         if ( pFolderInfo )
  755.         {
  756.             C3PaneMailFrame *pFrame = C3PaneMailFrame::FindFrame( pFolderInfo );
  757.  
  758.             if (pFrame) {
  759.                 pFrame->ActivateFrame();
  760.  
  761.                 if (pFolderInfo != pFrame->GetCurFolder()) {
  762.                     // We must be a category, since we found a frame,
  763.                     // but our folderInfos don't match
  764.                     pFrame->m_navPending = msgCommand;
  765.                     
  766.                     switch ( msgCommand ) {
  767.                     case MSG_Forward:
  768.                     case MSG_Back:
  769.                         pFrame->m_selPending = resultId;
  770.                         break;
  771.                     default:
  772.                         break;
  773.                     }
  774.                     pFrame->LoadFolder(pFolderInfo, MSG_MESSAGEKEYNONE, actionNavigation);
  775.                 } else {
  776.                     switch ( msgCommand ) {
  777.                     case MSG_Forward:
  778.                     case MSG_Back:
  779.                     case MSG_EditUndo:
  780.                     case MSG_EditRedo:
  781.                         pFrame->SelectMessage( resultId );
  782.                         break;
  783.  
  784.                     case MSG_NextFolder:
  785.                     case MSG_NextMessage:
  786.                         pFrame->m_pOutliner->SelectItem( -1 );
  787.                         pFrame->DoNavigate(MSG_FirstMessage);
  788.                         break;
  789.  
  790.                     case MSG_NextUnreadMessage:
  791.                     case MSG_NextUnreadThread:
  792.                     case MSG_NextUnreadGroup:
  793.                     case MSG_LaterMessage:
  794.                         pFrame->m_pOutliner->SelectItem( -1 );
  795.                         pFrame->DoNavigate( msgCommand );
  796.  
  797.                     default:
  798.                         break;
  799.                     }
  800.                 }
  801.             } else {
  802.                 m_navPending = msgCommand;
  803.                 
  804.                 switch ( msgCommand ) {
  805.                 case MSG_NextFolder:
  806.                 case MSG_NextUnreadGroup:
  807.                     LoadFolder(pFolderInfo);
  808.                     break;
  809.                 case MSG_Forward:
  810.                 case MSG_Back:
  811.                     m_selPending = resultId;
  812.                     break;
  813.                 default:
  814.                     break;
  815.                 }
  816.             }
  817.         } else if ( resultId != key && (int) resultIndex >= 0 &&
  818.                     (int) resultIndex < m_pOutliner->GetTotalLines() ) {
  819.             m_pOutliner->SelectItem( CASTINT(resultIndex) );
  820.             m_pOutliner->ScrollIntoView( CASTINT(resultIndex) );
  821.         }
  822.         else if ( resultId != key && resultId != MSG_MESSAGEKEYNONE) {
  823.             SelectMessage(resultId);
  824.         }
  825.     }
  826. }
  827.  
  828. void C3PaneMailFrame::DoUpdateNavigate( CCmdUI* pCmdUI, MSG_MotionType msgCommand )
  829. {
  830.     ASSERT( m_pPane && m_pOutliner );
  831.     if ( !m_pPane || !m_pOutliner )
  832.         return;
  833.  
  834.     XP_Bool    enable = FALSE;
  835.     MSG_ViewIndex viewIndex = (MSG_ViewIndex) m_pOutliner->GetFocusLine();
  836.  
  837.     // Back end really wants -1 if there are no messages.
  838.     if ( m_pOutliner->GetTotalLines() < 1 ) {
  839.         viewIndex = (MSG_ViewIndex) -1;
  840.     }
  841.  
  842.     if ((int) viewIndex >= -1) {
  843.         MSG_NavigateStatus(m_pPane, msgCommand, viewIndex, &enable, NULL);
  844.     }
  845.  
  846.     pCmdUI->Enable( enable );
  847. }
  848.  
  849. int C3PaneMailFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
  850. {
  851.     // Add menus to genframe's menu map in order to load these menus
  852.     // when they are accessed rather than when frame is first created.
  853.     AddToMenuMap(0, IDM_MAILTHREADFILEMENU);
  854.     AddToMenuMap(1, IDM_MAILTHREADEDITMENU);
  855.     AddToMenuMap(2, IDM_MAILTHREADVIEWMENU);
  856.     AddToMenuMap(3, IDM_MAILTHREADGOMENU);
  857.     AddToMenuMap(4, IDM_MAILTHREADMESSAGEMENU);
  858.  
  859.     int res = CMailNewsFrame::OnCreate(lpCreateStruct);
  860.  
  861.  
  862.     if ( res != -1) {
  863.         m_pChrome->SetWindowTitle(XP_AppName);
  864.     
  865.         //I'm hardcoding string since I don't want it translated.
  866.         m_pChrome->CreateCustomizableToolbar("Messenger", 3, TRUE);
  867.         UINT nID = CASTUINT(ID_NAVIGATION_TOOLBAR);
  868.         CButtonToolbarWindow *pWindow;
  869.         BOOL bOpen, bShowing;
  870.  
  871.         int32 nPos;
  872.  
  873.         //I'm hardcoding because I don't want this translated
  874.         m_pChrome->LoadToolbarConfiguration(ID_NAVIGATION_TOOLBAR, CString("Navigation_Toolbar"), nPos, bOpen, bShowing);
  875.  
  876.         // Create tool bar
  877.         LPNSTOOLBAR pIToolBar;
  878.         m_pChrome->QueryInterface( IID_INSToolBar, (LPVOID *) &pIToolBar );
  879.         if ( pIToolBar ) {
  880.             pIToolBar->Create( this, WS_CHILD|WS_CLIPCHILDREN|WS_VISIBLE|CBRS_TOP );
  881.             pIToolBar->SetToolbarStyle( theApp.m_pToolbarStyle );
  882.             SwitchUI();
  883.             pWindow = new CButtonToolbarWindow(CWnd::FromHandlePermanent(pIToolBar->GetHWnd()), theApp.m_pToolbarStyle, 43, 27, eLARGE_HTAB);
  884.             m_pChrome->GetCustomizableToolbar()->AddNewWindow(ID_NAVIGATION_TOOLBAR, pWindow,nPos, 50, 37, 0, CString(szLoadString(nID)),theApp.m_pToolbarStyle, bOpen, FALSE);
  885.             m_pChrome->ShowToolbar(ID_NAVIGATION_TOOLBAR, bShowing);
  886.  
  887.             pIToolBar->Release();
  888.         }
  889.  
  890.         m_pInfoBar = new CFolderInfoBar;
  891.         m_pInfoBar->Create( this, m_pPane );
  892.  
  893.         //I'm hardcoding because I don't want this translated
  894.         m_pChrome->LoadToolbarConfiguration(ID_LOCATION_TOOLBAR, CString("Location_Toolbar"), nPos, bOpen, bShowing);
  895.  
  896.         CToolbarWindow *pToolWindow = new CToolbarWindow(m_pInfoBar, theApp.m_pToolbarStyle, 27, 27, eSMALL_HTAB);
  897.         m_pChrome->GetCustomizableToolbar()->AddNewWindow(ID_LOCATION_TOOLBAR, pToolWindow,nPos, 27, 27, 0, CString(szLoadString(ID_LOCATION_TOOLBAR)),theApp.m_pToolbarStyle, bOpen, FALSE);
  898.         m_pChrome->ShowToolbar(ID_LOCATION_TOOLBAR, bShowing);
  899.  
  900.         m_barStatus.Create( this );
  901.         m_barStatus.SetIndicators(indicators, sizeof(indicators)/sizeof(UINT));
  902.  
  903.         LPNSSTATUSBAR pIStatusBar = NULL;
  904.         m_pChrome->QueryInterface( IID_INSStatusBar, (LPVOID *) &pIStatusBar );
  905.         if ( pIStatusBar ) {
  906.             pIStatusBar->Attach( &m_barStatus );
  907.             pIStatusBar->Release();
  908.         }
  909.  
  910.         RecalcLayout();
  911.     }
  912.  
  913.     if ( res != -1) {
  914.         g_pLast3PaneMailFrame = this;
  915.     } else {
  916.         g_pLast3PaneMailFrame = NULL;
  917.     }
  918.  
  919.     return res;
  920. }
  921. #ifndef ON_COMMAND_RANGE
  922.  
  923. BOOL C3PaneMailFrame::OnCommand( WPARAM wParam, LPARAM lParam )
  924. {
  925.     UINT nID = wParam;
  926.  
  927.     if ( nID >= FIRST_MOVE_MENU_ID && nID <= LAST_MOVE_MENU_ID ) {
  928.         OnMove( nID );
  929.         return TRUE;
  930.     }
  931.     if ( nID >= FIRST_COPY_MENU_ID && nID <= LAST_COPY_MENU_ID ) {
  932.         OnCopy( nID );
  933.         return TRUE;
  934.     }
  935.     return CMsgListFrame::OnCommand( wParam, lParam );
  936. }
  937.  
  938. BOOL C3PaneMailFrame::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
  939.     if (nCode == CN_UPDATE_COMMAND_UI) {
  940.         CCmdUI* pCmdUI = (CCmdUI*)pExtra;
  941.         if ( nID >= FIRST_MOVE_MENU_ID && nID <= LAST_MOVE_MENU_ID ) {
  942.             OnUpdateFile( pCmdUI );
  943.             return TRUE;
  944.         }
  945.         if ( nID >= FIRST_COPY_MENU_ID && nID <= LAST_COPY_MENU_ID ) {
  946.             OnUpdateFile( pCmdUI );
  947.             return TRUE;
  948.         }
  949.     }
  950.     return CMsgListFrame::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo);
  951. }
  952.  
  953. #endif
  954.  
  955. void C3PaneMailFrame::OnClose()
  956. {
  957.     int16 left, top, width, height;
  958.     int32 prefInt;
  959.     WINDOWPLACEMENT wp;
  960.     wp.length = sizeof(WINDOWPLACEMENT);
  961.     GetWindowPlacement(&wp);
  962.     CRect rect(wp.rcNormalPosition);
  963.  
  964.     left = (int16) rect.left;
  965.     top = (int16) rect.top;
  966.     width = (int16) rect.Width();
  967.     height = (int16) rect.Height();
  968.     prefInt = wp.showCmd;
  969.  
  970.     PREF_SetRectPref("mailnews.thread_window_rect", left, top, width, height);
  971.     PREF_SetIntPref("mailnews.thread_window_showwindow", prefInt);
  972.  
  973.     PREF_SetIntPref("mailnews.3pane_folder_width", m_pFolderSplitter->GetPaneSize());
  974.     PREF_SetIntPref("mailnews.3pane_thread_height", m_pThreadSplitter->GetPaneSize());
  975.  
  976.     //I'm hardcoding because I don't want this translated
  977.     m_pChrome->SaveToolbarConfiguration(ID_NAVIGATION_TOOLBAR, CString("Navigation_Toolbar"));
  978.     m_pChrome->SaveToolbarConfiguration(ID_LOCATION_TOOLBAR, CString("Location_Toolbar"));
  979.  
  980.     CMailNewsFrame::OnClose();
  981. }
  982.  
  983. void C3PaneMailFrame::OnDestroy()
  984. {
  985.     if (m_pAttachmentData)
  986.         MSG_FreeAttachmentList(m_pMessagePane, m_pAttachmentData);
  987.     m_pAttachmentData = NULL;
  988.  
  989.     if (m_pMessagePane) {
  990.         // Since MSG_DestroyPane can result in notifications that
  991.         // we may attempt to act upon with the dying pane, NULL
  992.         // it out first
  993.         MSG_Pane *pTemp = m_pMessagePane;
  994.         m_pMessagePane = NULL;
  995.         MSG_DestroyPane( pTemp );
  996.     }
  997.     if ( m_pFolderPane ) {
  998.         // Ditto...
  999.         MSG_Pane *pTemp = m_pFolderPane;
  1000.         m_pFolderPane = NULL;
  1001.         MSG_DestroyPane( pTemp );
  1002.     }
  1003.  
  1004.     CView *pView = (CView *) GetDescendantWindow(IDW_MESSAGE_PANE, TRUE);
  1005.  
  1006.     ASSERT(pView && pView->IsKindOf(RUNTIME_CLASS(CNetscapeView)));
  1007.  
  1008.     if(pView)
  1009.         ((CNetscapeView *)pView)->FrameClosing();
  1010.  
  1011.     CMsgListFrame::OnDestroy();
  1012. }
  1013.  
  1014. // Edit Menu Items
  1015.  
  1016. void C3PaneMailFrame::OnSelectThread()
  1017. {
  1018.     ( (CMessageOutliner *) m_pOutliner)->SelectThread( -1 );
  1019. }
  1020.  
  1021. void C3PaneMailFrame::OnUpdateSelectThread ( CCmdUI* pCmdUI )
  1022. {
  1023.     BOOL bEnable = TRUE;
  1024.  
  1025.     bEnable &= MSG_GetToggleStatus( m_pPane, MSG_SortByThread, NULL, 0) == MSG_Checked;
  1026.  
  1027.     MSG_ViewIndex *indices;
  1028.     int count;    
  1029.     m_pOutliner->GetSelection( indices, count );
  1030.  
  1031.     bEnable &= (count > 0);
  1032.  
  1033.     pCmdUI->Enable( bEnable );
  1034. }
  1035.  
  1036. void C3PaneMailFrame::OnSelectFlagged()
  1037. {
  1038.     ( (CMessageOutliner *) m_pOutliner)->SelectFlagged();
  1039. }
  1040.  
  1041. void C3PaneMailFrame::OnUpdateSelectFlagged( CCmdUI *pCmdUI )
  1042. {
  1043.     // We should probably only do this when there are
  1044.     // flagged messages in the view, but that's probably
  1045.     // too expensive
  1046.     pCmdUI->Enable( TRUE );
  1047. }
  1048.  
  1049. void C3PaneMailFrame::OnSelectAll()
  1050. {
  1051.     HWND hwndFocus = ::GetFocus();
  1052.     HWND hwndOutliner = m_pOutliner ? m_pOutliner->m_hWnd : NULL;
  1053.     HWND hwndView = NULL;
  1054.  
  1055.     CWinCX*    pContext = GetActiveWinContext();
  1056.     if (pContext) {
  1057.         hwndView = pContext->GetPane();
  1058.     }
  1059.  
  1060.     BOOL bEnable = TRUE;
  1061.     UINT nID = IDS_MENU_ALL;
  1062.  
  1063.     if (IS_IN_WINDOW(hwndOutliner, hwndFocus)) {
  1064.         m_pOutliner->SelectRange( 0, -1, TRUE );
  1065.     } else if (hwndView == hwndFocus){
  1066.         LO_SelectAll(pContext->GetDocumentContext());
  1067.     }
  1068. }
  1069.  
  1070. void C3PaneMailFrame::OnUpdateSelectAll( CCmdUI *pCmdUI )
  1071. {
  1072.     HWND hwndFocus = ::GetFocus();
  1073.     HWND hwndOutliner = m_pOutliner ? m_pOutliner->m_hWnd : NULL;
  1074.     HWND hwndView = NULL;
  1075.  
  1076.     CWinCX*    pContext = GetActiveWinContext();
  1077.     if (pContext) {
  1078.         hwndView = pContext->GetPane();
  1079.     }
  1080.  
  1081.     BOOL bEnable = TRUE;
  1082.     UINT nID = IDS_MENU_ALL;
  1083.  
  1084.     if (IS_IN_WINDOW(hwndOutliner, hwndFocus)) {
  1085.         nID = IDS_MENU_ALLMESSAGES;
  1086.         bEnable = m_pOutliner->GetTotalLines() > 0;
  1087.     } else if (hwndView != hwndFocus){
  1088.         bEnable = FALSE;
  1089.     }
  1090.     pCmdUI->SetText(szLoadString(nID));
  1091.     pCmdUI->Enable(bEnable);
  1092. }
  1093.  
  1094. void C3PaneMailFrame::OnUpdateProperties(CCmdUI *pCmdUI)
  1095. {
  1096.     MSG_ViewIndex *indices = NULL;
  1097.     int count = 0;
  1098.     MSG_FolderLine folderLine;
  1099.  
  1100.  
  1101.     if (pCmdUI)
  1102.     {   
  1103.         if (m_pFolderOutliner == GetFocus())
  1104.         {
  1105.             m_pFolderOutliner->GetSelection( indices, count );
  1106.  
  1107.             if (indices && count)
  1108.             {
  1109.                 MSG_FolderInfo *folderInfo = MSG_GetFolderInfo( m_pFolderPane, indices[0] );
  1110.                 MSG_GetFolderLineByIndex( m_pFolderPane, indices[0], 1, &folderLine );
  1111.  
  1112.                 //only make and add the pages if they selected a news group or category
  1113.                 if ( folderLine.flags & (MSG_FOLDER_FLAG_NEWSGROUP|MSG_FOLDER_FLAG_CATEGORY) )
  1114.                 {
  1115.                     pCmdUI->Enable(TRUE);
  1116.                     return;
  1117.                 }
  1118.             }
  1119.         }
  1120.     }
  1121.     pCmdUI->Enable(FALSE);
  1122. }
  1123.  
  1124. void C3PaneMailFrame::OnEditProperties()
  1125. {
  1126.     MSG_ViewIndex *indices = NULL;
  1127.     int count = 0;
  1128.     MSG_FolderLine folderLine;
  1129.  
  1130.     if (m_pFolderOutliner)
  1131.         m_pFolderOutliner->GetSelection( indices, count );
  1132.  
  1133.     if (indices && count)
  1134.     {
  1135.         MSG_FolderInfo *folderInfo = MSG_GetFolderInfo( m_pFolderPane, indices[0] );
  1136.         MSG_GetFolderLineByIndex( m_pFolderPane, indices[0], 1, &folderLine );
  1137.  
  1138.         CNewsFolderPropertySheet FolderSheet( szLoadString(IDS_NEWSGROUPPROP), this );
  1139.         //destructor handles clean up of added sheets
  1140.  
  1141.         //only make and add the pages if they selected a news group or category
  1142.         if ( folderLine.flags & (MSG_FOLDER_FLAG_NEWSGROUP|MSG_FOLDER_FLAG_CATEGORY) )
  1143.         {
  1144.             FolderSheet.m_pNewsFolderPage= new CNewsGeneralPropertyPage(&FolderSheet);
  1145.             FolderSheet.m_pNewsFolderPage->SetFolderInfo( folderInfo, (MWContext*)GetContext() );
  1146.  
  1147.             FolderSheet.m_pDownLoadPageNews = new CDownLoadPPNews(&FolderSheet);
  1148.             FolderSheet.m_pDownLoadPageNews->SetFolderInfo(folderInfo);
  1149.  
  1150.             FolderSheet.m_pDiskSpacePage = new CDiskSpacePropertyPage(&FolderSheet);
  1151.             FolderSheet.m_pDiskSpacePage->SetFolderInfo (folderInfo );
  1152.  
  1153.             FolderSheet.AddPage(FolderSheet.m_pNewsFolderPage);
  1154.             FolderSheet.AddPage(FolderSheet.m_pDownLoadPageNews);
  1155.             FolderSheet.AddPage(FolderSheet.m_pDiskSpacePage);
  1156.  
  1157.             if(FolderSheet.DoModal() == IDOK)
  1158.             {
  1159.                 if(FolderSheet.DownLoadNow())
  1160.                 {
  1161.                   new CProgressDialog(this, NULL,_ShutDownFrameCallBack,
  1162.                     folderInfo,szLoadString(IDS_DOWNLOADINGARTICLES));
  1163.                     ;//DonwLoad!!!!!!!
  1164.                 }
  1165.                 else if (FolderSheet.SynchronizeNow())
  1166.                         ;//Synchronize!!!! NOT IMPLEMENTED
  1167.             }
  1168.         }
  1169.     }
  1170. }
  1171.  
  1172. // Message Menu Items
  1173.  
  1174. void C3PaneMailFrame::OnMove(UINT nID)
  1175. {
  1176.     if ( m_pPane ) {
  1177.         MSG_FolderInfo *folderInfo = FolderInfoFromMenuID( nID );
  1178.  
  1179.         ASSERT(folderInfo);
  1180.         if (folderInfo) {
  1181.             MSG_FolderLine folderLine;
  1182.             MSG_GetFolderLineById( WFE_MSGGetMaster(), folderInfo, &folderLine );
  1183.  
  1184.             MSG_ViewIndex *indices;
  1185.             int count;
  1186.             m_pOutliner->GetSelection( indices, count );
  1187.  
  1188.             // We want to make file behave for newsgroups
  1189.             if ( folderLine.flags & MSG_FOLDER_FLAG_NEWSGROUP ) {
  1190.                 MSG_CopyMessagesIntoFolder( m_pPane, indices, count, folderInfo);
  1191.             } else {
  1192.                 MSG_MoveMessagesIntoFolder( m_pPane, indices, count, folderInfo);
  1193.             }
  1194.             ModalStatusBegin( MODAL_DELAY );
  1195.         }
  1196.     }
  1197. }
  1198.  
  1199. void C3PaneMailFrame::OnCopy(UINT nID)
  1200. {            
  1201.     if ( m_pPane ) {
  1202.         MSG_FolderInfo *folderInfo = FolderInfoFromMenuID( nID );
  1203.  
  1204.         ASSERT(folderInfo);
  1205.         if (folderInfo) {
  1206.             MSG_ViewIndex *indices;
  1207.             int count;
  1208.             m_pOutliner->GetSelection( indices, count );
  1209.  
  1210.             MSG_CopyMessagesIntoFolder( m_pPane, indices, count, folderInfo);
  1211.             ModalStatusBegin( MODAL_DELAY );
  1212.         }
  1213.     }
  1214. }
  1215.  
  1216. void C3PaneMailFrame::OnUpdateFile( CCmdUI *pCmdUI ) 
  1217. {
  1218.     MSG_ViewIndex *indices;
  1219.     int count;
  1220.     m_pOutliner->GetSelection( indices, count );
  1221.  
  1222.     BOOL bEnable = count > 0;
  1223.  
  1224.     if (pCmdUI->m_pSubMenu) {
  1225.         pCmdUI->m_pMenu->EnableMenuItem(pCmdUI->m_nIndex,
  1226.                                         MF_BYPOSITION |(bEnable ? MF_ENABLED : MF_GRAYED));
  1227.     } else {
  1228.         pCmdUI->Enable( bEnable );
  1229.     }
  1230. }
  1231.  
  1232. void C3PaneMailFrame::OnViewMessage()
  1233. {
  1234.     MSG_FolderInfo *folderInfo = GetCurFolder();
  1235.  
  1236.     if ( folderInfo ) {
  1237.         if (m_pThreadSplitter->IsOnePaneClosed()) { 
  1238.             CFolderFrame::SetFolderPref( folderInfo, MSG_FOLDER_PREF_ONEPANE );
  1239.         } else {
  1240.             CFolderFrame::ClearFolderPref( folderInfo, MSG_FOLDER_PREF_ONEPANE );
  1241.         }
  1242.     }
  1243. }
  1244.  
  1245. void C3PaneMailFrame::OnUpdateViewMessage( CCmdUI *pCmdUI )
  1246. {
  1247.     pCmdUI->SetText( szLoadString( CASTUINT(m_pThreadSplitter->IsOnePaneClosed() ? 
  1248.                                    IDS_MENU_SHOWMESSAGE : IDS_MENU_HIDEMESSAGE )) );
  1249.     pCmdUI->Enable( TRUE );
  1250. }
  1251.  
  1252. void C3PaneMailFrame::OnViewFolder()
  1253. {
  1254.     if (m_pFolderSplitter->IsOnePaneClosed()) {
  1255.         m_pFolderOutlinerParent->EnableWindow(TRUE);
  1256.         m_pFolderOutliner->EnableWindow(TRUE);
  1257.  
  1258.         MSG_FolderInfo *pFolderInfo = MSG_GetCurFolder(m_pPane);
  1259.         UpdateFolderPane(pFolderInfo);
  1260.     }
  1261. }
  1262.  
  1263. // Message Menu Items
  1264.  
  1265. void C3PaneMailFrame::OnIgnore()
  1266. {
  1267.     DoNavigate((MSG_MotionType) MSG_ToggleThreadKilled);
  1268. }
  1269.  
  1270. void C3PaneMailFrame::OnUpdateIgnore(CCmdUI *pCmdUI)
  1271. {
  1272.     pCmdUI->SetText(szLoadString(IDS_MENU_IGNORETHREAD));
  1273.     DoUpdateCommand(pCmdUI, MSG_ToggleThreadKilled);
  1274. }
  1275.  
  1276. void C3PaneMailFrame::OnSelectFolder()
  1277. {
  1278.     MSG_FolderLine folderLine;
  1279.     if (GetSelectedFolder(&folderLine))
  1280.     {
  1281.         C3PaneMailFrame* pFrame = NULL;
  1282.  
  1283.         if (!m_pPane)
  1284.              CreateThreadPane();
  1285.         ASSERT(m_pPane);
  1286.         MSG_FolderInfo *folderInfo = MSG_GetCurFolder(m_pPane);
  1287.         if (folderLine.id == folderInfo)
  1288.         {
  1289.             if (folderLine.total == m_pOutliner->GetTotalLines())
  1290.                 return;
  1291.         }
  1292.         // check if folder has loaded in other window
  1293.         pFrame = FindFrame(folderLine.id);
  1294.         if (pFrame) 
  1295.         {
  1296.             pFrame->ActivateFrame();
  1297.             // fix do next unread group selection problem
  1298.             if (folderLine.total != m_pOutliner->GetTotalLines())
  1299.                 return;
  1300.             // set selection back to original one when doing a double click
  1301.             int nIndex = m_pFolderOutliner->GetCurrentSelected();
  1302.             if (nIndex != -1)
  1303.                 m_pFolderOutliner->SelectItem(nIndex);
  1304.         }
  1305.         else
  1306.             LoadFolder(folderLine.id);
  1307.     }
  1308.     else
  1309.     {
  1310.         BlankOutThreadPane();
  1311.         BlankOutMessagePane(NULL);
  1312.         MSG_DestroyPane(m_pPane);
  1313.         m_pPane = NULL;
  1314.     }
  1315. }
  1316.  
  1317. void C3PaneMailFrame::OnSelect()
  1318. {
  1319.     if (!m_pPane)
  1320.         return; // Abort!
  1321.  
  1322.     MessageKey idLoad = MSG_MESSAGEIDNONE;
  1323.     MSG_FolderInfo *folderInfo = MSG_GetCurFolder( m_pPane );
  1324.  
  1325.     // Make sure we need to load a message
  1326.     if ( m_pOutliner ) {
  1327.         MSG_MessageLine messageLine;
  1328.         MSG_ViewIndex *indices;
  1329.         int count;
  1330.         
  1331.         m_pOutliner->GetSelection( indices, count );
  1332.         if ( count == 1  && 
  1333.              MSG_GetThreadLineByIndex( m_pPane, indices[0], 1, &messageLine ) && 
  1334.              !m_pThreadSplitter->IsOnePaneClosed() ) {
  1335.             idLoad = messageLine.messageKey;
  1336.  
  1337.             if (!m_bNoScrollHack) {
  1338.                 m_pOutliner->ScrollIntoView( CASTINT(indices[0]) );
  1339.             }
  1340.         }
  1341.     }
  1342.  
  1343.     if (!m_pMessagePane)
  1344.         return; // Abort!
  1345.  
  1346.     // Make sure we aren't already displaying the message
  1347.     MessageKey idCur;
  1348.     MSG_FolderInfo *folderInfoCur;
  1349.     MSG_ViewIndex idxCur;
  1350.  
  1351.     MSG_GetCurMessage( m_pMessagePane, &folderInfoCur, &idCur, &idxCur );
  1352.  
  1353.     if ( idCur != idLoad || folderInfo != folderInfoCur ) {
  1354.  
  1355.         // Our null document doesn't clear the title.
  1356.         if (idLoad == MSG_MESSAGEIDNONE)  
  1357.             BlankOutMessagePane(folderInfo);
  1358.         else
  1359.             MSG_LoadMessage( m_pMessagePane, folderInfo, idLoad );
  1360.     }
  1361.  
  1362.     // Sync our info bar
  1363.     m_pInfoBar->Update();
  1364.  
  1365.     m_bNoScrollHack = FALSE;
  1366. }
  1367.  
  1368. void C3PaneMailFrame::DoOpenMessage(BOOL bReuse)
  1369. {
  1370.     if (m_pOutliner) {
  1371.         MSG_ViewIndex *indices;
  1372.         int i, count;
  1373.         
  1374.         m_pOutliner->GetSelection(indices, count);
  1375.         for ( i = 0; i < count; i++ ) {
  1376.             MSG_FolderInfo *folderInfo = MSG_GetCurFolder( m_pPane );
  1377.             MessageKey id = MSG_GetMessageKey(m_pPane, indices[i]);
  1378.  
  1379.             if ( folderInfo && id != MSG_MESSAGEKEYNONE ) {
  1380.                 MSG_FolderLine folderLine;
  1381.                 MSG_GetFolderLineById( WFE_MSGGetMaster(), folderInfo, &folderLine );
  1382.                 if (folderLine.flags & 
  1383.                     (MSG_FOLDER_FLAG_DRAFTS |
  1384.                      MSG_FOLDER_FLAG_QUEUE |
  1385.                      MSG_FOLDER_FLAG_TEMPLATES)) {
  1386.                     MSG_OpenDraft (m_pPane, folderInfo, id);
  1387.                 } else {
  1388.                     CMessageFrame *pFrame = CMessageFrame::FindFrame( folderInfo, id );
  1389.  
  1390.                     if ( !pFrame ) {
  1391.                         if ( bReuse && i == 0 ) {
  1392.                             pFrame = GetLastMessageFrame();
  1393.                         }
  1394.             
  1395.                         if ( pFrame ) {
  1396.                             pFrame->LoadMessage( folderInfo, id );
  1397.                         } else {
  1398.                             pFrame = CMessageFrame::Open( folderInfo, id );
  1399.                         }
  1400.                     }
  1401.                     if ( pFrame ) {
  1402.                         pFrame->ActivateFrame();
  1403.                     }
  1404.                 }
  1405.                 m_pOutliner->SelectItem(((CMessageOutliner*)m_pOutliner)->GetCurrentSelected());
  1406.             }
  1407.         }
  1408.     }
  1409.     m_pInfoBar->Update();
  1410. }
  1411.  
  1412. void C3PaneMailFrame::OnOpen( )
  1413. {
  1414.     BOOL bReuse = g_MsgPrefs.m_bMessageReuse;
  1415.     if (GetKeyState(VK_MENU) & 0x8000)
  1416.         bReuse = !bReuse;
  1417.  
  1418.     DoOpenMessage(bReuse);
  1419. }
  1420.  
  1421. void C3PaneMailFrame::OnOpenNew( )
  1422. {
  1423.     DoOpenMessage(FALSE);
  1424. }
  1425.  
  1426. void C3PaneMailFrame::OnOpenReuse( )
  1427. {
  1428.     DoOpenMessage(TRUE);
  1429. }
  1430.  
  1431. void C3PaneMailFrame::OnUpdateOpen(CCmdUI *pCmdUI)
  1432. {
  1433.     MSG_ViewIndex *indices;
  1434.     int count;
  1435.     m_pOutliner->GetSelection(indices, count);
  1436.  
  1437.     pCmdUI->Enable(count > 0);
  1438. }
  1439.  
  1440. void C3PaneMailFrame::OnOpenNewFrame()
  1441. {
  1442.     if (GetFocus() == m_pFolderOutliner) 
  1443.     {
  1444.         MSG_FolderLine folderLine;
  1445.         if (GetSelectedFolder(&folderLine))
  1446.         {
  1447.             if (folderLine.level > 1) 
  1448.             {
  1449.                 Open(folderLine.id);
  1450.                 if (!g_MsgPrefs.m_bThreadReuse)
  1451.                 {
  1452.                     int nIndex = m_pFolderOutliner->GetCurrentSelected();
  1453.                     if (nIndex != -1)
  1454.                     m_pFolderOutliner->SelectItem(nIndex);
  1455.                 }
  1456.             }
  1457.         }
  1458.     }
  1459. }
  1460.  
  1461. void C3PaneMailFrame::OnContinue()
  1462. {
  1463.     CWinCX * pCX = GetMainWinContext();
  1464.  
  1465.     if(pCX->GetOriginY() + pCX->GetHeight() < pCX->GetDocumentHeight()) {
  1466.         pCX->Scroll(SB_VERT, SB_PAGEDOWN, 0, NULL);
  1467.     } else if (!pCX->IsLayingOut()) {
  1468.         DoNavigate( MSG_NextUnreadMessage ); 
  1469.     }
  1470. }
  1471.  
  1472. void C3PaneMailFrame::OnContainer()
  1473. {
  1474.     MSG_FolderInfo *folderInfo = MSG_GetCurFolder( m_pPane );
  1475.     if ( folderInfo ) {
  1476.         CFolderFrame::Open( folderInfo );
  1477.     }
  1478. }
  1479.  
  1480. void C3PaneMailFrame::DoPriority( MSG_PRIORITY priority )
  1481. {
  1482.     MSG_ViewIndex *indices;
  1483.     int count;
  1484.     m_pOutliner->GetSelection(indices, count);
  1485.     for (int i = 0; i < count; i++) {
  1486.         MSG_SetPriority( m_pPane,
  1487.                          MSG_GetMessageKey( m_pPane, indices[i] ),
  1488.                          priority );
  1489.     }
  1490. }
  1491.  
  1492. void C3PaneMailFrame::OnPriorityLowest()
  1493. {
  1494.     DoPriority( MSG_LowestPriority );
  1495. }
  1496.  
  1497. void C3PaneMailFrame::OnPriorityLow()
  1498. {
  1499.     DoPriority( MSG_LowPriority );
  1500. }
  1501.  
  1502. void C3PaneMailFrame::OnPriorityNormal()
  1503. {
  1504.     DoPriority( MSG_NormalPriority );
  1505. }
  1506.  
  1507. void C3PaneMailFrame::OnPriorityHigh()
  1508. {
  1509.     DoPriority( MSG_HighPriority );
  1510. }
  1511.  
  1512. void C3PaneMailFrame::OnPriorityHighest()
  1513. {
  1514.     DoPriority( MSG_HighestPriority );
  1515. }
  1516.  
  1517. void C3PaneMailFrame::OnUpdatePriority(CCmdUI *pCmdUI)
  1518. {
  1519.     MSG_ViewIndex *indices;
  1520.     int count;
  1521.     m_pOutliner->GetSelection(indices,count);
  1522.  
  1523.     pCmdUI->Enable( !m_bNews && (count > 0) );
  1524. }
  1525.  
  1526. void C3PaneMailFrame::OnDoneGettingMail()
  1527. {
  1528.     MSG_ViewIndex    resultIndex = 0;
  1529.     MessageKey        resultId = MSG_MESSAGEKEYNONE;
  1530.     MSG_ViewIndex    threadIndex = 0;
  1531.     MSG_FolderInfo    *pFolderInfo = NULL;
  1532.  
  1533.     // We don't want to be informed of a selection change if the BE does 
  1534.     // something weird like collapse a thread as part of navigation, since
  1535.     // we're probably going to select something ourselves.
  1536.     m_pOutliner->BlockSelNotify(TRUE);
  1537.  
  1538.     MSG_ViewNavigate(m_pPane, MSG_FirstNew, 0,
  1539.                      &resultId, &resultIndex, &threadIndex, &pFolderInfo);
  1540.  
  1541.     m_pOutliner->BlockSelNotify(FALSE);
  1542.     if (resultId != MSG_MESSAGEKEYNONE) {
  1543.         resultIndex = MSG_GetMessageIndexForKey(m_pPane, resultId, TRUE);
  1544.         m_pOutliner->ScrollIntoView(CASTINT(resultIndex));
  1545.     }
  1546. }
  1547.  
  1548.  
  1549. void C3PaneMailFrame::DoUndoNavigate( MSG_MotionType motionCmd )
  1550. {
  1551.     MessageKey key = MSG_MESSAGEKEYNONE;
  1552.     MSG_FolderInfo *folder = NULL;
  1553.  
  1554.     if (!m_pPane || !m_pOutliner) return;
  1555.  
  1556.     UndoStatus undoStatus = MSG_GetUndoStatus(m_pPane); 
  1557.  
  1558.     if ( UndoComplete == undoStatus ) {
  1559.         if (MSG_GetUndoMessageKey(m_pPane, &folder, &key) && folder) {
  1560.             if (GetCurFolder() == folder) {
  1561.                 SelectMessage(key);
  1562.             }
  1563.             else {
  1564.                 /* need to load new folder */
  1565.                 m_navPending = motionCmd;
  1566.                 m_selPending = key;
  1567.                 LoadFolder(folder, MSG_MESSAGEKEYNONE, actionNavigation);
  1568.             }
  1569.         }
  1570.     }
  1571. }
  1572.  
  1573. // Edit Menu Items
  1574.  
  1575. void C3PaneMailFrame::OnEditUndo()
  1576. {
  1577.     DoCommand(MSG_Undo);
  1578.     DoUndoNavigate(MSG_EditUndo);
  1579. }
  1580.  
  1581. void C3PaneMailFrame::OnEditRedo()
  1582. {
  1583.     DoCommand(MSG_Redo);
  1584.     DoUndoNavigate(MSG_EditRedo);
  1585. }
  1586.  
  1587. void C3PaneMailFrame::SelectMessage( MessageKey key )
  1588. {
  1589.     MSG_ViewIndex index = 
  1590.         MSG_GetMessageIndexForKey( m_pPane, key, TRUE );
  1591.     if ( index != MSG_VIEWINDEXNONE ) {
  1592.         m_pOutliner->SelectItem( CASTINT(index) );
  1593.         m_pOutliner->ScrollIntoView(CASTINT(index));
  1594.     }
  1595. }
  1596.  
  1597. void C3PaneMailFrame::CreateThreadPane()
  1598. {
  1599.     m_pPane = MSG_CreateThreadPane(GetMainContext()->GetContext(), m_pMaster);
  1600.     if (m_pPane)
  1601.     {
  1602.         if (m_pOutliner)
  1603.             m_pOutliner->SetPane(m_pPane);
  1604.         MSG_SetFEData( m_pPane, (LPVOID) (LPUNKNOWN) (LPMSGLIST) this );
  1605.         if (m_pInfoBar)
  1606.             m_pInfoBar->SetPane(m_pPane);
  1607.     }
  1608. }
  1609.  
  1610. void C3PaneMailFrame::CreateFolderOutliner()
  1611. {
  1612.     m_pFolderOutlinerParent = new CFolderOutlinerParent;
  1613. #ifdef _WIN32
  1614.     m_pFolderOutlinerParent->CreateEx(WS_EX_CLIENTEDGE, NULL, NULL,
  1615.                                  WS_CHILD|WS_VISIBLE|WS_CLIPCHILDREN|WS_CLIPSIBLINGS,
  1616.                                  0,0,0,0, m_pFolderSplitter->m_hWnd, (HMENU) IDW_FOLDER_PANE, NULL );
  1617. #else
  1618.     m_pFolderOutlinerParent->Create( NULL, NULL,
  1619.                                  WS_BORDER|WS_CHILD|WS_VISIBLE|WS_CLIPCHILDREN|WS_CLIPSIBLINGS,
  1620.                                  CRect(0,0,0,0), m_pFolderSplitter, IDW_FOLDER_PANE );
  1621. #endif
  1622.  
  1623.     m_pFolderOutlinerParent->EnableFocusFrame(TRUE);
  1624.     m_pFolderPane = MSG_CreateFolderPane( GetMainContext()->GetContext(), m_pMaster );
  1625.     m_pFolderOutliner = DOWNCAST(CFolderOutliner, m_pFolderOutlinerParent->m_pOutliner);
  1626.     m_pFolderOutlinerParent->CreateColumns ( );
  1627.     m_pFolderOutliner->SetPane(m_pFolderPane);
  1628. }
  1629.  
  1630. void C3PaneMailFrame::UpdateFolderPane(MSG_FolderInfo *pFolderInfo)
  1631. {
  1632.     if (m_pFolderOutliner && m_pFolderPane)
  1633.     {
  1634.         MSG_ViewIndex *indices;
  1635.         int count;    
  1636.         m_pFolderOutliner->GetSelection( indices, count );   
  1637.  
  1638.         MSG_ViewIndex index = MSG_GetFolderIndexForInfo(m_pFolderPane, 
  1639.                                 pFolderInfo, TRUE);
  1640.  
  1641.         if (index != MSG_VIEWINDEXNONE && indices[0] != index)
  1642.             m_pFolderOutliner->SelectItem( CASTINT(index) );
  1643.     }
  1644. }
  1645.  
  1646. BOOL C3PaneMailFrame::GetSelectedFolder(MSG_FolderLine* pFolderLine)
  1647. {
  1648.     if (m_pFolderOutliner && m_pFolderPane)
  1649.     {
  1650.         MSG_ViewIndex *indices;
  1651.         int count = 0;
  1652.  
  1653.         m_pFolderOutliner->GetSelection(indices, count);
  1654.         if (count == 1 &&
  1655.             MSG_GetFolderLineByIndex(m_pFolderPane, indices[0], 1, pFolderLine)) 
  1656.             return TRUE;
  1657.         else
  1658.         {
  1659.             int nIndex = m_pFolderOutliner->GetCurrentSelected();
  1660.             indices[0] = nIndex;
  1661.             if (MSG_GetFolderLineByIndex(m_pFolderPane, indices[0], 1, pFolderLine)) 
  1662.                 return TRUE;
  1663.         }
  1664.     }
  1665.     return FALSE;
  1666. }
  1667.  
  1668. void C3PaneMailFrame::BlankOutThreadPane()
  1669. {
  1670.     m_pOutliner->SelectItem(-1);
  1671.     m_pOutliner->SetTotalLines(0);
  1672.     m_pOutliner->Invalidate();
  1673.     m_pOutliner->UpdateWindow();
  1674. }
  1675.  
  1676. void C3PaneMailFrame::BlankOutMessagePane(MSG_FolderInfo *pFolderInfo)
  1677. {
  1678.     MSG_LoadMessage(m_pMessagePane, pFolderInfo, MSG_MESSAGEKEYNONE);
  1679.     m_pChrome->SetDocumentTitle("");
  1680.     m_pMessageView->SetAttachments(NULL, 0);
  1681. }
  1682.  
  1683. void C3PaneMailFrame::LoadFolder( MSG_FolderInfo *folderInfo, MessageKey key, int action )
  1684. {
  1685.     if (m_pPane) {
  1686.         if ( key == MSG_MESSAGEKEYNONE ) {
  1687.             m_actionOnLoad = action;
  1688.         } else {
  1689.             m_actionOnLoad = actionSelectKey;
  1690.             m_selPending = key;
  1691.         }
  1692.  
  1693.         BlankOutMessagePane(folderInfo);
  1694.  
  1695.         UIForFolder( folderInfo );
  1696.  
  1697.         if (m_nLoadingFolder == 0) {
  1698.             m_nLoadingFolder++; // FYI
  1699.             m_pOutliner->BlockSelNotify(TRUE);
  1700.         } 
  1701.         MSG_LoadFolder( m_pPane, folderInfo );
  1702.     }
  1703. }
  1704.  
  1705. MessageKey C3PaneMailFrame::GetCurMessage() const
  1706. {
  1707.     MessageKey res = MSG_MESSAGEKEYNONE;
  1708.     MSG_ViewIndex *indices;
  1709.     int count;
  1710.  
  1711.     m_pOutliner->GetSelection( indices, count );
  1712.  
  1713.     if ( count == 1 ) {
  1714.         res = MSG_GetMessageKey( m_pPane, indices[0] );
  1715.     }
  1716.     return res;
  1717. }
  1718.  
  1719. MSG_FolderInfo *C3PaneMailFrame::GetCurFolder() const
  1720. {
  1721.     if (m_pPane)
  1722.         return MSG_GetCurFolder(m_pPane);
  1723.     else
  1724.         return NULL;
  1725. }
  1726.  
  1727. LPCTSTR C3PaneMailFrame::GetWindowMenuTitle()
  1728. {
  1729.     static CString cs;
  1730.  
  1731.     cs.LoadString(m_bNews ? IDS_NEWSGROUPCOLON : IDS_FOLDERCOLON);
  1732.     CString csTitle;
  1733.     csTitle.LoadString(IDS_NOTITLE);
  1734.  
  1735.     MSG_FolderLine folderLine;
  1736.     MSG_FolderInfo *folderInfo;
  1737.     folderInfo = MSG_GetCurFolder(m_pPane);
  1738.  
  1739.     if ( folderInfo && MSG_GetFolderLineById( m_pMaster, folderInfo, &folderLine ) ) {
  1740.         csTitle = folderLine.prettyName && folderLine.prettyName[0] ? 
  1741.                   folderLine.prettyName :
  1742.                   folderLine.name;
  1743.     }
  1744.  
  1745.     cs += csTitle;
  1746.  
  1747.     return cs;
  1748. }
  1749.  
  1750. void C3PaneMailFrame::OnFileBookmark()
  1751. {
  1752.     FileBookmark();
  1753. }
  1754.  
  1755. void C3PaneMailFrame::OnUpdateFileBookmark(CCmdUI *pCmdUI)
  1756. {
  1757.     pCmdUI->Enable(GetCurFolder() != NULL);
  1758. }
  1759.  
  1760. BOOL C3PaneMailFrame::FileBookmark()
  1761. {
  1762.     BOOL res = FALSE;
  1763.     MSG_ViewIndex *indices = NULL;
  1764.     int count = 0;
  1765.     m_pOutliner->GetSelection(indices, count);
  1766.  
  1767.     if (count < 1) {
  1768.         // Add bookmark to folder
  1769.         MSG_FolderLine folderLine;
  1770.         MSG_FolderInfo *folderInfo = MSG_GetCurFolder(m_pPane);
  1771.  
  1772.         if ( folderInfo && MSG_GetFolderLineById( m_pMaster, folderInfo, &folderLine ) ) {
  1773.             URL_Struct *url = MSG_ConstructUrlForPane(m_pPane);
  1774.             if (url) {
  1775.                 const char *name = (folderLine.prettyName && folderLine.prettyName[0]) ?
  1776.                                    folderLine.prettyName : folderLine.name;
  1777.  
  1778.                 HT_AddBookmark(url->address, (char*)name); // Updated to Aurora (Dave H.)
  1779.                 NET_FreeURLStruct( url );
  1780.                 res = TRUE;
  1781.             }
  1782.         }
  1783.     } else {
  1784.             // Add bookmark to each selected message
  1785.         MSG_MessageLine messageLine;
  1786.         for (int i = 0; i < count; i++) {
  1787.             if (MSG_GetThreadLineByIndex(m_pPane, indices[i], 1, &messageLine)) {
  1788.                 URL_Struct *url = MSG_ConstructUrlForMessage( m_pPane, messageLine.messageKey );
  1789.  
  1790.                 char *buf = IntlDecodeMimePartIIStr(messageLine.subject, INTL_DocToWinCharSetID(m_iCSID), FALSE);
  1791.                 char *name = (buf && buf[0]) ? buf : messageLine.subject;
  1792.  
  1793.                 if ( url ) {            
  1794.                     HT_AddBookmark(url->address, (char*)name); // Updated to Aurora (Dave H.) 
  1795.                     NET_FreeURLStruct( url );
  1796.                     res = TRUE;
  1797.                 }
  1798.                 XP_FREEIF(buf);
  1799.             }
  1800.         }
  1801.     }
  1802.  
  1803.     return res;
  1804. }
  1805.  
  1806. C3PaneMailFrame *C3PaneMailFrame::FindFrame( MSG_FolderInfo *folderInfo )
  1807. {
  1808.     CGenericFrame *pFrame = theApp.m_pFrameList;
  1809.     while (pFrame) {
  1810.         if (pFrame->IsKindOf(RUNTIME_CLASS(C3PaneMailFrame))) {
  1811.             C3PaneMailFrame *pThreadFrame = DYNAMIC_DOWNCAST(C3PaneMailFrame, pFrame);
  1812.             MSG_FolderInfo *folderInfo2 = pThreadFrame->GetCurFolder();
  1813.  
  1814.             if (folderInfo == folderInfo2)
  1815.                 return pThreadFrame;
  1816.         }
  1817.         pFrame = pFrame->m_pNext;
  1818.     }
  1819.     return NULL;
  1820. }
  1821.  
  1822. C3PaneMailFrame *C3PaneMailFrame::Open( )
  1823. {
  1824.     g_MsgPrefs.m_pThreadTemplate->OpenDocumentFile( NULL );
  1825.  
  1826.     return g_pLast3PaneMailFrame;
  1827. }
  1828.  
  1829. C3PaneMailFrame *C3PaneMailFrame::Open
  1830. ( MSG_FolderInfo *folderInfo, MessageKey key, BOOL* pContinue )
  1831. {
  1832.     BOOL bReuse = g_MsgPrefs.m_bThreadReuse;
  1833.     if (GetKeyState(VK_MENU) & 0x8000)
  1834.         bReuse = !bReuse;
  1835.  
  1836.     C3PaneMailFrame *pFrame = FindFrame( folderInfo );
  1837.     MSG_FolderInfo *pCurrentFolder = NULL;
  1838.     if (pFrame)
  1839.         pCurrentFolder = MSG_GetCurFolder( pFrame->m_pPane );
  1840.  
  1841.     if ( pFrame && (bReuse || (folderInfo == pCurrentFolder))) 
  1842.     {
  1843.         if (folderInfo != MSG_GetCurFolder( pFrame->m_pPane )) 
  1844.             pFrame->LoadFolder(folderInfo, key);
  1845.         else 
  1846.         {
  1847.             if ( key != MSG_MESSAGEKEYNONE )
  1848.                 pFrame->SelectMessage( key );
  1849.             else
  1850.             {
  1851.                 if (pFrame->m_nLoadingFolder && pContinue)
  1852.                     *pContinue = TRUE;
  1853.             }
  1854.         }
  1855.         if (s_bGetMail)
  1856.             pFrame->PostMessage(WM_COMMAND, (WPARAM) ID_FILE_GETNEWMAIL, (LPARAM) 0);
  1857.         if (pContinue && *pContinue)
  1858.             return     pFrame;
  1859.     } 
  1860.     else 
  1861.     {
  1862.         if ( !bReuse || !(pFrame = CMailNewsFrame::GetLastThreadFrame()) ) 
  1863.         {
  1864.             // Try to bring up the right UI the first time.
  1865.             MSG_FolderLine folderLine;
  1866.             MSG_GetFolderLineById(WFE_MSGGetMaster(), folderInfo, &folderLine);
  1867.             s_bHintNews = !(folderLine.flags & MSG_FOLDER_FLAG_MAIL);
  1868.  
  1869.             pFrame = C3PaneMailFrame::Open();
  1870.             if (pFrame)
  1871.             {
  1872.                 if (pFrame->m_pFolderOutliner && pFrame->m_pFolderPane)
  1873.                 {
  1874.                     MSG_ViewIndex index = MSG_GetFolderIndexForInfo(pFrame->m_pFolderPane, 
  1875.                                            folderInfo, TRUE);
  1876.                     if (index != MSG_VIEWINDEXNONE) 
  1877.                         pFrame->m_pFolderOutliner->SelectItem( CASTINT(index) );
  1878.                 }
  1879.                 pFrame->m_pOutliner->Invalidate();
  1880.                 pFrame->m_pFolderOutliner->Invalidate();
  1881.                 pFrame->m_pMessageView->Invalidate();
  1882.                 pFrame->UpdateWindow();
  1883.             }
  1884.         }
  1885.  
  1886.         if (pFrame) 
  1887.         {
  1888.             if (s_bGetMail)
  1889.                 pFrame->m_bWantToGetMail = TRUE;
  1890.  
  1891.             pFrame->LoadFolder( folderInfo, key );
  1892.         }
  1893.     }
  1894.     if ( pFrame ) 
  1895.         pFrame->ActivateFrame();
  1896.  
  1897.     return pFrame;
  1898. }
  1899.  
  1900. C3PaneMailFrame *C3PaneMailFrame::OpenInbox( BOOL bGetNew )
  1901. {
  1902.     if(theApp.m_hPostalLib)
  1903.     {        
  1904.         FEU_AltMail_ShowMailBox(); 
  1905.         return NULL;
  1906.     }
  1907.     else
  1908.     {
  1909.         if (!CheckWizard())
  1910.             return NULL;
  1911.  
  1912.         C3PaneMailFrame *pFrame = NULL;
  1913.         MSG_FolderInfo *folderInfo = NULL;
  1914.         MSG_GetFoldersWithFlag( WFE_MSGGetMaster(),
  1915.                                 MSG_FOLDER_FLAG_INBOX,
  1916.                                 &folderInfo, 1 );
  1917.  
  1918.         s_bGetMail = bGetNew;
  1919.  
  1920.         if (folderInfo)
  1921.         {
  1922.             pFrame = Open( folderInfo );
  1923.  
  1924.             if (pFrame->m_pFolderOutliner && pFrame->m_pFolderPane)
  1925.             {
  1926.                 MSG_ViewIndex index = MSG_GetFolderIndexForInfo(pFrame->m_pFolderPane, 
  1927.                                        folderInfo, TRUE);
  1928.                 if (index != MSG_VIEWINDEXNONE) 
  1929.                     pFrame->m_pFolderOutliner->SelectItem( CASTINT(index) );
  1930.             }
  1931.         }
  1932.         s_bGetMail = FALSE;
  1933.  
  1934.         return pFrame;
  1935.     }
  1936. }
  1937.  
  1938.  
  1939. C3PaneMailFrame *WFE_MSGOpenInbox(BOOL bGetNew)
  1940. {
  1941.     return C3PaneMailFrame::OpenInbox(bGetNew);
  1942. }
  1943.  
  1944.  
  1945. #ifdef DEBUG_WHITEBOX
  1946. BOOL C3PaneMailFrame::WhiteBox_DoesMessageExist( MessageKey key )
  1947. {
  1948.     MSG_ViewIndex index = MSG_GetMessageIndexForKey( m_pPane, key, TRUE );
  1949.     if ( index != MSG_VIEWINDEXNONE )
  1950.         return TRUE;
  1951.  
  1952.     return FALSE;
  1953. }
  1954. #endif
  1955.  
  1956.