/* * Copyright 1999 Perforce Software. All rights reserved. * * This file is part of Perforce - the FAST SCM System. */ // SpecsPage.cpp : implementation file // #include "stdafx.h" #include "..\p4win.h" #include "SpecsPage.h" #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif ///////////////////////////////////////////////////////////////////////////// // CSpecsPage property page IMPLEMENT_DYNCREATE(CSpecsPage, CPropertyPage) CSpecsPage::CSpecsPage() : CPropertyPage(CSpecsPage::IDD) { //{{AFX_DATA_INIT(CSpecsPage) m_FontFace = _T(""); m_FontSize = _T(""); m_FontStyle = _T(""); m_MinMultiLineSize = _T(""); m_DescWrapSw = FALSE; m_DescWrap = _T(""); //}}AFX_DATA_INIT m_Inited = FALSE; } CSpecsPage::~CSpecsPage() { } void CSpecsPage::DoDataExchange(CDataExchange* pDX) { CPropertyPage::DoDataExchange(pDX); //{{AFX_DATA_MAP(CSpecsPage) DDX_Control(pDX, IDC_AUTOMINEDITDLG, m_AutoMinEditDlg); DDX_Control(pDX, IDC_ALLOWPROMPTABOVE, m_AllowPromptAbove); DDX_Control(pDX, IDC_PRESERVESPECFORMAT, m_PreserveSpecFormat); DDX_Text(pDX, IDC_MINMULTILINESIZE, m_MinMultiLineSize); DDV_MaxChars(pDX, m_MinMultiLineSize, 1); DDX_Check(pDX, IDC_DESCWRAPSW, m_DescWrapSw); DDX_Text(pDX, IDC_DESCWRAP, m_DescWrap); DDV_MaxChars(pDX, m_DescWrap, 3); DDX_Control(pDX, IDC_FONT, m_FontCombo); DDX_Control(pDX, IDC_FONTSIZE, m_SizeCombo); DDX_Control(pDX, IDC_STYLE, m_StyleCombo); DDX_Control(pDX, IDC_SAMPLE, m_Sample); DDX_CBString(pDX, IDC_FONT, m_FontFace); DDX_CBString(pDX, IDC_FONTSIZE, m_FontSize); DDX_CBString(pDX, IDC_STYLE, m_FontStyle); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CSpecsPage, CPropertyPage) //{{AFX_MSG_MAP(CSpecsPage) ON_CBN_SELCHANGE(IDC_FONTSIZE, OnSelChange) ON_CBN_SELCHANGE(IDC_STYLE, OnSelChange) ON_CBN_KILLFOCUS(IDC_FONT, OnSelchangeFont) ON_CBN_KILLFOCUS(IDC_FONTSIZE, OnSelChange) ON_CBN_KILLFOCUS(IDC_STYLE, OnSelChange) ON_CBN_SELCHANGE(IDC_FONT, OnSelchangeFont) ON_BN_CLICKED(IDC_DESCWRAPSW, OnDescWrapSw) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CSpecsPage message handlers BOOL CSpecsPage::OnInitDialog() { CPropertyPage::OnInitDialog(); // Create the current fixed width font CWindowDC dc(GetDesktopWindow() ); m_cyPixelsPerInch = GetDeviceCaps(dc, LOGPIXELSY); // Get the current dialog font from the registry // CString face= GET_P4REGPTR()->GetFontFace(); int size= - abs(GET_P4REGPTR()->GetFontSize()); int weight= GET_P4REGPTR()->GetFontWeight(); BOOL isItalic= GET_P4REGPTR()->GetFontItalic(); // Attempt to create the font that is referred to in the // registry. Windows may substitute an alternative LOGFONT logFont; memset( &logFont, 0, sizeof(LOGFONT) ); lstrcpy( logFont.lfFaceName, face ); logFont.lfCharSet= DEFAULT_CHARSET; logFont.lfHeight= size; logFont.lfWeight= weight; logFont.lfItalic= (unsigned char) isItalic; logFont.lfPitchAndFamily= FIXED_PITCH | FF_DONTCARE; m_FontSample.CreateFontIndirect( &logFont ); m_FontSample.GetLogFont( &logFont ); m_FontFace = logFont.lfFaceName; m_FontSize.Format( _T("%d"), abs(MulDiv( logFont.lfHeight, 72, m_cyPixelsPerInch)) ); m_FontStyle = LoadStringResource(IDS_FONT_REGULAR); if( logFont.lfWeight >= 700 && logFont.lfItalic) m_FontStyle = LoadStringResource(IDS_FONT_BOLD_ITALIC); else if( logFont.lfItalic ) m_FontStyle = LoadStringResource(IDS_FONT_ITALIC); else if ( logFont.lfWeight >= 700 ) m_FontStyle = LoadStringResource(IDS_FONT_BOLD); // Now get the names of all the fixed width fonts memset( &logFont, 0, sizeof(LOGFONT) ); logFont.lfPitchAndFamily= FIXED_PITCH | FF_DONTCARE; logFont.lfCharSet= DEFAULT_CHARSET; CWindowDC dcthis(this); EnumFontFamiliesEx( dcthis.m_hDC, &logFont, (FONTENUMPROC)FontEnumProc, (LPARAM) this, 0 ); // Fill Style combobox with "common" styles m_StyleCombo.AddString( LoadStringResource(IDS_FONT_REGULAR) ); m_StyleCombo.AddString( LoadStringResource(IDS_FONT_BOLD) ); m_StyleCombo.AddString( LoadStringResource(IDS_FONT_ITALIC) ); m_StyleCombo.AddString( LoadStringResource(IDS_FONT_BOLD_ITALIC) ); // Load non-font stuff m_AutoMinEditDlg.SetCheck(GET_P4REGPTR()->AutoMinEditDlg()); m_AllowPromptAbove.SetCheck(GET_P4REGPTR()->AllowPromptAbove()); m_PreserveSpecFormat.SetCheck(GET_P4REGPTR()->PreserveSpecFormat()); m_MinMultiLineSize = GET_P4REGPTR()->GetMinMultiLineSize(); m_DescWrapSw = GET_P4REGPTR()->GetDescWrapSw(); TCHAR str[8]; _stprintf(str, _T("%d"), GET_P4REGPTR()->GetDescWrap()); m_DescWrap = str; // Update input fields UpdateData(FALSE); OnSelchangeFont(); OnDescWrapSw(); m_Inited = TRUE; return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX Property Pages should return FALSE } int CALLBACK CSpecsPage::FontEnumProc( ENUMLOGFONTEX *enumLogFontEx, NEWTEXTMETRICEX *newTextMetric, int fontType, CSpecsPage *specsPage ) { BOOL fixedPitch= FALSE; if( enumLogFontEx->elfLogFont.lfPitchAndFamily & FIXED_PITCH ) fixedPitch= TRUE; if( fixedPitch && (lstrlen((LPCTSTR)enumLogFontEx->elfFullName) < 32) && (specsPage->m_FontCombo.FindStringExact( 0, (LPCTSTR)enumLogFontEx->elfFullName) == CB_ERR ) ) { int index= specsPage->m_FontCombo.AddString( (LPCTSTR)enumLogFontEx->elfFullName ); specsPage->m_FontCombo.SetItemData( index, (DWORD) fontType ); } return 1; } void CSpecsPage::OnSelChange() { // The selection hasn't changed yet, so change it if( IsChild( GetFocus() ) && GetFocus()->GetParent()->IsKindOf( RUNTIME_CLASS( CComboBox ) ) ) { CComboBox *cb = (CComboBox *)GetFocus()->GetParent(); CString text; if( cb->GetCurSel() != CB_ERR ) { cb->GetLBText( cb->GetCurSel(), text ); cb->SetWindowText( text ); } } UpdateData(TRUE); UpdateSampleFont(); } void CSpecsPage::UpdateSampleFont() { LOGFONT logFont; memset( &logFont, 0, sizeof(LOGFONT) ); logFont.lfPitchAndFamily= FIXED_PITCH | FF_DONTCARE; lstrcpy(logFont.lfFaceName,m_FontFace.GetBuffer(m_FontFace.GetLength())); logFont.lfHeight= -MulDiv(_ttoi(m_FontSize), m_cyPixelsPerInch, 72); logFont.lfWeight = 400; //Regular logFont.lfItalic = FALSE; logFont.lfCharSet = DEFAULT_CHARSET; if( m_FontStyle.Find( LoadStringResource(IDS_FONT_ITALIC) ) != -1 ) logFont.lfItalic = TRUE; if( m_FontStyle.Find( LoadStringResource(IDS_FONT_BOLD) ) != -1 ) logFont.lfWeight = 700; m_FontSample.DeleteObject(); m_FontSample.CreateFontIndirect( &logFont ); m_Sample.SetFont(&m_FontSample); } void CSpecsPage::OnOK() { if (!m_Inited) return; // This bit of silliness is required to trick the font edit // fields into providing their data to the UpdateData() routine GotoDlgCtrl(GetParent()->GetDlgItem(IDC_APPLY)); m_ErrorCount = 0; if( UpdateData(TRUE) ) { int i; LOGFONT logFont; m_FontSample.GetLogFont( &logFont ); if( !GET_P4REGPTR()->SetFontFace( logFont.lfFaceName ) ) m_ErrorCount++; if( !GET_P4REGPTR()->SetFontWeight( logFont.lfWeight ) ) m_ErrorCount++; if( !GET_P4REGPTR()->SetFontSize( abs(logFont.lfHeight) ) ) m_ErrorCount++; if( !GET_P4REGPTR()->SetFontItalic( logFont.lfItalic ) ) m_ErrorCount++; BOOL autoMinEditDlg = TRUE; if( m_AutoMinEditDlg.GetCheck() == 0 ) autoMinEditDlg = FALSE; if( autoMinEditDlg != GET_P4REGPTR()->AutoMinEditDlg( ) ) if(!GET_P4REGPTR()->SetAutoMinEditDlg( autoMinEditDlg ) ) m_ErrorCount++; BOOL allowPromptAbove = TRUE; if( m_AllowPromptAbove.GetCheck() == 0 ) allowPromptAbove = FALSE; if( allowPromptAbove != GET_P4REGPTR()->AllowPromptAbove( ) ) if(!GET_P4REGPTR()->SetAllowPromptAbove( allowPromptAbove ) ) m_ErrorCount++; BOOL preserveSpecFormat = TRUE; if( m_PreserveSpecFormat.GetCheck() == 0 ) preserveSpecFormat = FALSE; if( preserveSpecFormat != GET_P4REGPTR()->PreserveSpecFormat( ) ) if(!GET_P4REGPTR()->SetPreserveSpecFormat( preserveSpecFormat ) ) m_ErrorCount++; if (!m_ErrorCount) { m_MinMultiLineSize.TrimRight(); m_MinMultiLineSize.TrimLeft(); if (m_MinMultiLineSize < _T("2")) m_MinMultiLineSize = _T("2"); if(!GET_P4REGPTR()->SetMinMultiLineSize( m_MinMultiLineSize ) ) m_ErrorCount++; } m_DescWrap.TrimLeft(); i = _tstoi(m_DescWrap); if (m_DescWrapSw && i < 10) AfxMessageBox( IDS_DESC_WRAP_VALUE_MUST_BE_GREATER_THAN_9, MB_ICONEXCLAMATION ); if (!m_ErrorCount) { if (i < 10) m_DescWrapSw = FALSE; if(!GET_P4REGPTR()->SetDescWrap( i ) ) m_ErrorCount++; } // do this after m_DescWrap because it might set m_DescWrapSw if (!m_ErrorCount) { if(!GET_P4REGPTR()->SetDescWrapSw( m_DescWrapSw ) ) m_ErrorCount++; } if(m_ErrorCount) AfxMessageBox(IDS_BAD_REGISTRY, MB_ICONSTOP); } if(m_ErrorCount) MessageBox(LoadStringResource(IDS_BAD_REGISTRY), LoadStringResource(IDS_P4WIN_ERROR), MB_ICONSTOP); } void CSpecsPage::OnSelchangeFont() { int cursel; // Change the selection if( (cursel = m_FontCombo.GetCurSel()) != CB_ERR ) { CString text; m_FontCombo.GetLBText( m_FontCombo.GetCurSel(), text ); m_FontCombo.SetWindowText( text ); } // Fill in the size list m_SizeCombo.ResetContent(); // Fill with "real" sizes CString faceName; if (cursel >= 0) m_FontCombo.GetLBText(cursel, faceName); else m_FontCombo.GetWindowText(faceName); if (faceName.GetLength() > 31) { AfxMessageBox(IDS_MICROSOFT_NO_SUPPORT_FONTNAMES_LONGER_THAN_31_CHAR, MB_OK | MB_ICONEXCLAMATION); m_FontCombo.SetWindowText( _T("") ); m_FontCombo.SetCurSel(-1); return; } CClientDC dc(NULL); DWORD fontType= (cursel >= 0) ? m_FontCombo.GetItemData( m_FontCombo.GetCurSel() ) : 0; // Check if we have a font that is either a vector or Truettype font if ( fontType != RASTER_FONTTYPE) { static TCHAR* Defaults[] = { _T("8"), _T("9"), _T("10"), _T("11"), _T("12"), _T("14"), _T("16"), _T("18"), _T("20"), _T("22"), _T("24"), _T("26"), _T("28"), _T("36"), _T("48") }; // Fill with "common" sizes for (int i = 0; i < sizeof(Defaults)/sizeof(Defaults[0]); i++) m_SizeCombo.AddString( Defaults[i] ); } else // Enum the fontname to get all the sizes EnumFontFamilies(dc.GetSafeHdc(), faceName, (FONTENUMPROC) CSpecsPage::SizeEnumProc, (LPARAM) this); // Set the point size if (m_SizeCombo.FindString(-1, m_FontSize) != CB_ERR) { // Attempt to select proper list item m_SizeCombo.SelectString(-1, m_FontSize); } else { // Point size is not in the list so just fill the edit box // and don't select anything from the list m_SizeCombo.SetCurSel(-1); m_SizeCombo.SetWindowText(m_FontSize); } // Redraw the sample UpdateData(TRUE); UpdateSampleFont(); } // This callback is called once for each font on the system that has the same name // as the current font in the font name combobox. It does nothing for non-Raster fonts; // for raster fonts, it adds the various font sizes to the font size combobox. // Because the fonts come in random order, to be able to get the sizes in ascending // order, we have to paw thru those already loaded to figure where to insert this size. // We cannot us the CB_SORT style becuase that is an alpha sort and 7 would come after 10. int CALLBACK CSpecsPage::SizeEnumProc( ENUMLOGFONT *enumLogFont, NEWTEXTMETRIC *newTextMetric, int fontType, CSpecsPage *specsPage) { int i, hy; ASSERT(specsPage != NULL); if (fontType & RASTER_FONTTYPE) { int height = newTextMetric->tmHeight - newTextMetric->tmInternalLeading; CString h; h.Format(_T("%d"), hy = MulDiv(height, 72, specsPage->m_cyPixelsPerInch) ); // First look to see if this size is already in the combox // If so (i.e. != -1), there is nothing to do if (specsPage->m_SizeCombo.FindStringExact( -1, h ) == -1) { CString buf; // now look thru the size already loaded and find one bigger than this for (i = -1; specsPage->m_SizeCombo.GetLBTextLen(++i) != CB_ERR; ) { specsPage->m_SizeCombo.GetLBText(i, buf); int y = _ttoi(buf); if (y > hy) // if this one is bigger than the new one { // insert the new one in front of it specsPage->m_SizeCombo.InsertString(i, h); i = -1; // signal that we did the insert break; } } if (i != -1) // i != -1 means we didn't find a bigger one, so append this one at the end specsPage->m_SizeCombo.AddString(h); } } return 1; } void CSpecsPage::OnDescWrapSw() { UpdateData(); CWnd *pwnd=GetDlgItem(IDC_DESCWRAP); if( m_DescWrapSw ) { pwnd->EnableWindow(TRUE); if (m_Inited) GotoDlgCtrl(pwnd); } else pwnd->EnableWindow(FALSE); }