home *** CD-ROM | disk | FTP | other *** search
/ Computer Shopper 217 / DPCS0306DVD.ISO / Toolkit / Internet / FileZilla / Server / FileZilla_Server-0.9.11.exe / source / interface / misc / SAPrefsDialog.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2004-12-01  |  14.6 KB  |  613 lines

  1. /*********************************************************************
  2.  
  3.    SAPrefsDialog
  4.  
  5.    Copyright (C) 2000 Smaller Animals Software, Inc.
  6.  
  7.    This software is provided 'as-is', without any express or implied
  8.    warranty.  In no event will the authors be held liable for any damages
  9.    arising from the use of this software.
  10.  
  11.    Permission is granted to anyone to use this software for any purpose,
  12.    including commercial applications, and to alter it and redistribute it
  13.    freely, subject to the following restrictions:
  14.  
  15.    1. The origin of this software must not be misrepresented; you must not
  16.      claim that you wrote the original software. If you use this software
  17.      in a product, an acknowledgment in the product documentation would be
  18.      appreciated but is not required.
  19.  
  20.    2. Altered source versions must be plainly marked as such, and must not be
  21.      misrepresented as being the original software.
  22.  
  23.    3. This notice may not be removed or altered from any source distribution.
  24.  
  25.    http://www.smalleranimals.com
  26.    smallest@smalleranimals.com
  27.  
  28. **********************************************************************/
  29.  
  30. // SAPrefsDialog.cpp : implementation file
  31. //
  32.  
  33. #include "stdafx.h"
  34. #include "../resource.h"
  35. #include "SAPrefsDialog.h"
  36.  
  37. #if defined(_DEBUG) && !defined(MMGR)
  38. #define new DEBUG_NEW
  39. #undef THIS_FILE
  40. static char THIS_FILE[] = __FILE__;
  41. #endif
  42.  
  43. /////////////////////////////////////////////////////////////////////////////
  44. // CSAPrefsDialog dialog
  45.  
  46.  
  47. CSAPrefsDialog::CSAPrefsDialog(UINT nIDTemplate /*=CSAPrefsDialog::IDD*/, CWnd* pParent /*=NULL*/)
  48.     : CDialog(nIDTemplate, pParent)
  49. {
  50.     //{{AFX_DATA_INIT(CSAPrefsDialog)
  51.     //}}AFX_DATA_INIT
  52.  
  53.    m_iCurPage = -1;
  54.    m_pages.clear();
  55.  
  56.     m_pStartPage = NULL;
  57. }
  58.  
  59. /////////////////////////////////////////////////////////////////////////////
  60.  
  61. CSAPrefsDialog::~CSAPrefsDialog()
  62. {
  63.     // clean up
  64.    for (unsigned int i = 0; i < m_pages.size(); i++)
  65.    {
  66.       pageStruct *pPS = m_pages[i];
  67.       if (pPS)
  68.          delete pPS;
  69.    }
  70. }
  71.  
  72. /////////////////////////////////////////////////////////////////////////////
  73.  
  74. void CSAPrefsDialog::DoDataExchange(CDataExchange* pDX)
  75. {
  76.     CDialog::DoDataExchange(pDX);
  77.     //{{AFX_DATA_MAP(CSAPrefsDialog)
  78.     DDX_Control(pDX, IDC_PAGE_TREE, m_pageTree);
  79.     DDX_Control(pDX, IDC_DLG_FRAME, m_boundingFrame);
  80.     //}}AFX_DATA_MAP
  81.     if (GetDlgItem(IDC_CAPTION_BAR))
  82.     {
  83.         DDX_Control(pDX, IDC_CAPTION_BAR, m_captionBar);
  84.     }
  85.  
  86. }
  87.  
  88.  
  89. BEGIN_MESSAGE_MAP(CSAPrefsDialog, CDialog)
  90.     //{{AFX_MSG_MAP(CSAPrefsDialog)
  91.     ON_WM_CREATE()
  92.     ON_NOTIFY(TVN_SELCHANGED, IDC_PAGE_TREE, OnSelchangedPageTree)
  93.     ON_NOTIFY(TVN_GETDISPINFO, IDC_PAGE_TREE, OnGetdispinfoPageTree)
  94.     ON_BN_CLICKED(IDC_PHELP, OnPhelp)
  95.     //}}AFX_MSG_MAP
  96.     ON_MESSAGE(WM_CHANGE_PAGE, OnChangePage)
  97. END_MESSAGE_MAP()
  98.  
  99. /////////////////////////////////////////////////////////////////////////////
  100. // CSAPrefsDialog message handlers
  101.  
  102. /////////////////////////////////////////////////////////////////////////////
  103.  
  104. BOOL CSAPrefsDialog::PreTranslateMessage(MSG* pMsg) 
  105. {
  106.     ASSERT(pMsg != NULL);
  107.    ASSERT_VALID(this);
  108.    ASSERT(m_hWnd != NULL);
  109.  
  110.     // Don't let CDialog process the Escape key.
  111.     if ((pMsg->message == WM_KEYDOWN) && (pMsg->wParam == VK_ESCAPE))
  112.     {
  113.     //    return TRUE;
  114.     }
  115.  
  116.     if (CWnd::PreTranslateMessage(pMsg))
  117.       return TRUE;
  118.  
  119.    // don't translate dialog messages when 
  120.    // application is in help mode
  121.    CFrameWnd* pFrameWnd = GetTopLevelFrame();
  122.    if (pFrameWnd != NULL && pFrameWnd->m_bHelpMode)
  123.       return FALSE;
  124.  
  125.    // ensure the dialog messages will not
  126.    // eat frame accelerators
  127.    pFrameWnd = GetParentFrame();
  128.    while (pFrameWnd != NULL)
  129.    {
  130.       if (pFrameWnd->PreTranslateMessage(pMsg))
  131.          return TRUE;
  132.       pFrameWnd = pFrameWnd->GetParentFrame();
  133.    }
  134.  
  135.    return PreTranslateInput(pMsg);
  136.  
  137. }
  138.  
  139. /////////////////////////////////////////////////////////////////////////////
  140.  
  141. int CSAPrefsDialog::OnCreate(LPCREATESTRUCT lpCreateStruct) 
  142. {
  143.     if (CDialog::OnCreate(lpCreateStruct) == -1)
  144.         return -1;
  145.     
  146.     return 0;
  147. }
  148.  
  149. /////////////////////////////////////////////////////////////////////////////
  150.  
  151. BOOL CSAPrefsDialog::OnInitDialog() 
  152. {
  153.     CDialog::OnInitDialog();
  154.     
  155.     long l = GetWindowLong(m_pageTree.m_hWnd, GWL_STYLE);
  156. #if (_MSC_VER > 1100)
  157.     l = l | TVS_TRACKSELECT ;
  158. #else
  159.     //#define TVS_TRACKSELECT         0x0200
  160.     l = l | 0x0200;
  161. #endif
  162.     SetWindowLong(m_pageTree.m_hWnd, GWL_STYLE, l);
  163.     
  164.     // where will the dlgs live?
  165.     m_boundingFrame.GetWindowRect(m_frameRect);
  166.     ScreenToClient(m_frameRect);
  167.     //   m_frameRect.DeflateRect(2,2);
  168.     
  169.     if (m_csTitle != "")
  170.         SetWindowText(m_csTitle);
  171.     
  172.     // set some styles for the pretty page indicator bar
  173.     if (::IsWindow(m_captionBar.m_hWnd))
  174.     {
  175.         m_captionBar.m_textClr     = ::GetSysColor(COLOR_3DFACE);
  176.         m_captionBar.m_fontWeight  = FW_BOLD;
  177.         m_captionBar.m_fontSize    = 14;
  178.         m_captionBar.m_csFontName  = "Verdana";
  179.         m_captionBar.SetConstantText(m_csConstantText);
  180.     }
  181.     
  182.     // fill the tree. we'll create the pages as we need them
  183.     unsigned int i;
  184.     for (i = 0; i <m_pages.size(); i++)
  185.     {
  186.         pageStruct *pPS = m_pages[i];
  187.         ASSERT(pPS);
  188.         ASSERT(pPS->pDlg);
  189.         if (pPS)
  190.         {
  191.             TV_INSERTSTRUCT tvi;
  192.             
  193.             // find this node's parent...
  194.             tvi.hParent = FindHTREEItemForDlg(pPS->pDlgParent);
  195.             
  196.             tvi.hInsertAfter = TVI_LAST;
  197.             tvi.item.cchTextMax = 0;
  198.             tvi.item.pszText = LPSTR_TEXTCALLBACK;
  199.             tvi.item.lParam = (long)pPS;
  200.             tvi.item.mask = TVIF_PARAM | TVIF_TEXT;
  201.             
  202.             HTREEITEM hTree = m_pageTree.InsertItem(&tvi);
  203.             m_pageTree.Expand(tvi.hParent,TVE_EXPAND);
  204.             
  205.             // keep track of the dlg's we've added (for parent selection)
  206.             if (hTree)
  207.             {
  208.                 DWORD dwTree = (DWORD)hTree;
  209.                 m_dlgMap[pPS->pDlg]=dwTree;
  210.             }
  211.         }
  212.     }
  213.  
  214.     for (i = 0; i < m_pages.size(); i++)
  215.         // if we haven't already, Create the dialog
  216.         if (!::IsWindow(m_pages[i]->pDlg->m_hWnd))
  217.         {
  218.             m_pages[i]->pDlg->Create(m_pages[i]->pDlg->GetID(), this);
  219.         }
  220.     
  221.     // start with page 0
  222.     if (m_pStartPage == NULL)
  223.     {
  224.         if (ShowPage(0))
  225.         {
  226.             m_iCurPage = 0;   
  227.         }
  228.     }
  229.     else
  230.     {
  231.         // find start page
  232.         for (unsigned int i = 0; i <m_pages.size(); i++)
  233.         {
  234.             pageStruct *pPS = m_pages[i];
  235.             ASSERT(pPS);
  236.             if (pPS)
  237.             {
  238.                 ASSERT(pPS->pDlg);
  239.                 if (pPS->pDlg == m_pStartPage)
  240.                 {
  241.                     ShowPage(i);
  242.                     m_iCurPage = i;
  243.                     break;
  244.                 }
  245.             }
  246.         }
  247.     }
  248.     
  249.     return TRUE;  // return TRUE unless you set the focus to a control
  250.     // EXCEPTION: OCX Property Pages should return FALSE
  251. }
  252.  
  253. /////////////////////////////////////////////////////////////////////////////
  254.  
  255. HTREEITEM CSAPrefsDialog::FindHTREEItemForDlg(CSAPrefsSubDlg *pParent)
  256. {
  257.    // if you didn't specify a parent in AddPage(...) , the
  258.    // dialog becomes a root-level entry
  259.     if (pParent==NULL)
  260.     {
  261.         return TVI_ROOT;
  262.     }
  263.    else
  264.    {
  265.       std::map<CSAPrefsSubDlg *, DWORD>::iterator iter=m_dlgMap.find(pParent);
  266.       if (iter!=m_dlgMap.end())
  267.           return (HTREEITEM)iter->second;
  268.       else
  269.       {
  270.          // you have specified a parent that has not 
  271.          // been added to the tree - can't do that.
  272.          ASSERT(FALSE);
  273.          return TVI_ROOT;
  274.       }
  275.    }
  276. }
  277.  
  278. /////////////////////////////////////////////////////////////////////////////
  279.  
  280. LONG CSAPrefsDialog::OnChangePage(UINT u, LONG l)
  281. {
  282.    if (ShowPage(u))
  283.    {
  284.       m_iCurPage = u;   
  285.    }
  286.  
  287.     return 0L;
  288. }
  289.  
  290. /////////////////////////////////////////////////////////////////////////////
  291.  
  292. bool CSAPrefsDialog::AddPage(CSAPrefsSubDlg &dlg, const char *pCaption, CSAPrefsSubDlg* pDlgParent /*=NULL*/)
  293. {
  294.     if (m_hWnd)
  295.     {
  296.         // can't add once the window has been created
  297.         ASSERT(0);
  298.         return false;
  299.     }
  300.  
  301.    pageStruct *pPS = new pageStruct;
  302.    pPS->pDlg = &dlg;
  303.    pPS->id = dlg.GetID();
  304.    pPS->csCaption = pCaption;
  305.    pPS->pDlgParent = pDlgParent;
  306.  
  307.    m_pages.push_back(pPS);
  308.  
  309.    return true;
  310. }
  311.  
  312. /////////////////////////////////////////////////////////////////////////////
  313.  
  314. BOOL CSAPrefsDialog::PreCreateWindow(CREATESTRUCT& cs) 
  315. {
  316.     if (!CWnd::PreCreateWindow(cs))
  317.       return FALSE;
  318.  
  319.    cs.lpszClass = AfxRegisterWndClass(CS_DBLCLKS, NULL, NULL, NULL);
  320.    cs.style |= WS_CLIPCHILDREN;
  321.    return TRUE;
  322. }
  323.  
  324. /////////////////////////////////////////////////////////////////////////////
  325.  
  326. bool CSAPrefsDialog::ShowPage(CSAPrefsSubDlg * pPage)
  327. {
  328.    // find that page
  329.     for (unsigned int i = 0; i < m_pages.size(); i++)
  330.     {
  331.         pageStruct *pPS = m_pages[i];
  332.         ASSERT(pPS);
  333.         if (pPS)
  334.         {
  335.             ASSERT(pPS->pDlg);
  336.             if (pPS->pDlg == pPage)
  337.             {
  338.                 ShowPage(i);
  339.                 m_iCurPage = i;
  340.                 return true;
  341.             }
  342.         }
  343.     }
  344.  
  345.    return false;
  346. }
  347.  
  348. /////////////////////////////////////////////////////////////////////////////
  349.  
  350. bool CSAPrefsDialog::ShowPage(int iPage)
  351. {
  352.     if (::IsWindow(m_captionBar.m_hWnd))
  353.    m_captionBar.SetWindowText("");
  354.  
  355.     // turn off the current page
  356.    if ((m_iCurPage >= 0) && (m_iCurPage < (int)m_pages.size()))
  357.    {
  358.       pageStruct *pPS = m_pages[m_iCurPage];
  359.       ASSERT(pPS);
  360.       if (pPS)
  361.       {
  362.          ASSERT(pPS->pDlg);
  363.          if (pPS->pDlg)
  364.          {
  365.             if (::IsWindow(pPS->pDlg->m_hWnd))
  366.             {
  367.                pPS->pDlg->ShowWindow(SW_HIDE);
  368.             }
  369.          }
  370.       }
  371.       else
  372.       {
  373.          return false;
  374.       }
  375.    }
  376.  
  377.     // show the new one
  378.    if ((iPage >= 0) && (iPage < (int)m_pages.size()))
  379.    {
  380.       pageStruct *pPS = m_pages[iPage];
  381.       ASSERT(pPS);
  382.  
  383.       if (pPS)
  384.       {
  385.          ASSERT(pPS->pDlg);
  386.          if (pPS->pDlg)
  387.          {
  388.  
  389.                // update caption bar
  390.              if (::IsWindow(m_captionBar.m_hWnd))
  391.             m_captionBar.SetWindowText(pPS->csCaption);
  392.  
  393.             // if we haven't already, Create the dialog
  394.             if (!::IsWindow(pPS->pDlg->m_hWnd))
  395.             {
  396.                pPS->pDlg->Create(pPS->pDlg->GetID(), this);
  397.             }
  398.          
  399.             // move, show, focus
  400.             if (::IsWindow(pPS->pDlg->m_hWnd))
  401.             {
  402.                pPS->pDlg->MoveWindow(m_frameRect.left, m_frameRect.top, m_frameRect.Width(), m_frameRect.Height());
  403.                pPS->pDlg->ShowWindow(SW_SHOW);
  404.                pPS->pDlg->SetFocus();
  405.             }
  406.  
  407.             // change the tree
  408.  
  409.             // find this in our map
  410.             HTREEITEM hItem = FindHTREEItemForDlg(pPS->pDlg);
  411.             if (hItem)
  412.             {
  413.                // select it
  414.                m_pageTree.SelectItem(hItem);
  415.             }
  416.             return true;
  417.          }
  418.       }
  419.    }
  420.  
  421.    return false;
  422. }
  423.  
  424. /////////////////////////////////////////////////////////////////////////////
  425.  
  426. void CSAPrefsDialog::OnOK() 
  427. {
  428.    // if EndOK returns true, all of the UpdateData(TRUE)'s succeeded
  429.    if (EndOK())
  430.    {
  431.        CDialog::OnOK();
  432.    }
  433. }
  434.  
  435. /////////////////////////////////////////////////////////////////////////////
  436.  
  437. bool CSAPrefsDialog::EndOK()
  438. {
  439.    bool bOK = true;
  440.  
  441.    CSAPrefsSubDlg * pPage = NULL;
  442.  
  443.     // first, UpdateData...
  444.    unsigned int i;
  445.    for (i = 0; i < m_pages.size(); i++)
  446.    {
  447.       pageStruct *pPS = m_pages[i];
  448.       ASSERT(pPS);
  449.       if (pPS)
  450.       {
  451.          ASSERT(pPS->pDlg);
  452.          if (pPS->pDlg)
  453.          {
  454.             if (::IsWindow(pPS->pDlg->m_hWnd))
  455.             {
  456.                if (!pPS->pDlg->UpdateData(TRUE))
  457.                {
  458.                   bOK = false;
  459.                   pPage = pPS->pDlg;
  460.                   break;
  461.                }
  462.             }
  463.          }
  464.       }
  465.    }
  466.  
  467.    // were there any UpdateData errors?
  468.    if ((!bOK) && (pPage!=NULL))
  469.    {
  470.       ShowPage(pPage);
  471.       return false;
  472.    }
  473.  
  474.    // tell all of the sub-dialogs "OK"
  475.    for ( i = 0; i < m_pages.size(); i++)
  476.    {
  477.       pageStruct *pPS = m_pages[i];
  478.       ASSERT(pPS);
  479.       if (pPS)
  480.       {
  481.          ASSERT(pPS->pDlg);
  482.          if (pPS->pDlg)
  483.          {
  484.             if (::IsWindow(pPS->pDlg->m_hWnd))
  485.             {
  486.                pPS->pDlg->OnOK();
  487.             }
  488.          }
  489.       }
  490.    }
  491.  
  492.    return true;
  493. }
  494.  
  495. /////////////////////////////////////////////////////////////////////////////
  496.  
  497. void CSAPrefsDialog::OnCancel() 
  498. {
  499.     // tell all of the sub-dialogs "Cancel"
  500.    for (unsigned int i = 0; i < m_pages.size(); i++)
  501.    {
  502.       pageStruct *pPS = m_pages[i];
  503.       ASSERT(pPS);
  504.       
  505.       if (pPS)
  506.       {
  507.          ASSERT(pPS->pDlg);
  508.          if (pPS->pDlg)
  509.          {
  510.             if (::IsWindow(pPS->pDlg->m_hWnd))
  511.             {
  512.                pPS->pDlg->OnCancel();
  513.             }
  514.          }
  515.       }
  516.    }
  517.  
  518.     CDialog::OnCancel();
  519. }
  520.  
  521.  
  522. /////////////////////////////////////////////////////////////////////////////
  523.  
  524. void CSAPrefsDialog::EndSpecial(UINT res, bool bOk)
  525. {
  526.    if (bOk)
  527.    {
  528.       EndOK();
  529.    }
  530.  
  531.     EndDialog(res);
  532. }
  533.  
  534. /////////////////////////////////////////////////////////////////////////////
  535.  
  536. void CSAPrefsDialog::OnSelchangedPageTree(NMHDR* pNMHDR, LRESULT* pResult) 
  537. {
  538.     NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
  539.  
  540.    if (pNMTreeView->itemNew.lParam)
  541.    {
  542.         // find out which page was selected
  543.       int iIdx = -1;
  544.       for (unsigned int i = 0; i < m_pages.size(); i++)
  545.       {
  546.          if (m_pages[i]==(pageStruct *)pNMTreeView->itemNew.lParam)
  547.          {
  548.             iIdx = i;
  549.             break;
  550.          }
  551.       }
  552.  
  553.         // show that page
  554.       if ((iIdx >= 0) && (iIdx < (int)m_pages.size()))
  555.       {
  556.          pageStruct *pPS = m_pages[iIdx];
  557.          if (m_iCurPage!=iIdx)
  558.          {
  559.                 PostMessage(WM_CHANGE_PAGE, iIdx);
  560.          }
  561.       }
  562.    }
  563.  
  564.     *pResult = 0;
  565. }
  566.  
  567. /////////////////////////////////////////////////////////////////////////////
  568.  
  569. void CSAPrefsDialog::OnGetdispinfoPageTree(NMHDR* pNMHDR, LRESULT* pResult) 
  570. {
  571.     TV_DISPINFO* pTVDispInfo = (TV_DISPINFO*)pNMHDR;
  572.  
  573.     // return the caption of the appropriate dialog
  574.    if (pTVDispInfo->item.lParam)
  575.    {
  576.       if (pTVDispInfo->item.mask & TVIF_TEXT)
  577.       {
  578.          pageStruct *pPS = (pageStruct *)pTVDispInfo->item.lParam;
  579.          strcpy(pTVDispInfo->item.pszText, pPS->csCaption);
  580.       }
  581.    }
  582.    
  583.     *pResult = 0;
  584. }
  585.  
  586. /////////////////////////////////////////////////////////////////////////////
  587.  
  588. void CSAPrefsDialog::OnPhelp() 
  589. {
  590.     // simulate the property sheet method of sending Help (with WM_NOTIFY)
  591.    if ((m_iCurPage >= 0) && (m_iCurPage < (int)m_pages.size()))
  592.    {
  593.       pageStruct *pPS = m_pages[m_iCurPage];
  594.       ASSERT(pPS);
  595.       ASSERT(pPS->pDlg);
  596.       if (pPS)
  597.       {
  598.          if (pPS->pDlg)
  599.          {
  600.             if (::IsWindow(pPS->pDlg->m_hWnd))
  601.             {
  602.                // help!
  603.                   NMHDR nm;
  604.                   nm.code=PSN_HELP;
  605.                   nm.hwndFrom=m_hWnd;
  606.                   nm.idFrom=CSAPrefsDialog::IDD;
  607.                   pPS->pDlg->SendMessage(WM_NOTIFY, 0, (long)&nm);
  608.             }
  609.          }
  610.         }
  611.     }
  612. }
  613.