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

  1. ////////////////////////////////////////////////////////////////////////////
  2. //
  3. // splitex.cpp
  4. // Based upon code from Oleg G. Galkin
  5. // Modified to handle multiple hidden rows
  6.  
  7. #include "stdafx.h"
  8. #include "splitex.h"
  9.  
  10. #if defined(_DEBUG) && !defined(MMGR)
  11. #define new DEBUG_NEW
  12. #undef THIS_FILE
  13. static char THIS_FILE[] = __FILE__;
  14. #endif
  15.  
  16. ////////////////////////////////////////////////////////////////////////////
  17. //
  18. // CSplitterWndEx
  19.  
  20. CSplitterWndEx::CSplitterWndEx()
  21. {
  22.     m_arr = 0;
  23. }
  24.  
  25. CSplitterWndEx::~CSplitterWndEx()
  26. {
  27.     if (m_arr)
  28.         delete [] m_arr;
  29. }
  30.  
  31. int CSplitterWndEx::Id_short(int row, int col)
  32. {
  33.     return AFX_IDW_PANE_FIRST + row * 16 + col;
  34. }
  35.  
  36. void CSplitterWndEx::ShowRow(int r)
  37. {
  38.     ASSERT_VALID(this);
  39.     ASSERT(m_nRows < m_nMaxRows);
  40.  
  41.     ASSERT(m_arr);
  42.     ASSERT(r < m_length);
  43.     ASSERT(m_arr[r] >= m_nRows);
  44.     ASSERT(m_arr[r] < m_length);
  45.  
  46.     int rowNew = r;
  47.     int cyNew = m_pRowInfo[m_arr[r]].nCurSize;
  48.     int cyIdealNew = m_pRowInfo[m_arr[r]].nIdealSize;
  49.     
  50.     int new_val = 0;
  51.  
  52.     for (int i = rowNew - 1; i >= 0; i--)
  53.         if (m_arr[i] < m_nRows)    // not hidden
  54.         {
  55.             new_val = m_arr[i] + 1;
  56.             break;
  57.         }
  58.  
  59.     int old_val = m_arr[rowNew];
  60.  
  61.     m_nRows++;  // add a row
  62.  
  63.     // fill the hided row
  64.     int row;
  65.     for (int col = 0; col < m_nCols; col++)
  66.     {
  67.         CWnd* pPaneShow = GetDlgItem(
  68.             Id_short(old_val, col));
  69.         ASSERT(pPaneShow != NULL);
  70.         pPaneShow->ShowWindow(SW_SHOWNA);
  71.  
  72.         for (row = m_length - 1; row >= 0; row--)
  73.         {
  74.             if ((m_arr[row] >= new_val) &&
  75.                 (m_arr[row] < old_val))
  76.             {
  77.                 CWnd* pPane = CSplitterWnd::GetPane(m_arr[row], col);
  78.                 ASSERT(pPane != NULL);
  79.                 pPane->SetDlgCtrlID(Id_short(m_arr[row] + 1, col));
  80.             }
  81.         }
  82.         pPaneShow->SetDlgCtrlID(Id_short(new_val, col));
  83.     }
  84.  
  85.     for (row = 0; row < m_length; row++)
  86.         if ((m_arr[row] >= new_val) &&
  87.             (m_arr[row] < old_val))
  88.             m_arr[row]++;
  89.  
  90.     m_arr[rowNew] = new_val;
  91.  
  92.     //new panes have been created -- recalculate layout
  93.     for (row = new_val + 1; row < m_length; row++)
  94.     {
  95.         if (m_arr[row]<m_nRows)
  96.         {
  97.             m_pRowInfo[m_arr[row]].nIdealSize = m_pRowInfo[m_arr[row-1]].nCurSize;
  98.             m_pRowInfo[m_arr[row]].nCurSize = m_pRowInfo[m_arr[row-1]].nCurSize;
  99.         }
  100.     }
  101.     if (cyNew>=0x10000)
  102.     {
  103.         int rowToResize=(cyNew>>16)-1;
  104.         cyNew%=0x10000;
  105.         cyIdealNew%=0x10000;
  106.         m_pRowInfo[m_arr[rowToResize]].nCurSize-=cyNew+m_cxSplitter;
  107.         m_pRowInfo[m_arr[rowToResize]].nIdealSize=m_pRowInfo[m_arr[rowToResize]].nCurSize;//-=cyIdealNew+m_cxSplitter;
  108.     }
  109.  
  110.     m_pRowInfo[new_val].nIdealSize = cyNew;
  111.     m_pRowInfo[new_val].nCurSize = cyNew;
  112.     RecalcLayout();
  113. }
  114.  
  115. void CSplitterWndEx::ShowColumn(int c)
  116. {
  117.     ASSERT_VALID(this);
  118.     ASSERT(m_nCols < m_nMaxCols);
  119.  
  120.     ASSERT(m_arr);
  121.     ASSERT(c < m_length);
  122.     ASSERT(m_arr[c] >= m_nRows);
  123.     ASSERT(m_arr[c] < m_length);
  124.  
  125.     int colNew = c;
  126.     int cxNew = m_pColInfo[m_arr[c]].nCurSize;
  127.     int cxIdealNew = m_pColInfo[m_arr[c]].nIdealSize;
  128.     
  129.     int new_val = 0;
  130.  
  131.     for (int i = colNew - 1; i >= 0; i--)
  132.         if (m_arr[i] < m_nCols)    // not hidden
  133.         {
  134.             new_val = m_arr[i] + 1;
  135.             break;
  136.         }
  137.  
  138.     int old_val = m_arr[colNew];
  139.  
  140.     m_nCols++;  // add a col
  141.  
  142.     // fill the hided col
  143.     int col;
  144.     for (int row = 0; row < m_nRows; row++)
  145.     {
  146.         CWnd* pPaneShow = GetDlgItem(
  147.             Id_short(row, old_val));
  148.         ASSERT(pPaneShow != NULL);
  149.         pPaneShow->ShowWindow(SW_SHOWNA);
  150.  
  151.         for (col = m_length - 1; col >= 0; col--)
  152.         {
  153.             if ((m_arr[col] >= new_val) &&
  154.                 (m_arr[col] < old_val))
  155.             {
  156.                 CWnd* pPane = CSplitterWnd::GetPane(row, m_arr[col]);
  157.                 ASSERT(pPane != NULL);
  158.                 pPane->SetDlgCtrlID(Id_short(row, m_arr[col]+1));
  159.             }
  160.         }
  161.         pPaneShow->SetDlgCtrlID(Id_short(row, new_val));
  162.     }
  163.  
  164.     for (col = 0; col < m_length; col++)
  165.         if ((m_arr[col] >= new_val) &&
  166.             (m_arr[col] < old_val))
  167.             m_arr[col]++;
  168.  
  169.     m_arr[colNew] = new_val;
  170.  
  171.     //new panes have been created -- recalculate layout
  172.     for (col = new_val + 1; col < m_length; col++)
  173.     {
  174.         if (m_arr[col]<m_nCols)
  175.         {
  176.             m_pColInfo[m_arr[col]].nIdealSize = m_pColInfo[m_arr[col-1]].nCurSize;
  177.             m_pColInfo[m_arr[col]].nCurSize = m_pColInfo[m_arr[col-1]].nCurSize;
  178.         }
  179.     }
  180.     if (cxNew>=0x10000)
  181.     {
  182.         int colToResize=(cxNew>>16)-1;
  183.         cxNew%=0x10000;
  184.         cxIdealNew%=0x10000;
  185.         m_pColInfo[m_arr[colToResize]].nCurSize-=cxNew+m_cySplitter;
  186.         m_pColInfo[m_arr[colToResize]].nIdealSize=m_pColInfo[m_arr[colToResize]].nCurSize;//-=cxIdealNew+m_cySplitter;
  187.     }
  188.  
  189.     m_pColInfo[new_val].nIdealSize = cxNew;
  190.     m_pColInfo[new_val].nCurSize = cxNew;
  191.     RecalcLayout();
  192. }
  193.  
  194. void CSplitterWndEx::HideRow(int rowHide,int rowToResize)
  195. {
  196.     ASSERT_VALID(this);
  197.     ASSERT(m_nRows > 1);
  198.  
  199.     if (m_arr)
  200.         ASSERT(m_arr[rowHide] < m_nRows);
  201.  
  202.     // if the row has an active window -- change it
  203.     int rowActive, colActive;
  204.  
  205.     if (!m_arr)
  206.     {
  207.         m_arr = new int[m_nRows];
  208.         for (int i = 0; i < m_nRows; i++)
  209.             m_arr[i] = i;
  210.         m_length = m_nRows;
  211.     }
  212.  
  213.     if (GetActivePane(&rowActive, &colActive) != NULL &&
  214.         rowActive == rowHide) //colActive == rowHide)
  215.     {
  216.         if (++rowActive >= m_nRows)
  217.             rowActive = 0;
  218.         //SetActivePane(rowActive, colActive);
  219.  
  220.         SetActivePane(rowActive, colActive);
  221.     }
  222.  
  223.     // hide all row panes
  224.     for (int col = 0; col < m_nCols; col++)
  225.     {
  226.         CWnd* pPaneHide = CSplitterWnd::GetPane(m_arr[rowHide], col);
  227.         ASSERT(pPaneHide != NULL);
  228.         pPaneHide->ShowWindow(SW_HIDE);
  229.  
  230.         for (int row = rowHide + 1; row < m_length; row++)
  231.         {
  232.             if (m_arr[row] < m_nRows )
  233.             {
  234.                 CWnd* pPane = CSplitterWnd::GetPane(m_arr[row], col);
  235.                 ASSERT(pPane != NULL);
  236.                 pPane->SetDlgCtrlID(Id_short(row-1, col));
  237.                 m_arr[row]--;
  238.             }
  239.         }
  240.         pPaneHide->SetDlgCtrlID(
  241.             Id_short(m_nRows -1 , col));
  242.     }
  243.  
  244.     int oldsize=m_pRowInfo[m_arr[rowHide]].nCurSize;
  245.     int oldidealsize=m_pRowInfo[m_arr[rowHide]].nIdealSize;
  246.     for (int row=rowHide;row<(m_length-1);row++)
  247.     {
  248.         if (m_arr[row+1] < m_nRows )
  249.         {
  250.             m_pRowInfo[m_arr[row]].nCurSize=m_pRowInfo[m_arr[row+1]].nCurSize;
  251.             m_pRowInfo[m_arr[row]].nIdealSize=m_pRowInfo[m_arr[row+1]].nCurSize;        
  252.         }
  253.     }
  254.     if (rowToResize!=-1)
  255.     {
  256.         m_pRowInfo[m_arr[rowToResize]].nCurSize+=oldsize+m_cySplitter;
  257.         m_pRowInfo[m_arr[rowToResize]].nIdealSize+=oldsize+m_cySplitter;
  258.         oldsize+=0x10000*(rowToResize+1);
  259.         oldidealsize+=0x10000*(rowToResize+1);
  260.     }
  261.  
  262.     m_pRowInfo[m_nRows - 1].nCurSize =oldsize;
  263.     m_pRowInfo[m_nRows - 1].nIdealSize =oldsize;
  264.     
  265.     m_arr[rowHide] = m_nRows-1;
  266.     
  267.  
  268.     m_nRows--;
  269.     RecalcLayout();
  270. }
  271.  
  272. void CSplitterWndEx::HideColumn(int colHide, int colToResize)
  273. {
  274.     ASSERT_VALID(this);
  275.     ASSERT(m_nCols > 1);
  276.  
  277.     if (m_arr)
  278.         ASSERT(m_arr[colHide] < m_nCols);
  279.  
  280.     // if the col has an active window -- change it
  281.     int colActive, rowActive;
  282.  
  283.     if (!m_arr)
  284.     {
  285.         m_arr = new int[m_nCols];
  286.         for (int i = 0; i < m_nCols; i++)
  287.             m_arr[i] = i;
  288.         m_length = m_nCols;
  289.     }
  290.  
  291.     if (GetActivePane(&rowActive, &colActive) != NULL &&
  292.         colActive == colHide)
  293.     {
  294.         if (++colActive >= m_nCols)
  295.             colActive = 0;
  296.         SetActivePane(rowActive, colActive);
  297.     }
  298.  
  299.     // hide all row panes
  300.     for (int row = 0; row < m_nRows; row++)
  301.     {
  302.         CWnd* pPaneHide = CSplitterWnd::GetPane(row, m_arr[colHide]);
  303.         ASSERT(pPaneHide != NULL);
  304.         pPaneHide->ShowWindow(SW_HIDE);
  305.  
  306.         for (int col = colHide + 1; col < m_length; col++)
  307.         {
  308.             if (m_arr[col] < m_nCols )
  309.             {
  310.                 CWnd* pPane = CSplitterWnd::GetPane(row, m_arr[col]);
  311.                 ASSERT(pPane != NULL);
  312.                 pPane->SetDlgCtrlID(Id_short(row, col-1));
  313.                 m_arr[col]--;
  314.             }
  315.         }
  316.         pPaneHide->SetDlgCtrlID(
  317.             Id_short(row, m_nCols -1));
  318.     }
  319.  
  320.     int oldsize=m_pColInfo[m_arr[colHide]].nCurSize;
  321.     int oldidealsize=m_pColInfo[m_arr[colHide]].nIdealSize;
  322.     for (int col=colHide; col<(m_length-1); col++)
  323.     {
  324.         if (m_arr[col+1] < m_nCols )
  325.         {
  326.             m_pColInfo[m_arr[col]].nCurSize=m_pColInfo[m_arr[col+1]].nCurSize;
  327.             m_pColInfo[m_arr[col]].nIdealSize=m_pColInfo[m_arr[col+1]].nCurSize;        
  328.         }
  329.     }
  330.     if (colToResize!=-1)
  331.     {
  332.         m_pColInfo[m_arr[colToResize]].nCurSize+=oldsize+m_cxSplitter;
  333.         m_pColInfo[m_arr[colToResize]].nIdealSize+=oldsize+m_cxSplitter;
  334.         oldsize+=0x10000*(colToResize+1);
  335.         oldidealsize+=0x10000*(colToResize+1);
  336.     }
  337.  
  338.     m_pColInfo[m_nCols - 1].nCurSize =oldsize;
  339.     m_pColInfo[m_nCols - 1].nIdealSize =oldsize;
  340.     
  341.     m_arr[colHide] = m_nCols-1;
  342.  
  343.     m_nCols--;
  344.     RecalcLayout();
  345. }
  346.  
  347. BEGIN_MESSAGE_MAP(CSplitterWndEx, CSplitterWnd)
  348. //{{AFX_MSG_MAP(CSplitterWndEx)
  349.   // NOTE - the ClassWizard will add and remove mapping macros here.
  350. //}}AFX_MSG_MAP
  351. END_MESSAGE_MAP()
  352.  
  353. CWnd* CSplitterWndEx::GetPane(int row, int col)
  354. {
  355.     if (!m_arr)
  356.         return CSplitterWnd::GetPane(row,col);
  357.     else
  358.     {
  359.         ASSERT_VALID(this);
  360.  
  361.         CWnd* pView = GetDlgItem(IdFromRowCol(m_arr[row], col));
  362.         ASSERT(pView != NULL);  // panes can be a CWnd, but are usually CViews
  363.         return pView;
  364.     }
  365. }
  366.  
  367. int CSplitterWndEx::IdFromRowCol(int row, int col) const
  368. {
  369.     ASSERT_VALID(this);
  370.     ASSERT(row >= 0);
  371.     ASSERT(row < (m_arr?m_length:m_nRows));
  372.     ASSERT(col >= 0);
  373.     ASSERT(col < m_nCols);
  374.  
  375.     return AFX_IDW_PANE_FIRST + row * 16 + col;
  376. }
  377.  
  378. BOOL CSplitterWndEx::IsChildPane(CWnd* pWnd, int* pRow, int* pCol)
  379. {
  380.     ASSERT_VALID(this);
  381.     ASSERT_VALID(pWnd);
  382.  
  383.     UINT nID = ::GetDlgCtrlID(pWnd->m_hWnd);
  384.     if (IsChild(pWnd) && nID >= AFX_IDW_PANE_FIRST && nID <= AFX_IDW_PANE_LAST)
  385.     {
  386.         if (pWnd->GetParent()!=this)
  387.             return FALSE;
  388.         if (pRow != NULL)
  389.             *pRow = (nID - AFX_IDW_PANE_FIRST) / 16;
  390.         if (pCol != NULL)
  391.             *pCol = (nID - AFX_IDW_PANE_FIRST) % 16;
  392.         ASSERT(pRow == NULL || *pRow < (m_arr?m_length:m_nRows));
  393.         ASSERT(pCol == NULL || *pCol < m_nCols);
  394.         return TRUE;
  395.     }
  396.     else
  397.     {
  398.         if (pRow != NULL)
  399.             *pRow = -1;
  400.         if (pCol != NULL)
  401.             *pCol = -1;
  402.         return FALSE;
  403.     }
  404. }
  405.  
  406. CWnd* CSplitterWndEx::GetActivePane(int* pRow, int* pCol)
  407.     // return active view, NULL when no active view
  408. {
  409.     ASSERT_VALID(this);
  410.  
  411.     // attempt to use active view of frame window
  412.     CWnd* pView = NULL;
  413.     CFrameWnd* pFrameWnd = GetParentFrame();
  414.     ASSERT_VALID(pFrameWnd);
  415.     pView = pFrameWnd->GetActiveView();
  416.  
  417.     // failing that, use the current focus
  418.     if (pView == NULL)
  419.         pView = GetFocus();
  420.  
  421.     // make sure the pane is a child pane of the splitter
  422.     if (pView != NULL && !IsChildPane(pView, pRow, pCol))
  423.         pView = NULL;
  424.  
  425.     return pView;
  426. }
  427.  
  428. BOOL CSplitterWndEx::IsRowHidden(int row)
  429. {
  430.     return m_arr[row]>=m_nRows;
  431.  
  432. }
  433.  
  434. void CSplitterWndEx::GetRowInfoEx(int row, int &cyCur, int &cyMin)
  435. {
  436.     if (!m_arr)
  437.         GetRowInfo(row,cyCur,cyMin);
  438.     else
  439.     {
  440.         if (m_pRowInfo[m_arr[row]].nCurSize>0x10000)
  441.             cyCur=m_pRowInfo[m_arr[row]].nCurSize/0x10000;
  442.         else
  443.             cyCur=m_pRowInfo[m_arr[row]].nCurSize%0x10000;
  444.         cyMin=0;
  445.     }
  446. }
  447.  
  448. __int64 CSplitterWndEx::GetSizes() const
  449. {
  450.     LARGE_INTEGER v;
  451.     int dummy;
  452.     int s1, s2;
  453.     if (BarIsHorizontal())
  454.     {
  455.         GetRowInfo(0, s1, dummy);
  456.         GetRowInfo(1, s2, dummy);
  457.         v.HighPart = s1;
  458.         v.LowPart = s2;
  459.     }
  460.     else
  461.     {
  462.         GetColumnInfo(0, s1, dummy);
  463.         GetColumnInfo(1, s2, dummy);
  464.         v.HighPart = s1;
  465.         v.LowPart = s2;
  466.     }
  467.     return v.QuadPart;
  468. }
  469.