home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / winfe / namcomp.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  24.6 KB  |  1,017 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. // addrdlg.cpp : implementation file
  19. //
  20.  
  21. #include "stdafx.h"
  22. #include "wfemsg.h"
  23. #include "msg_srch.h"
  24. #include "dirprefs.h"
  25. #include "namcomp.h"
  26. #include "apiaddr.h"
  27. #include "nethelp.h" 
  28. #include "prefapi.h"
  29. #include "intl_csi.h"
  30.  
  31. #ifdef _DEBUG
  32. #undef THIS_FILE
  33. static char BASED_CODE THIS_FILE[] = __FILE__;
  34. #endif
  35.  
  36. extern "C" {
  37. #include "xpgetstr.h"
  38. };
  39.  
  40.  
  41. class CNameCompletion;
  42.  
  43. CNameCompletionCX::CNameCompletionCX(CNameCompletion *pDialog)  
  44. : CStubsCX(AddressCX, MWContextAddressBook)
  45. {
  46.     m_pDialog = pDialog;
  47.     m_lPercent = 0;
  48.     m_bAnimated = FALSE;
  49. }
  50.  
  51.  
  52. void CNameCompletionCX::SetProgressBarPercent(MWContext *pContext, int32 lPercent ) {
  53.     //    Ensure the safety of the value.
  54.  
  55.     lPercent = lPercent < 0 ? 0 : ( lPercent > 100 ? 100 : lPercent );
  56.  
  57.     if ( m_lPercent == lPercent ) {
  58.         return;
  59.     }
  60.  
  61.     m_lPercent = lPercent;
  62.     if (m_pDialog) {
  63.         m_pDialog->SetProgressBarPercent(lPercent);
  64.     }
  65. }
  66.  
  67. void CNameCompletionCX::Progress(MWContext *pContext, const char *pMessage) {
  68.     if ( m_pDialog ) {
  69.         m_pDialog->SetStatusText(pMessage);
  70.     }
  71. }
  72.  
  73. int32 CNameCompletionCX::QueryProgressPercent()    {
  74.     return m_lPercent;
  75. }
  76.  
  77.  
  78. void CNameCompletionCX::AllConnectionsComplete(MWContext *pContext)    
  79. {
  80.     //  Call the base.
  81.     CStubsCX::AllConnectionsComplete(pContext);
  82.  
  83.     //    Also, we can clear the progress bar now.
  84.     m_lPercent = 0;
  85.     if ( m_pDialog ) {
  86.         m_pDialog->SetProgressBarPercent(m_lPercent);
  87.         m_pDialog->AllConnectionsComplete(pContext);
  88.     }
  89.     if (m_pDialog) {
  90.         m_pDialog->SendMessageToDescendants(WM_IDLEUPDATECMDUI, (WPARAM)TRUE, (LPARAM)0);
  91.     }
  92. }
  93.  
  94. void CNameCompletionCX::UpdateStopState( MWContext *pContext )
  95. {
  96.     if (m_pDialog) {
  97.         m_pDialog->SendMessageToDescendants(WM_IDLEUPDATECMDUI, (WPARAM)TRUE, (LPARAM)0);
  98.     }
  99. }
  100.  
  101. CWnd *CNameCompletionCX::GetDialogOwner() const {
  102.     return m_pDialog;
  103. }
  104.  
  105.  
  106. /////////////////////////////////////////////////////////////////////////////
  107. // CNameCompletionEntryList
  108.  
  109. STDMETHODIMP CNameCompletionEntryList::QueryInterface(REFIID refiid, LPVOID * ppv)
  110. {
  111.     *ppv = NULL;
  112.     if (IsEqualIID(refiid,IID_IUnknown))
  113.            *ppv = (LPUNKNOWN) this;
  114.     else if (IsEqualIID(refiid,IID_IMsgList))
  115.            *ppv = (LPMSGLIST) this;
  116.     else if (IsEqualIID(refiid,IID_IMailFrame))
  117.         *ppv = (LPMAILFRAME) m_pNameCompletion;
  118.  
  119.     if (*ppv != NULL) {
  120.            AddRef();
  121.         return NOERROR;
  122.     }
  123.             
  124.     return ResultFromScode(E_NOINTERFACE);
  125. }
  126.  
  127. STDMETHODIMP_(ULONG) CNameCompletionEntryList::AddRef(void)
  128. {
  129.     return ++m_ulRefCount;
  130. }
  131.  
  132. STDMETHODIMP_(ULONG) CNameCompletionEntryList::Release(void)
  133. {
  134.     ULONG ulRef;
  135.     ulRef = --m_ulRefCount;
  136.     if (m_ulRefCount == 0) 
  137.         delete this;       
  138.     return ulRef;       
  139. }
  140.  
  141. void CNameCompletionEntryList::ListChangeStarting( MSG_Pane* pane, XP_Bool asynchronous,
  142.                                        MSG_NOTIFY_CODE notify, MSG_ViewIndex where,
  143.                                        int32 num)
  144. {
  145.     if (m_pNameCompletion) {
  146.         m_pNameCompletion->ListChangeStarting( pane, asynchronous,
  147.                                                  notify, where, num );
  148.     }
  149. }
  150.  
  151. void CNameCompletionEntryList::ListChangeFinished( MSG_Pane* pane, XP_Bool asynchronous,
  152.                                        MSG_NOTIFY_CODE notify, MSG_ViewIndex where,
  153.                                        int32 num)
  154. {
  155.     if (m_pNameCompletion) {
  156.         m_pNameCompletion->ListChangeFinished( pane, asynchronous,
  157.                                                  notify, where, num );
  158.     }
  159. }
  160.  
  161. void CNameCompletionEntryList::GetSelection( MSG_Pane* pane, MSG_ViewIndex **indices, int *count, 
  162.                                 int *focus)
  163. {
  164. }
  165.  
  166. void CNameCompletionEntryList::SelectItem( MSG_Pane* pane, int item )
  167. {
  168. }
  169.  
  170.  
  171. /////////////////////////////////////////////////////////////////////////////
  172. // CNameCompletion
  173.  
  174. CNameCompletion::CNameCompletion(LPCTSTR lpszSearchString,
  175.     CWnd * parent): CDialog(CNameCompletion::IDD, parent)
  176. {
  177.     int result = 0;
  178.     INTL_CharSetInfo csi;
  179.  
  180.     m_pCX = new CNameCompletionCX( this );
  181.     csi = LO_GetDocumentCharacterSetInfo(m_pCX->GetContext());
  182.  
  183.     m_pCX->GetContext()->type = MWContextAddressBook;
  184.     m_pCX->GetContext()->fancyFTP = TRUE;
  185.     m_pCX->GetContext()->fancyNews = TRUE;
  186.     m_pCX->GetContext()->intrupt = FALSE;
  187.     m_pCX->GetContext()->reSize = FALSE;
  188.     INTL_SetCSIWinCSID(csi, CIntlWin::GetSystemLocaleCsid());
  189.  
  190.     m_addrBookPane = NULL;
  191.     m_pOutliner = NULL;
  192.     m_pOutlinerParent = NULL;
  193.     m_bSearching = FALSE;
  194.     m_lpszSearchString = lpszSearchString;
  195.  
  196.     CNameCompletionEntryList *pInstance = new CNameCompletionEntryList( this );
  197.     pInstance->QueryInterface( IID_IMsgList, (LPVOID *) &m_pIAddrList );
  198.  
  199.     HandleErrorReturn((result = AB_CreateAddressBookPane(&m_addrBookPane,
  200.             m_pCX->GetContext(),
  201.             WFE_MSGGetMaster())));
  202.  
  203.     //{{AFX_DATA_INIT(CNameCompletion)
  204.         // NOTE: the ClassWizard will add member initialization here
  205.     //}}AFX_DATA_INIT
  206. }
  207.  
  208.  
  209. void CNameCompletion::CleanupOnClose()
  210. {
  211.     // DestroyContext will call Interrupt, but if we wait until after DestroyContext
  212.     // to call MSG_SearchFree, the MWContext will be gone, and we'll be reading freed memory
  213.     if (XP_IsContextBusy (m_pCX->GetContext()))
  214.         XP_InterruptContext (m_pCX->GetContext());
  215.     MSG_SearchFree ((MSG_Pane*) m_addrBookPane);
  216.  
  217.     if (m_pIAddrList)
  218.         m_pIAddrList->Release();
  219.  
  220.     if (m_addrBookPane)
  221.         HandleErrorReturn(AB_CloseAddressBookPane(&m_addrBookPane));
  222.  
  223.     if(!m_pCX->IsDestroyed()) {
  224.         m_pCX->DestroyContext();
  225.     }
  226.  
  227.     if (m_pFont){
  228.         theApp.ReleaseAppFont(m_pFont);
  229.     }
  230.  
  231.     if (m_pOutlinerParent){
  232.         delete m_pOutlinerParent;
  233.     }
  234. }
  235.  
  236. /////////////////////////////////////////////////////////////////////////////
  237. // CNameCompletion Overloaded methods
  238. /////////////////////////////////////////////////////////////////////////////
  239. BOOL CNameCompletion::OnInitDialog( )
  240. {
  241.     if (CDialog::OnInitDialog()) {
  242.  
  243.         CWnd* widget;
  244.         CRect rect2, rect3, rect4;
  245.         UINT aIDArray[] = { IDS_SECURITY_STATUS, IDS_TRANSFER_STATUS, ID_SEPARATOR};
  246.         int result = 0;
  247.  
  248.         DIR_Server* dir = (DIR_Server*)XP_ListGetObjectNum(theApp.m_directories, 1);
  249.  
  250.         XP_ASSERT (dir);
  251.  
  252.         if (!dir)
  253.             return FALSE;
  254.  
  255.         HandleErrorReturn((result = AB_InitializeAddressBookPane(m_addrBookPane,
  256.             dir,
  257.             theApp.m_pABook,
  258.             ABFullName,
  259.             TRUE)));
  260.  
  261.         if (result) {
  262.             EndDialog(IDCANCEL);
  263.             return TRUE;
  264.         }
  265.  
  266.         // create the outliner
  267.         widget = GetDlgItem(IDC_ADDRESSLIST);
  268.         widget->GetWindowRect(&rect2);
  269.         widget->GetClientRect(&rect3);
  270.         GetClientRect(&rect4);
  271.         ClientToScreen(&rect4);
  272.         rect2.OffsetRect(-rect4.left, -rect4.top);
  273.  
  274.         widget->DestroyWindow ();
  275.  
  276.         // create the outliner control
  277.         m_pOutlinerParent = new CNameCompletionOutlinerParent;
  278. #ifdef _WIN32
  279.         m_pOutlinerParent->CreateEx ( WS_EX_CLIENTEDGE, NULL, _T("NSOutlinerParent"), 
  280.                                 WS_BORDER|WS_TABSTOP|WS_VISIBLE|WS_CHILD|WS_CLIPCHILDREN,
  281.                                 0, 0, 0, 0,
  282.                                 this->m_hWnd, (HMENU) IDC_ADDRESSLIST);
  283. #else
  284.         rect3.SetRectEmpty();
  285.         m_pOutlinerParent->Create( NULL, _T("NSOutlinerParent"), 
  286.                                   WS_BORDER|WS_TABSTOP|WS_VISIBLE|WS_CHILD|WS_CLIPCHILDREN|WS_CLIPSIBLINGS,
  287.                                   rect3, this, IDC_ADDRESSLIST);
  288. #endif
  289.  
  290.         m_pOutlinerParent->MoveWindow(&rect2, TRUE);
  291.         m_pOutlinerParent->CreateColumns ( );
  292.         m_pOutliner = (CNameCompletionOutliner *) m_pOutlinerParent->m_pOutliner;
  293.         m_pOutliner->SetPane(m_addrBookPane);
  294.         m_pOutliner->SetContext( m_pCX->GetContext() );
  295.  
  296.         // create the status bar
  297.         widget = GetDlgItem(IDC_StatusRect);
  298.         widget->GetWindowRect(&rect2);
  299.         widget->GetClientRect(&rect3);
  300.         ScreenToClient(&rect2);
  301.  
  302.         widget->DestroyWindow ();
  303.  
  304.         // create the status bar
  305.         m_barStatus.Create(this, TRUE, FALSE);
  306.         m_barStatus.MoveWindow(&rect2, TRUE);
  307.         m_barStatus.SetIndicators( aIDArray, sizeof(aIDArray) / sizeof(UINT) );
  308.         
  309.         UpdateButtons();
  310.     }
  311.  
  312.     return TRUE;
  313. }
  314.  
  315.  
  316. void CNameCompletion::Progress(const char *pMessage)
  317. {
  318.     m_barStatus.SetWindowText( pMessage );
  319. }
  320.  
  321.  
  322. void CNameCompletion::SetProgressBarPercent(int32 lPercent)
  323. {
  324.     m_barStatus.SetPercentDone (lPercent);
  325. } // END OF    FUNCTION CNameCompletion::DrawProgressBar()
  326.  
  327.  
  328. /////////////////////////////////////////////////////////////////////////////
  329. // CAddrDialog message handlers
  330.  
  331. BEGIN_MESSAGE_MAP(CNameCompletion, CDialog)
  332.     //{{AFX_MSG_MAP(CNameCompletion)
  333.     ON_BN_CLICKED( IDOK, OnOK)
  334.     ON_BN_CLICKED( IDCANCEL, OnCancel)
  335.     ON_WM_CREATE()
  336.     ON_WM_DESTROY()
  337.     ON_COMMAND(ID_HELP, OnHelp)
  338.     //}}AFX_MSG_MAP
  339. END_MESSAGE_MAP()
  340.  
  341.  
  342. void CNameCompletion::DoDataExchange(CDataExchange* pDX)
  343. {
  344.     CDialog::DoDataExchange(pDX);
  345.     //{{AFX_DATA_MAP(CNameCompletion)
  346.     //}}AFX_DATA_MAP
  347. }
  348.  
  349.  
  350. int CNameCompletion::OnCreate(LPCREATESTRUCT lpCreateStruct) 
  351. {
  352.     int res = CDialog::OnCreate(lpCreateStruct);
  353.  
  354.     m_MailNewsResourceSwitcher.Reset();
  355.  
  356.     MSG_SetFEData( (MSG_Pane*) m_addrBookPane, (void *) m_pIAddrList );
  357.     return res;
  358. }
  359.  
  360.  
  361. void CNameCompletion::OnOK() 
  362. {
  363.     CDialog::OnOK();
  364.     CleanupOnClose();
  365. }
  366.  
  367.  
  368. void CNameCompletion::OnCancel() 
  369. {
  370.     CDialog::OnCancel();
  371.     CleanupOnClose();
  372. }
  373.  
  374.  
  375. void CNameCompletion::ListChangeStarting( MSG_Pane* pane, XP_Bool asynchronous,
  376.                                         MSG_NOTIFY_CODE notify, MSG_ViewIndex where,
  377.                                         int32 num)
  378. {
  379.     if ( pane == (MSG_Pane*) m_addrBookPane ) {
  380.         if ( m_pOutliner ) {
  381.             m_pOutliner->MysticStuffStarting( asynchronous, notify,
  382.                                                    where, num );
  383.         }
  384.     }
  385. }
  386.  
  387. void CNameCompletion::ListChangeFinished( MSG_Pane* pane, XP_Bool asynchronous,
  388.                                         MSG_NOTIFY_CODE notify, MSG_ViewIndex where,
  389.                                         int32 num)
  390. {
  391.     if ( pane == (MSG_Pane*) m_addrBookPane ) {
  392.         if ( m_pOutliner ) {
  393.             m_pOutliner->MysticStuffFinishing( asynchronous, notify,
  394.                                                     where, num );
  395.             UpdateButtons();
  396.         }
  397.     }
  398. }
  399.  
  400.  
  401. void CNameCompletion::SetStatusText(const char* pMessage)
  402. {
  403.     m_barStatus.SetWindowText( pMessage );
  404. }
  405.  
  406.  
  407. void CNameCompletion::SetSearchResults(MSG_ViewIndex index, int32 num)
  408. {
  409.  
  410.     CString csStatus;
  411.  
  412.     ASSERT(m_pOutliner);
  413.     AB_LDAPSearchResults(m_addrBookPane, index, num);
  414.     if (num > 1 ) {
  415.         csStatus.Format( szLoadString(IDS_SEARCHHITS), num );
  416.     } else if ( num > 0 ) {
  417.         csStatus.LoadString( IDS_SEARCHONEHIT );
  418.     } else {
  419.         csStatus.LoadString( IDS_SEARCHNOHITS );
  420.     }
  421.  
  422.     m_barStatus.SetWindowText( csStatus );
  423.  
  424. }
  425.  
  426. STDMETHODIMP CNameCompletion::QueryInterface(REFIID refiid, LPVOID * ppv)
  427. {
  428.     *ppv = NULL;
  429.     if (IsEqualIID(refiid,IID_IUnknown))
  430.            *ppv = (LPUNKNOWN) (LPMAILFRAME) this;
  431.     else if (IsEqualIID(refiid,IID_IMailFrame))
  432.         *ppv = (LPMAILFRAME) this;
  433.  
  434.     if (*ppv != NULL) {
  435.            AddRef();
  436.         return NOERROR;
  437.     }
  438.             
  439.     return ResultFromScode(E_NOINTERFACE);
  440. }
  441.  
  442. STDMETHODIMP_(ULONG) CNameCompletion::AddRef(void)
  443. {
  444.     return 0; // Not a real component
  445. }
  446.  
  447. STDMETHODIMP_(ULONG) CNameCompletion::Release(void)
  448. {
  449.     return 0; // Not a real component
  450. }
  451.  
  452. // IMailFrame interface
  453. CMailNewsFrame *CNameCompletion::GetMailNewsFrame()
  454. {
  455.     return (CMailNewsFrame *) NULL; 
  456. }
  457.  
  458. MSG_Pane *CNameCompletion::GetPane()
  459. {
  460.     return (MSG_Pane*) m_addrBookPane;
  461. }
  462.  
  463. void CNameCompletion::PaneChanged(MSG_Pane *pane, XP_Bool asynchronous, 
  464.                                  MSG_PANE_CHANGED_NOTIFY_CODE notify, int32 value)
  465. {
  466.     if (notify == MSG_PaneDirectoriesChanged) {
  467.         if (IsSearching())
  468.             PerformDirectorySearch ();
  469.     }
  470. }
  471.  
  472.  
  473. void CNameCompletion::AllConnectionsComplete( MWContext *pContext )
  474. {
  475.     PerformDirectorySearch();
  476.  
  477.     int total = m_pOutliner->GetTotalLines();
  478.     CString csStatus;
  479.     if ( total > 1 ) {
  480.         csStatus.Format( szLoadString( IDS_SEARCHHITS ), total );
  481.     } else if ( total > 0 ) {
  482.         csStatus.LoadString( IDS_SEARCHONEHIT );
  483.     } else {
  484.         csStatus.LoadString( IDS_SEARCHNOHITS );
  485.     }
  486.     m_barStatus.SetWindowText( csStatus );
  487.  
  488.     SendMessageToDescendants(WM_IDLEUPDATECMDUI, (WPARAM)TRUE, (LPARAM)0);
  489. }
  490.  
  491.  
  492. void CNameCompletion::OnComposeMsg()
  493. {
  494.     
  495. }
  496.  
  497.  
  498. void CNameCompletion::HandleErrorReturn(int errorid)
  499. {    
  500.     if (errorid) {
  501.         CString s;
  502.         if (s.LoadString( IDS_BOOKMARK_ADDRESSPROPERTIES ))
  503.             ::MessageBox(NULL, XP_GetString(errorid), s, MB_OK);
  504.     }
  505. }
  506.  
  507.  
  508. void CNameCompletion::PerformDirectorySearch ()
  509. {
  510.     CString cs;
  511.  
  512.     if ( m_bSearching) {
  513.         // We've turned into stop button
  514.         XP_InterruptContext( m_pCX->GetContext() );
  515.         HandleErrorReturn(AB_FinishSearch(m_addrBookPane, m_pCX->GetContext()));
  516.         m_bSearching = FALSE;
  517.         return;
  518.     }
  519.  
  520.     // Begin Search
  521.     m_barStatus.SetWindowText( szLoadString( IDS_SEARCHING ) );
  522.     m_bSearching = TRUE;
  523.     m_pOutliner->UpdateCount();
  524.     m_pOutliner->SetFocus();
  525.  
  526.     HandleErrorReturn(AB_SearchDirectory(m_addrBookPane, NULL));
  527.  
  528. }
  529.  
  530.  
  531. //////////////////////////////////////////////////////////////////////////////
  532. // CNameCompletionOutliner
  533. BEGIN_MESSAGE_MAP(CNameCompletionOutliner, COutliner)
  534.     //{{AFX_MSG_MAP(CNameCompletionOutliner)
  535.     //}}AFX_MSG_MAP
  536. END_MESSAGE_MAP()
  537.  
  538. CNameCompletionOutliner::CNameCompletionOutliner ( )
  539. {
  540.     ApiApiPtr(api);
  541.     m_pUnkUserImage = api->CreateClassInstance(APICLASS_IMAGEMAP);
  542.     if (m_pUnkUserImage) {
  543.         m_pUnkUserImage->QueryInterface(IID_IImageMap,(LPVOID*)&m_pIUserImage);
  544.         ASSERT(m_pIUserImage);
  545.         m_pIUserImage->Initialize(IDB_ADDRESSBOOK,16,16);
  546.     }
  547.     m_iMysticPlane = 0;
  548.     m_hFont = NULL;
  549. }
  550.  
  551. CNameCompletionOutliner::~CNameCompletionOutliner ( )
  552. {
  553.     if (m_pUnkUserImage) {
  554.         if (m_pIUserImage)
  555.             m_pUnkUserImage->Release();
  556.     }
  557.  
  558.     if (m_hFont) {
  559.         theApp.ReleaseAppFont(m_hFont);
  560.     }
  561. }
  562.  
  563.  
  564. void CNameCompletionOutliner::SetColumnsForDirectory (DIR_Server* pServer)
  565. {
  566.     int iCount = GetNumColumns();
  567.     for (int i = 0; i < iCount; i++) {
  568.         CString cs;
  569.         int iColumn = GetColumnAtPos(i);
  570.         if (pServer->dirType == LDAPDirectory)
  571.         {
  572.             DIR_AttributeId id;
  573.             const char *text = NULL;
  574.             switch (iColumn) {
  575.             case ID_COLADDR_TYPE:
  576.                 text = NULL;
  577.                 break;
  578.             case ID_COLADDR_NAME:
  579.                 MSG_SearchAttribToDirAttrib(attribCommonName, &id);        
  580.                 text = DIR_GetAttributeName(pServer, id);
  581.                 break;
  582.             case ID_COLADDR_EMAIL:
  583.                 MSG_SearchAttribToDirAttrib(attrib822Address, &id);    
  584.                 text = DIR_GetAttributeName(pServer, id);
  585.                 break;
  586.             case ID_COLADDR_COMPANY:
  587.                 MSG_SearchAttribToDirAttrib(attribOrganization, &id);    
  588.                 text = DIR_GetAttributeName(pServer, id);
  589.                 break;
  590.             case ID_COLADDR_PHONE:
  591.                 MSG_SearchAttribToDirAttrib(attribPhoneNumber, &id);    
  592.                 text = DIR_GetAttributeName(pServer, id);
  593.                 break;
  594.             case ID_COLADDR_LOCALITY:
  595.                 MSG_SearchAttribToDirAttrib(attribLocality, &id);    
  596.                 text = DIR_GetAttributeName(pServer, id);
  597.                 break;
  598.             case ID_COLADDR_NICKNAME:
  599.                 text = NULL;    
  600.                 break;
  601.             default:
  602.                 break;
  603.             }
  604.             if (text)
  605.                 SetColumnName(iColumn, text);
  606.         }
  607.         else
  608.         {
  609.             switch (iColumn) {
  610.             case ID_COLADDR_TYPE:
  611.                 cs = "";
  612.                 break;
  613.             case ID_COLADDR_NAME:
  614.                 cs.LoadString(IDS_USERNAME);        
  615.                 break;
  616.             case ID_COLADDR_EMAIL:
  617.                 cs.LoadString(IDS_EMAILADDRESS);
  618.                 break;
  619.             case ID_COLADDR_COMPANY:
  620.                 cs.LoadString(IDS_COMPANYNAME);
  621.                 break;
  622.             case ID_COLADDR_PHONE:
  623.                 cs.LoadString(IDS_PHONE);
  624.                 break;
  625.             case ID_COLADDR_LOCALITY:
  626.                 cs.LoadString(IDS_LOCALITY);
  627.                 break;
  628.             case ID_COLADDR_NICKNAME:
  629.                 cs.LoadString(IDS_NICKNAME);
  630.                 break;
  631.             default:
  632.                 break;
  633.             }
  634.         if (cs.GetLength())
  635.             SetColumnName(iColumn, cs);
  636.         }
  637.     }
  638.     GetParent()->Invalidate();
  639.     GetParent()->UpdateWindow();
  640. }
  641.  
  642.  
  643. void CNameCompletionOutliner::UpdateCount( )
  644. {
  645.     uint32 count = 0;
  646.  
  647.     SetTotalLines(CASTINT(count));
  648. }
  649.  
  650.  
  651. void CNameCompletionOutliner::SetPane(ABPane *pane)
  652. {
  653.     m_pane = pane;
  654.     uint32 count = 0;
  655.  
  656.     if (m_pane) {
  657.         SetTotalLines(CASTINT(count));
  658.         Invalidate();
  659.         UpdateWindow();
  660.     }
  661. }
  662.  
  663. void CNameCompletionOutliner::MysticStuffStarting( XP_Bool asynchronous,
  664.                                             MSG_NOTIFY_CODE notify, 
  665.                                             MSG_ViewIndex where,
  666.                                             int32 num )
  667. {
  668.     ++m_iMysticPlane;
  669. }
  670.  
  671. void CNameCompletionOutliner::MysticStuffFinishing( XP_Bool asynchronous,
  672.                                              MSG_NOTIFY_CODE notify, 
  673.                                              MSG_ViewIndex where,
  674.                                              int32 num )
  675. {
  676.  
  677. #ifdef _WIN32
  678.             CWnd *pParent = GetParentOwner();
  679. #else
  680.             CWnd *pParent = GetOwner();      
  681.             pParent = pParent->GetParent();
  682.             ASSERT(pParent);
  683. #endif
  684.  
  685.     switch ( notify ) 
  686.     {
  687.  
  688.     case MSG_NotifyNone:
  689.         break;
  690.  
  691.     case MSG_NotifyInsertOrDelete:
  692.         // if its insert or delete then tell my frame to add the next chunk of values
  693.         // from the search
  694.         if (notify == MSG_NotifyInsertOrDelete 
  695.             && ((CNameCompletion*)pParent)->IsSearching() && num > 0) 
  696.         {
  697.             ((CNameCompletion*)pParent)->SetSearchResults(where, num);
  698.         }
  699.         else
  700.         {
  701.         }
  702.         break;
  703.  
  704.     case MSG_NotifyChanged:
  705.         InvalidateLines( (int) where, (int) num );
  706.         break;
  707.  
  708.     case MSG_NotifyAll:
  709.     case MSG_NotifyScramble:
  710.         Invalidate();
  711.         break;
  712.     }
  713.  
  714.     if (( !--m_iMysticPlane && m_pane)) 
  715.     {
  716.         uint32 count;
  717.         SetTotalLines(CASTINT(count));
  718.         Invalidate();
  719.         UpdateWindow();
  720.     }
  721. }
  722.  
  723.  
  724. void CNameCompletionOutliner::SetTotalLines( int count)
  725. {
  726.     COutliner::SetTotalLines(count);
  727. }
  728.  
  729.  
  730.  
  731.  
  732. BOOL CNameCompletionOutliner::RenderData  ( UINT iColumn, CRect &rect, CDC &dc, const char * text )
  733. {
  734.     if ( iColumn != ID_COLADDR_TYPE )
  735.         return COutliner::RenderData ( iColumn, rect, dc, text );
  736.  
  737.     int idxImage = 0;
  738.  
  739.     if (m_EntryLine.entryType == ABTypeList)
  740.         idxImage = IDX_ADDRESSBOOKLIST;
  741.     else
  742.         idxImage = IDX_ADDRESSBOOKPERSON;
  743.  
  744.     m_pIUserImage->DrawImage ( idxImage,
  745.         rect.left + ( ( rect.Width ( ) - 16 ) / 2 ), rect.top, &dc, FALSE );
  746.     return TRUE;
  747. }
  748.  
  749.  
  750. int CNameCompletionOutliner::TranslateIcon ( void * pLineData )
  751. {
  752.     AB_EntryLine* line = (AB_EntryLine*) pLineData;
  753.     int idxImage = 0;
  754.  
  755.     if (line->entryType == ABTypeList)
  756.         idxImage = IDX_ADDRESSBOOKLIST;
  757.     else
  758.         idxImage = IDX_ADDRESSBOOKPERSON;
  759.     return idxImage;
  760. }
  761.  
  762. int CNameCompletionOutliner::TranslateIconFolder (void * pData)
  763. {
  764.     // We're a flat list, so we're never a folder
  765.     return ( OUTLINER_ITEM );
  766. }
  767.  
  768.  
  769. BOOL CNameCompletionOutliner::ColumnCommand ( int iColumn, int iLine )
  770. {
  771.     // We have no column commands
  772.     return FALSE;
  773. }
  774.  
  775. HFONT CNameCompletionOutliner::GetLineFont(void *pLineData)
  776. {
  777.     if (!m_hFont)
  778.     {
  779.         HDC hDC = ::GetDC(m_hWnd);
  780.         LOGFONT lf;  
  781.         memset(&lf,0,sizeof(LOGFONT));
  782.  
  783.         lf.lfPitchAndFamily = FF_SWISS;
  784.         lf.lfWeight = FW_NORMAL;
  785.         lf.lfCharSet = IntlGetLfCharset(CIntlWin::GetSystemLocaleCsid());
  786.         if (CIntlWin::GetSystemLocaleCsid() == CS_LATIN1)
  787.              _tcscpy(lf.lfFaceName, "MS Sans Serif");
  788.         else
  789.              _tcscpy(lf.lfFaceName, IntlGetUIPropFaceName(CIntlWin::GetSystemLocaleCsid()));
  790.         lf.lfHeight = -MulDiv(9, ::GetDeviceCaps(hDC, LOGPIXELSY), 72);
  791.         m_hFont = theApp.CreateAppFont( lf );
  792.         ::ReleaseDC(m_hWnd,hDC);
  793.     }
  794.     return m_hFont;
  795. }
  796.  
  797.  
  798. void * CNameCompletionOutliner::AcquireLineData ( int line )
  799. {
  800.     m_lineindex = line + 1;
  801.     if ( line >= m_iTotalLines)
  802.         return NULL;
  803.     if (!AB_GetEntryLine(m_pane, line, &m_EntryLine ))
  804.         return NULL;
  805.  
  806.     return &m_EntryLine;
  807. }
  808.  
  809.  
  810. void CNameCompletionOutliner::GetTreeInfo ( int iLine, uint32 * pFlags, int * pDepth, OutlinerAncestorInfo ** pAncestor )
  811. {
  812.     if ( pFlags ) *pFlags = 0; // Flags? 
  813.     if ( pDepth ) *pDepth = 0; // We're flat, remember?
  814. }
  815.  
  816.  
  817. void CNameCompletionOutliner::ReleaseLineData ( void * )
  818. {
  819. }
  820.  
  821.  
  822. LPCTSTR CNameCompletionOutliner::GetColumnText ( UINT iColumn, void * pLineData )
  823. {
  824.     AB_EntryLine* line = (AB_EntryLine*) pLineData;
  825.  
  826.     switch (iColumn) {
  827.         case ID_COLADDR_NAME:
  828.             return line->fullname;
  829.             break;
  830.         case ID_COLADDR_EMAIL:
  831.             return line->emailAddress;
  832.             break;
  833.         case ID_COLADDR_COMPANY:
  834.             return line->companyName;
  835.             break;
  836.         case ID_COLADDR_PHONE:
  837.             if (line->entryType == ABTypePerson)
  838.                 return line->workPhone;
  839.             break;
  840.         case ID_COLADDR_LOCALITY:
  841.             return line->locality;
  842.             break;
  843.         case ID_COLADDR_NICKNAME:
  844.             return line->nickname;
  845.             break;
  846.         default:
  847.             break;
  848.     }
  849.     return ("");
  850. }
  851.  
  852. void CNameCompletionOutliner::OnSelChanged()
  853. {
  854. #ifdef _WIN32
  855.     CWnd *pParent = GetParentOwner();
  856. #else
  857.     CWnd *pParent = GetOwner();      
  858.     pParent = pParent->GetParent();
  859.     ASSERT(pParent);
  860. #endif
  861.     ((CNameCompletion*) pParent)->UpdateButtons();
  862. }
  863.  
  864. void CNameCompletionOutliner::OnSelDblClk()
  865. {
  866. #ifdef _WIN32
  867.     CWnd *pParent = GetParentOwner();
  868. #else
  869.     CWnd *pParent = GetOwner();      
  870.     pParent = pParent->GetParent();
  871.     ASSERT(pParent);
  872. #endif
  873. }
  874.  
  875. /////////////////////////////////////////////////////////////////////////////
  876. // CAddrOutlinerParent
  877.  
  878. BEGIN_MESSAGE_MAP(CNameCompletionOutlinerParent, COutlinerParent)
  879.     //{{AFX_MSG_MAP(CNameCompletionOutlinerParent)
  880.     ON_WM_LBUTTONUP()
  881.     //}}AFX_MSG_MAP
  882. END_MESSAGE_MAP()
  883.  
  884. CNameCompletionOutlinerParent::CNameCompletionOutlinerParent()
  885. {
  886.  
  887. }
  888.  
  889.  
  890. CNameCompletionOutlinerParent::~CNameCompletionOutlinerParent()
  891. {
  892. }
  893.  
  894.  
  895. BOOL CNameCompletionOutlinerParent::RenderData ( int idColumn, CRect & rect, CDC &dc, const char * text )
  896. {
  897.     int cx = 3, cy = 0;
  898.     CNameCompletionOutliner *pOutliner = (CNameCompletionOutliner *) m_pOutliner;
  899.     
  900.     // Calculate text offset from top using font height.
  901.     TEXTMETRIC tm;
  902.     dc.GetTextMetrics ( &tm );
  903.     cy = ( rect.bottom - rect.top - tm.tmHeight ) / 2;
  904.         
  905.     // Draw Text String
  906.     dc.TextOut (rect.left + cx, rect.top + cy, text, _tcslen(text) );
  907.  
  908.     return TRUE;
  909. }
  910.  
  911.  
  912. COutliner * CNameCompletionOutlinerParent::GetOutliner ( void )
  913. {
  914.     return new CNameCompletionOutliner;
  915. }
  916.  
  917.  
  918. void CNameCompletionOutlinerParent::CreateColumns ( void )
  919.     CString cs; 
  920.  
  921.     m_pOutliner->AddColumn ("",        ID_COLADDR_TYPE,            24, 0, ColumnFixed, 0, TRUE );
  922.     cs.LoadString(IDS_USERNAME);
  923.     m_pOutliner->AddColumn (cs,            ID_COLADDR_NAME,        175, 0, ColumnVariable, 1500);
  924.     cs.LoadString(IDS_EMAILADDRESS);
  925.     m_pOutliner->AddColumn (cs,            ID_COLADDR_EMAIL,        175, 0, ColumnVariable, 1500); 
  926.     cs.LoadString(IDS_COMPANYNAME);
  927.     m_pOutliner->AddColumn (cs,            ID_COLADDR_COMPANY,        175, 0, ColumnVariable, 1500 ); 
  928.     cs.LoadString(IDS_PHONE);
  929.     m_pOutliner->AddColumn (cs,            ID_COLADDR_PHONE,        175, 0, ColumnVariable, 1500, FALSE);
  930.     cs.LoadString(IDS_LOCALITY);
  931.     m_pOutliner->AddColumn (cs,            ID_COLADDR_LOCALITY,    175, 0, ColumnVariable, 1500 );
  932.     cs.LoadString(IDS_NICKNAME);
  933.     m_pOutliner->AddColumn (cs,            ID_COLADDR_NICKNAME,    175, 0, ColumnVariable, 1500 );
  934.     m_pOutliner->SetHasPipes( FALSE );
  935.  
  936.     m_pOutliner->SetVisibleColumns(DEF_VISIBLE_COLUMNS);
  937.     m_pOutliner->LoadXPPrefs("mailnews.abook_columns_win");
  938.  
  939. }
  940.  
  941.  
  942. BOOL CNameCompletionOutlinerParent::ColumnCommand ( int idColumn )
  943. {    
  944.     ABID lastSelection;
  945.  
  946.     CNameCompletionOutliner *pOutliner = (CNameCompletionOutliner *) m_pOutliner;
  947.     
  948.     if (pOutliner->GetFocusLine() != -1)
  949.         lastSelection = AB_GetEntryIDAt((AddressPane*) pOutliner->GetPane(), pOutliner->GetFocusLine());
  950.  
  951.     SetCursor ( theApp.LoadStandardCursor ( IDC_WAIT ) );
  952.  
  953.     switch (idColumn) {
  954.         case ID_COLADDR_TYPE:
  955.             AB_Command(pOutliner->GetPane(), AB_SortByTypeCmd, 0, 0);
  956.             break;
  957.         case ID_COLADDR_NAME:
  958.             AB_Command(pOutliner->GetPane(), AB_SortByFullNameCmd, 0, 0);
  959.             break;
  960.         case ID_COLADDR_NICKNAME:
  961.             AB_Command(pOutliner->GetPane(), AB_SortByNickname, 0, 0);
  962.             break;
  963.         case ID_COLADDR_LOCALITY:
  964.             AB_Command(pOutliner->GetPane(), AB_SortByLocality, 0, 0);
  965.             break;
  966.         case ID_COLADDR_COMPANY:
  967.             AB_Command(pOutliner->GetPane(), AB_SortByCompanyName, 0, 0);
  968.             break;
  969.         case ID_COLADDR_EMAIL:
  970.             AB_Command(pOutliner->GetPane(), AB_SortByEmailAddress, 0, 0);
  971.             break;
  972.         default:
  973.             AB_Command(pOutliner->GetPane(), AB_SortByFullNameCmd, 0, 0);
  974.             break;
  975.     }
  976.     
  977.  
  978.     if (pOutliner->GetFocusLine() != -1) {
  979.         uint index = CASTUINT(AB_GetIndexOfEntryID ((AddressPane*) pOutliner->GetPane(), lastSelection));
  980.         pOutliner->SelectItem (index);
  981.         pOutliner->ScrollIntoView(index);
  982.     }
  983.  
  984.     Invalidate();
  985.     pOutliner->Invalidate();
  986.     SetCursor ( theApp.LoadStandardCursor ( IDC_ARROW ) );
  987.     return TRUE;
  988. }
  989.  
  990. void CNameCompletionOutlinerParent::OnLButtonUp( UINT nFlags, CPoint point )
  991. {
  992.     BOOL bSaveColumns = (m_pOutliner && 
  993.         (m_bResizeColumn || m_bDraggingHeader || m_iPusherHit))? TRUE : FALSE;
  994.     COutlinerParent::OnLButtonUp(nFlags, point);
  995.     if (bSaveColumns)
  996.         m_pOutliner->SaveXPPrefs("mailnews.autocomp_columns_win");
  997. }
  998.  
  999.  
  1000. void CNameCompletion::OnHelp() 
  1001. {
  1002.     NetHelp(HELP_SELECT_ADDRESSES);
  1003. }
  1004.  
  1005.  
  1006. void CNameCompletion::UpdateButtons()
  1007. {
  1008.     if (m_pOutliner)
  1009.     {
  1010.         // need to determine when to actually enable this
  1011.         BOOL bEnable = TRUE;
  1012.         GetDlgItem(IDOK)->EnableWindow(bEnable);
  1013.     }
  1014. }
  1015.  
  1016.