mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-06 09:05:45 +00:00
286 lines
7.4 KiB
C++
286 lines
7.4 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
*
|
|
* The contents of this file are subject to the Netscape Public License
|
|
* Version 1.0 (the "NPL"); you may not use this file except in
|
|
* compliance with the NPL. You may obtain a copy of the NPL at
|
|
* http://www.mozilla.org/NPL/
|
|
*
|
|
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
|
* for the specific language governing rights and limitations under the
|
|
* NPL.
|
|
*
|
|
* The Initial Developer of this code under the NPL is Netscape
|
|
* Communications Corporation. Portions created by Netscape are
|
|
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
|
* Reserved.
|
|
*/
|
|
|
|
// TabList.cpp : implementation file
|
|
//
|
|
|
|
#include "stdafx.h"
|
|
#include "tclist.h"
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CTCList
|
|
|
|
// initialize string to calculate average char width
|
|
CString CTCList::m_strCharSet =
|
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
|
|
|
CTCList::CTCList()
|
|
{
|
|
m_nSpacing = 2; // init column spacing
|
|
m_nTabs = MIN_TAB_SIZE; // init number of tabs
|
|
m_nAvgCharWidth = 8; // a reasonable default
|
|
|
|
// init size of tab setting and column width arrays
|
|
m_aTabs.SetSize (MIN_TAB_SIZE);
|
|
m_aColWidth.SetSize (MIN_TAB_SIZE);
|
|
|
|
InitColWidth(); // init column width array
|
|
}
|
|
|
|
CTCList::~CTCList()
|
|
{
|
|
}
|
|
|
|
|
|
BEGIN_MESSAGE_MAP(CTCList, CListBox)
|
|
//{{AFX_MSG_MAP(CTCList)
|
|
ON_MESSAGE(LB_ADDSTRING, OnAddString)
|
|
ON_MESSAGE(LB_INSERTSTRING, OnInsertString)
|
|
ON_MESSAGE(LB_DELETESTRING, OnDeleteString)
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CTCList message handlers
|
|
|
|
// Set the number of spaces to separate columns.
|
|
void CTCList::SetColumnSpace(int nSpacing)
|
|
{
|
|
// only process if different
|
|
if (nSpacing != m_nSpacing)
|
|
{
|
|
m_nSpacing = nSpacing; // store the number of character spaces
|
|
CalculateTabs(); // calculate new tab settings
|
|
SetTabStops(m_nTabs,
|
|
(LPINT) &m_aTabs[0]); // set tab settings
|
|
}
|
|
}
|
|
|
|
|
|
// Calculate average character width. The average character width is
|
|
// calculated using the same method used by GetDialogBaseUnits function;
|
|
// average char width = (pixel width of "ABC...Zabc...z") / 52.
|
|
// The current font is used for the calculation.
|
|
|
|
void CTCList::CalculateAvgCharWidth(CDC* pDC)
|
|
{
|
|
CFont* pCurrentFont = GetFont(); // get font currently using for list box
|
|
|
|
// GetFont will return NULL if using System font.
|
|
// If using system font just call GetDialogBaseUnits.
|
|
if (!pCurrentFont)
|
|
m_nAvgCharWidth = LOWORD(GetDialogBaseUnits());
|
|
|
|
// if not using system font, select font into dc and
|
|
// calculate average char width
|
|
else
|
|
{
|
|
// have to select object into the dc before
|
|
// we can calculate width of string
|
|
CFont* pOldFont = pDC->SelectObject(pCurrentFont);
|
|
|
|
// get width of string
|
|
CSize size = pDC->GetTextExtent(m_strCharSet,
|
|
m_strCharSet.GetLength());
|
|
|
|
// calculate average char width and round result
|
|
m_nAvgCharWidth = MulDiv(1, size.cx, m_strCharSet.GetLength());
|
|
|
|
// select old font back into dc
|
|
pDC->SelectObject(pOldFont);
|
|
}
|
|
}
|
|
|
|
// calculate tabs from maximum column array
|
|
void CTCList::CalculateTabs()
|
|
{
|
|
UINT nIndex; // index to array
|
|
|
|
// first tab setting is the fist col width
|
|
m_aTabs[0] = ((m_aColWidth[0]+(m_nAvgCharWidth*m_nSpacing)) * 4) /
|
|
m_nAvgCharWidth;
|
|
|
|
// calculate each tab setting
|
|
for (nIndex=1; nIndex < m_nTabs; nIndex++)
|
|
m_aTabs[nIndex] = m_aTabs[nIndex-1] +
|
|
((m_aColWidth[nIndex]+(m_nAvgCharWidth*m_nSpacing)) * 4) /
|
|
m_nAvgCharWidth;
|
|
}
|
|
|
|
// re-calculate maximum column widths
|
|
void CTCList::Recalc()
|
|
{
|
|
// we are totally recalculating, so reset size of arrays
|
|
m_aTabs.SetSize(MIN_TAB_SIZE); // reset tab stop array size
|
|
m_aColWidth.SetSize(MIN_TAB_SIZE); // reset col width array size
|
|
m_nTabs = MIN_TAB_SIZE; // set number of tab settings
|
|
InitColWidth(); // init col width array
|
|
|
|
// loop through list box and calculate col widths for each string
|
|
CString str;
|
|
for (int nItem = GetCount() - 1; nItem >= 0; --nItem)
|
|
{
|
|
GetText(nItem, str); // get list box item string
|
|
CalculateColWidths(str); // calculate column widths of string
|
|
}
|
|
|
|
CalculateTabs(); // calculate tab settings
|
|
}
|
|
|
|
// initialize column width to 0
|
|
void CTCList::InitColWidth()
|
|
{
|
|
// initialize col width settings to a length of 0
|
|
UINT nIndex;
|
|
for (nIndex=0; nIndex < m_nTabs; nIndex++)
|
|
m_aColWidth[nIndex] = 0;
|
|
}
|
|
|
|
|
|
// calculate column widths of string
|
|
BOOL CTCList::CalculateColWidths(LPCSTR pString, BOOL bSetWidths)
|
|
{
|
|
BOOL bMaxColumn = FALSE; // returns if this string contains max column
|
|
CDC* pDC = GetDC(); // get dc of list box window
|
|
UINT nCol=0; // column currently processing
|
|
|
|
if (pDC)
|
|
{
|
|
// calculate average char width
|
|
CalculateAvgCharWidth(pDC);
|
|
|
|
// select current font into dc so can measure width of string
|
|
CFont* pOldFont = pDC->SelectObject(GetFont());
|
|
|
|
CString strRow; // row string
|
|
CString strCol; // column string
|
|
CSize size; // size of column string
|
|
int nIndex=0; // index to row string
|
|
|
|
strRow = pString; // set row string to passed string
|
|
|
|
// divide row string up into column strings
|
|
while (nIndex != -1)
|
|
{
|
|
// check if need to grow tab setting and column width
|
|
if (nCol+1 > m_nTabs)
|
|
{
|
|
m_aTabs.SetSize(m_nTabs+1);
|
|
m_aColWidth.SetSize(m_nTabs+1);
|
|
m_nTabs += 1;
|
|
}
|
|
|
|
// parse out column string from row string
|
|
if ((nIndex = strRow.Find('\t')) == -1)
|
|
strCol = strRow;
|
|
else
|
|
{
|
|
strCol = strRow.Left(nIndex);
|
|
strRow = strRow.Mid(nIndex+1);
|
|
}
|
|
|
|
// get pixel width of column string
|
|
size = pDC->GetTextExtent(strCol, strCol.GetLength());
|
|
|
|
// see if this is the widest column string
|
|
if ((UINT)size.cx >= m_aColWidth[nCol])
|
|
{
|
|
// this string contains a longest column string
|
|
bMaxColumn = TRUE;
|
|
|
|
// store information to column width array
|
|
if (bSetWidths)
|
|
m_aColWidth[nCol] = size.cx;
|
|
}
|
|
|
|
nCol++; // move to the next column
|
|
}
|
|
|
|
pDC->SelectObject(pOldFont);
|
|
ReleaseDC(pDC);
|
|
}
|
|
|
|
return bMaxColumn;
|
|
}
|
|
|
|
|
|
// process the LB_INSERTSTRING message
|
|
LRESULT CTCList::OnInsertString(WPARAM wParam, LPARAM lParam)
|
|
{
|
|
// adjust the col width array for this string
|
|
BOOL bRet = CalculateColWidths((LPCSTR)lParam);
|
|
|
|
// set tab stop if required
|
|
if (bRet)
|
|
{
|
|
CalculateTabs(); // adjust the tab setting array
|
|
SetTabStops(m_nTabs,
|
|
(LPINT)&m_aTabs[0]); // set tab stops
|
|
}
|
|
|
|
return Default();
|
|
}
|
|
|
|
|
|
// process the LB_ADDSTRING message
|
|
LRESULT CTCList::OnAddString(WPARAM wParam, LPARAM lParam)
|
|
{
|
|
// adjust the col width array for this string
|
|
BOOL bRet = CalculateColWidths((LPCSTR)lParam);
|
|
|
|
// set tab stop if required
|
|
if (bRet)
|
|
{
|
|
CalculateTabs(); // adjust the tab setting array
|
|
SetTabStops(m_nTabs, (LPINT)&m_aTabs[0]); // set tab stops
|
|
}
|
|
|
|
return Default();
|
|
}
|
|
|
|
|
|
// process the LB_DELETESTRING message
|
|
LRESULT CTCList::OnDeleteString(WPARAM wParam, LPARAM lParam)
|
|
{
|
|
CString str;
|
|
GetText(wParam, str);
|
|
|
|
// see if need to recalculate tab stops
|
|
BOOL bRecalc = CalculateColWidths(str, FALSE);
|
|
|
|
// delete string from list box
|
|
// pass message along to list box proc
|
|
LRESULT lRet = Default();
|
|
|
|
// recalculate tab stops if required
|
|
if (bRecalc)
|
|
{
|
|
Recalc();
|
|
SetTabStops(m_nTabs, (LPINT)&m_aTabs[0]);
|
|
}
|
|
|
|
return lRet;
|
|
}
|
|
|