You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

317 lines
8.6 KiB
C++

// XTPReportControlLocale.cpp : implementation of the CXTPReportControlLocale class.
//
// This file is a part of the XTREME REPORTCONTROL MFC class library.
// (c)1998-2012 Codejock Software, All Rights Reserved.
//
// THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
// RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
// CONSENT OF CODEJOCK SOFTWARE.
//
// THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
// IN THE XTREME TOOLKIT PRO LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
// YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
// SINGLE COMPUTER.
//
// CONTACT INFORMATION:
// support@codejock.com
// http://www.codejock.com
//
/////////////////////////////////////////////////////////////////////////////
#include "StdAfx.h"
#include "Common/XTPDrawHelpers.h"
#include "Common/XTPSystemHelpers.h"
#include "Common/XTPImageManager.h"
#include "Common/XTPPropExchange.h"
#include "Common/XTPToolTipContext.h"
#include "Common/XTPResourceManager.h"
#include "Common/XTPMarkupRender.h"
#include "Common/XTPCustomHeap.h"
#include "Common/XTPSmartPtrInternalT.h"
#include "Common/XTPColorManager.h"
#include "XTPReportDefines.h"
#include "Behavior/XTPReportBehavior.h"
#include "XTPReportRows.h"
#include "XTPReportSelectedRows.h"
#include "XTPReportTip.h"
#include "XTPReportRecordItem.h"
#include "ItemTypes/XTPReportRecordItemText.h"
#include "XTPReportRecord.h"
#include "XTPReportRecords.h"
#include "XTPReportHeader.h"
#include "XTPReportColumn.h"
#include "XTPReportColumns.h"
#include "XTPReportRow.h"
#include "XTPReportControl.h"
#include "XTPReportPaintManager.h"
#include "XTPReportNavigator.h"
#include "XTPReportSubListControl.h"
#include "XTPReportGroupRow.h"
#include "XTPReportInplaceControls.h"
#include "XTPReportRecordItemControls.h"
#include "XTPReportHyperlink.h"
#include "XTPReportRecordItemRange.h"
#include "XTPReportSection.h"
#include "XTPReportADO.h"
#include "XTPReportDataManager.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
//////////////////////////////////////////////////////////////////////////
BOOL CXTPReportControlLocale::s_bUseResourceFileLocale = FALSE;
//===========================================================================
BOOL CXTPReportControlLocale::IsUseResourceFileLocale()
{
return s_bUseResourceFileLocale;
}
void CXTPReportControlLocale::SetUseResourceFileLocale(BOOL bUseResourceFileLocale)
{
s_bUseResourceFileLocale = bUseResourceFileLocale;
}
LCID CXTPReportControlLocale::GetActiveLCID()
{
LCID lcidCurr = LOCALE_USER_DEFAULT;
if (s_bUseResourceFileLocale)
lcidCurr = MAKELCID(XTPResourceManager()->GetResourcesLangID(), SORT_DEFAULT);
return lcidCurr;
}
BOOL AFX_CDECL CXTPReportControlLocale::VariantChangeTypeEx(VARIANT& rVarValue, VARTYPE vartype, BOOL bThrowError)
{
if (vartype != rVarValue.vt)
{
//if (rVarValue.vt == VT_BSTR)
//{
// vartype = VT_BSTR;
// return TRUE;
//}
LCID lcID = GetActiveLCID();
HRESULT hr = ::VariantChangeTypeEx(&rVarValue, &rVarValue, lcID, 0, vartype);
if (bThrowError && FAILED(hr))
{
if (hr == E_OUTOFMEMORY)
AfxThrowMemoryException();
else
AfxThrowOleException(hr);
}
return SUCCEEDED(hr);
}
return TRUE;
}
CString AFX_CDECL CXTPReportControlLocale::FormatDateTime(const COleDateTime& dt, LPCTSTR lpcszFormatString)
{
return _FormatDateTime(dt, lpcszFormatString, GetActiveLCID());
}
CString CXTPReportControlLocale::_FormatDateTime(const COleDateTime& dt, LPCTSTR lpcszFormatString, LCID lcLocaleID)
{
if (dt.GetStatus() != COleDateTime::valid)
{
ASSERT(dt.GetStatus() == COleDateTime::null);
return _T("");
}
CString strDT = lpcszFormatString;
SYSTEMTIME sysTime;
ZeroMemory(&sysTime, sizeof(sysTime));
if (!dt.GetAsSystemTime(sysTime))
{
ASSERT(FALSE);
return _T("");
}
// %% Percent sign
strDT.Replace(_T("%%"), _T("\0x1"));
_ProcessMappedSpecs(strDT, &sysTime, lcLocaleID);
_ProcessDateTimeSpecs(strDT, &sysTime, lcLocaleID);
// All locale dependent specifiers already processed
_ProcessOtherSpecs(strDT, dt);
strDT.Replace(_T("\0x1"), _T("%"));
return strDT;
}
void CXTPReportControlLocale::_ProcessMappedSpecs(CString& rstrFormat, const SYSTEMTIME* pST, LCID lcLocaleID)
{
_InitMappedSpecs();
const int cnBufferSize = 96;
TCHAR szBuffer[cnBufferSize];
int nCount = (int)s_arMappedSpecs.GetSize();
for (int i = 0; i < nCount; i++)
{
const XTP_TIMESPEC& specI = s_arMappedSpecs.ElementAt(i);
if (rstrFormat.Find(specI.pcszSpec, 0) < 0)
continue;
::ZeroMemory(szBuffer, sizeof(szBuffer));
int nResult;
if (specI.bTime)
{
nResult = ::GetTimeFormat(lcLocaleID, 0, pST, specI.pcszFormat, szBuffer, cnBufferSize);
}
else
{
nResult = ::GetDateFormat(lcLocaleID, 0, pST, specI.pcszFormat, szBuffer, cnBufferSize);
}
ASSERT(nResult);
if (nResult)
{
rstrFormat.Replace(specI.pcszSpec, szBuffer);
}
}
}
void CXTPReportControlLocale::_ProcessDateTimeSpecs(CString& rstrFormat, const SYSTEMTIME* pST, LCID lcLocaleID)
{
// %c Date and time representation appropriate for locale
// %#c Long date and time representation
// %x Date representation for current locale
// %#x Long date representation for current locale
// %X Time representation for current locale
rstrFormat.Replace(_T("%c"), _T("%x %X"));
rstrFormat.Replace(_T("%#c"), _T("%#x %X"));
__ProcessDate_x(rstrFormat, pST, lcLocaleID);
__ProcessTime_X(rstrFormat, pST, lcLocaleID);
}
void CXTPReportControlLocale::__ProcessDate_x(CString& rstrFormat, const SYSTEMTIME* pST, LCID lcLocaleID)
{
const int cnBufferSize = 96;
TCHAR szBuffer[cnBufferSize];
// %x Date representation for current locale
// %#x Long date representation for current locale
TCHAR* arSpec2[2] = {_T("%x"), _T("%#x")};
for (int i = 0; i < 2; i++)
{
if (rstrFormat.Find(arSpec2[i], 0) >= 0)
{
::ZeroMemory(szBuffer, sizeof(szBuffer));
DWORD dwFlags = (i == 0) ? DATE_SHORTDATE : DATE_LONGDATE;
int nRes = ::GetDateFormat(lcLocaleID, dwFlags, pST, NULL, szBuffer, cnBufferSize);
ASSERT(nRes);
rstrFormat.Replace(arSpec2[i], szBuffer);
}
}
}
void CXTPReportControlLocale::__ProcessTime_X(CString& rstrFormat, const SYSTEMTIME* pST, LCID lcLocaleID)
{
if (rstrFormat.Find(_T("%X"), 0) >= 0)
{
const int cnBufferSize = 96;
TCHAR szBuffer[cnBufferSize];
::ZeroMemory(szBuffer, sizeof(szBuffer));
int nRes = ::GetTimeFormat(lcLocaleID, 0, pST, NULL, szBuffer, cnBufferSize);
ASSERT(nRes);
rstrFormat.Replace(_T("%X"), szBuffer);
}
}
void CXTPReportControlLocale::_ProcessOtherSpecs(CString& rstrFormat, const COleDateTime& dt)
{
// %j Day of year as decimal number (001 - 366)
// %w Weekday as decimal number (0 - 6; Sunday is 0)
// %U Week of year as decimal number, with Sunday as first day of week (00 - 53)
// %W Week of year as decimal number, with Monday as first day of week (00 - 53)
// %z, %Z Either the time-zone name or time zone abbreviation, depending on registry settings; no characters if time zone is unknown
static LPCTSTR arszSpecs[] = { _T("%j"), _T("%#j"),
_T("%w"), _T("%#w"),
_T("%U"), _T("%#U"),
_T("%W"), _T("%#W"),
_T("%z"), _T("%Z") };
int nCount = _countof(arszSpecs);
for (int i = 0; i < nCount; i++)
{
if (rstrFormat.Find(arszSpecs[i], 0) < 0)
continue;
CString str = dt.Format(arszSpecs[i]);
rstrFormat.Replace(arszSpecs[i], str);
}
}
void CXTPReportControlLocale::_InitMappedSpecs()
{
if (s_arMappedSpecs.GetSize())
return;
// date
_AddsMappedSpec(_T("%a"), _T("ddd"), FALSE);
_AddsMappedSpec(_T("%A"), _T("dddd"), FALSE);
_AddsMappedSpec(_T("%b"), _T("MMM"), FALSE);
_AddsMappedSpec(_T("%B"), _T("MMMM"), FALSE);
_AddsMappedSpec(_T("%d"), _T("dd"), FALSE);
_AddsMappedSpec(_T("%#d"), _T("d"), FALSE);
_AddsMappedSpec(_T("%m"), _T("MM"), FALSE);
_AddsMappedSpec(_T("%#m"), _T("M"), FALSE);
_AddsMappedSpec(_T("%y"), _T("yy"), FALSE);
_AddsMappedSpec(_T("%#y"), _T("y"), FALSE);
_AddsMappedSpec(_T("%Y"), _T("yyyy"), FALSE);
// time
_AddsMappedSpec(_T("%H"), _T("HH"), TRUE);
_AddsMappedSpec(_T("%#H"), _T("H"), TRUE);
_AddsMappedSpec(_T("%I"), _T("hh"), TRUE);
_AddsMappedSpec(_T("%#I"), _T("h"), TRUE);
_AddsMappedSpec(_T("%M"), _T("mm"), TRUE);
_AddsMappedSpec(_T("%#M"), _T("m"), TRUE);
_AddsMappedSpec(_T("%S"), _T("ss"), TRUE);
_AddsMappedSpec(_T("%#S"), _T("s"), TRUE);
_AddsMappedSpec(_T("%p"), _T("tt"), TRUE);
}
void CXTPReportControlLocale::_AddsMappedSpec(LPCTSTR pcszSpec, LPCTSTR pcszFormat, BOOL bTime)
{
XTP_TIMESPEC tmpSpec = {pcszSpec, pcszFormat, bTime};
s_arMappedSpecs.Add(tmpSpec);
}