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.
524 lines
13 KiB
C++
524 lines
13 KiB
C++
// XTPChartNumberFormat.cpp
|
|
//
|
|
// This file is a part of the XTREME TOOLKIT PRO 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/XTPPropExchange.h"
|
|
#include "Common/XTPVC80Helpers.h"
|
|
|
|
#include "../Types/XTPChartTypes.h"
|
|
#include "../XTPChartDefines.h"
|
|
#include "../XTPChartElement.h"
|
|
#include <Chart/XTPChartLegendItem.h>
|
|
#include <Common/XTPMathUtils.h>
|
|
|
|
#include "../XTPChartSeriesPoint.h"
|
|
#include "../XTPChartSeries.h"
|
|
|
|
#include "XTPChartNumberFormat.h"
|
|
|
|
#ifndef LOCALE_SYEARMONTH
|
|
#define LOCALE_SYEARMONTH 0x00001006 // year month format string
|
|
#endif
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////
|
|
// CXTPChartNumberFormat
|
|
|
|
CXTPChartNumberFormat::CXTPChartNumberFormat(CXTPChartElement* pOwner)
|
|
{
|
|
m_pOwner = pOwner;
|
|
|
|
m_strPattern = _T("");
|
|
m_nCategory = xtpChartGeneral;
|
|
m_nDecimalPlaces = -1;
|
|
m_bUseThousandSeparator = TRUE;
|
|
m_nLocale = LOCALE_USER_DEFAULT;
|
|
|
|
|
|
|
|
memset(&m_fmtNumber, 0, sizeof(m_fmtNumber));
|
|
m_fmtNumber.lpDecimalSep = new TCHAR[10];
|
|
m_fmtNumber.lpThousandSep = new TCHAR[10];
|
|
|
|
CreateNumberFormat();
|
|
|
|
memset(&m_fmtCurrency, 0, sizeof(m_fmtCurrency));
|
|
m_fmtCurrency.lpDecimalSep = new TCHAR[10];
|
|
m_fmtCurrency.lpThousandSep = new TCHAR[10];
|
|
m_fmtCurrency.lpCurrencySymbol = new TCHAR[10];
|
|
|
|
CreateCurrencyFormat();
|
|
|
|
m_nDateTimeCategory = xtpChartDateTimeShortDate;
|
|
CreateDateTimeFormat();
|
|
|
|
|
|
#ifdef _XTP_ACTIVEX
|
|
EnableAutomation();
|
|
EnableTypeLib();
|
|
#endif
|
|
|
|
}
|
|
|
|
CXTPChartNumberFormat::~CXTPChartNumberFormat()
|
|
{
|
|
delete[] m_fmtNumber.lpDecimalSep;
|
|
delete[] m_fmtNumber.lpThousandSep;
|
|
|
|
delete[] m_fmtCurrency.lpDecimalSep;
|
|
delete[] m_fmtCurrency.lpThousandSep;
|
|
delete[] m_fmtCurrency.lpCurrencySymbol;
|
|
}
|
|
|
|
void CXTPChartNumberFormat::DoPropExchange(CXTPPropExchange* pPX)
|
|
{
|
|
PX_String(pPX, _T("Pattern"), m_strPattern, _T(""));
|
|
PX_Enum(pPX, _T("Category"), m_nCategory, xtpChartGeneral);
|
|
PX_Int(pPX, _T("DecimalPlaces"), m_nDecimalPlaces, -1);
|
|
PX_Bool(pPX, _T("UseThousandSeparator"), m_bUseThousandSeparator, TRUE);
|
|
PX_DWord(pPX, _T("Locale"), m_nLocale, LOCALE_USER_DEFAULT);
|
|
PX_String(pPX, _T("CurrencySymbol"), m_strCurrencySymbol, _T(""));
|
|
|
|
PX_Enum(pPX, _T("DateTimeCategory"), m_nDateTimeCategory, xtpChartDateTimeShortDate);
|
|
|
|
PX_String(pPX, _T("DateTimeFormat"), m_strDateTimeFormat, _T(""));
|
|
|
|
if (pPX->IsLoading())
|
|
{
|
|
CreateNumberFormat();
|
|
CreateCurrencyFormat();
|
|
CreateDateTimeFormat();
|
|
}
|
|
}
|
|
|
|
|
|
CString CXTPChartNumberFormat::GetLocaleString(LCTYPE LCType, int nMaxLength)
|
|
{
|
|
CString strResult;
|
|
|
|
::GetLocaleInfo(m_nLocale, LCType , strResult.GetBufferSetLength(nMaxLength), nMaxLength);
|
|
strResult.ReleaseBuffer();
|
|
|
|
return strResult;
|
|
}
|
|
|
|
int CXTPChartNumberFormat::GetLocaleLong(LCTYPE LCType) const
|
|
{
|
|
TCHAR szResult[5];
|
|
|
|
int nResult = ::GetLocaleInfo(m_nLocale, LCType , szResult, 4);
|
|
ASSERT(nResult >= 2 && nResult <= 3);
|
|
|
|
return _ttoi(szResult);
|
|
}
|
|
|
|
void CXTPChartNumberFormat::CreateCurrencyFormat()
|
|
{
|
|
m_fmtCurrency.NumDigits = m_nDecimalPlaces == -1 ? GetLocaleLong(LOCALE_IDIGITS) : m_nDecimalPlaces;
|
|
m_fmtCurrency.LeadingZero = GetLocaleLong(LOCALE_ILZERO);
|
|
m_fmtCurrency.Grouping = 3;
|
|
m_fmtCurrency.NegativeOrder = GetLocaleLong(LOCALE_INEGCURR);
|
|
|
|
|
|
m_fmtCurrency.PositiveOrder = GetLocaleLong(LOCALE_ICURRENCY);
|
|
|
|
GetLocaleInfo(m_nLocale, LOCALE_SDECIMAL, m_fmtCurrency.lpDecimalSep, 10);
|
|
|
|
if (m_bUseThousandSeparator)
|
|
GetLocaleInfo(m_nLocale, LOCALE_STHOUSAND, m_fmtCurrency.lpThousandSep, 10);
|
|
else
|
|
m_fmtCurrency.lpThousandSep[0] = 0;
|
|
|
|
if (m_strCurrencySymbol.IsEmpty())
|
|
GetLocaleInfo(m_nLocale, LOCALE_SCURRENCY, m_fmtCurrency.lpCurrencySymbol, 10);
|
|
else
|
|
STRNCPY_S(m_fmtCurrency.lpCurrencySymbol, 10, m_strCurrencySymbol, 9);
|
|
}
|
|
|
|
void CXTPChartNumberFormat::CreateNumberFormat()
|
|
{
|
|
m_fmtNumber.NumDigits = m_nDecimalPlaces == -1 ? GetLocaleLong(LOCALE_IDIGITS) : m_nDecimalPlaces;
|
|
m_fmtNumber.LeadingZero = GetLocaleLong(LOCALE_ILZERO);;
|
|
m_fmtNumber.Grouping = 3;
|
|
m_fmtNumber.NegativeOrder = GetLocaleLong(LOCALE_INEGNUMBER);
|
|
|
|
GetLocaleInfo(m_nLocale, LOCALE_SDECIMAL, m_fmtNumber.lpDecimalSep, 10);
|
|
|
|
if (m_bUseThousandSeparator)
|
|
GetLocaleInfo(m_nLocale, LOCALE_STHOUSAND, m_fmtNumber.lpThousandSep, 10);
|
|
else
|
|
m_fmtNumber.lpThousandSep[0] = 0;
|
|
|
|
}
|
|
|
|
CString CXTPChartNumberFormat::DoubleToString(double dValue) const
|
|
{
|
|
CString strResult;
|
|
|
|
switch (m_nCategory)
|
|
{
|
|
case xtpChartGeneral:
|
|
{
|
|
strResult.Format(_T("%g"), dValue);
|
|
|
|
if (m_fmtNumber.lpDecimalSep[0] == _T(','))
|
|
strResult.Replace(_T('.'), _T(','));
|
|
|
|
return strResult;
|
|
}
|
|
|
|
case xtpChartNumber:
|
|
{
|
|
CString strTemp;
|
|
strTemp.Format(_T("%lf"), dValue);
|
|
strTemp.Replace(_T(','), _T('.'));
|
|
|
|
GetNumberFormat(m_nLocale, 0, (LPCTSTR)strTemp, &m_fmtNumber, strResult.GetBuffer(40), 40);
|
|
strResult.ReleaseBuffer();
|
|
return strResult;
|
|
}
|
|
|
|
case xtpChartCurrency:
|
|
{
|
|
CString strTemp;
|
|
strTemp.Format(_T("%lf"), dValue);
|
|
strTemp.Replace(_T(','), _T('.'));
|
|
|
|
GetCurrencyFormat(m_nLocale, 0, (LPCTSTR)strTemp, &m_fmtCurrency, strResult.GetBuffer(40), 40);
|
|
strResult.ReleaseBuffer();
|
|
return strResult;
|
|
}
|
|
|
|
case xtpChartPercentage:
|
|
{
|
|
CString strTemp;
|
|
strTemp.Format(_T("%lf"), dValue * 100);
|
|
strTemp.Replace(_T(','), _T('.'));
|
|
|
|
GetNumberFormat(m_nLocale, 0, (LPCTSTR)strTemp, &m_fmtNumber, strResult.GetBuffer(40), 40);
|
|
strResult.ReleaseBuffer();
|
|
|
|
strResult += _T('%');
|
|
return strResult;
|
|
}
|
|
|
|
case xtpChartScientific:
|
|
{
|
|
if (m_nDecimalPlaces == -1)
|
|
strResult.Format(_T("%e"), dValue);
|
|
else
|
|
{
|
|
CString strFormat;
|
|
strFormat.Format(_T("%%.%de"), m_nDecimalPlaces);
|
|
|
|
strResult.Format(strFormat, dValue);
|
|
|
|
}
|
|
return strResult;
|
|
}
|
|
}
|
|
|
|
return strResult;
|
|
}
|
|
|
|
CString CXTPChartNumberFormat::FormatNumber(double dValue) const
|
|
{
|
|
if (CXTPMathUtils::Compare(dValue, 0) == 0)
|
|
dValue = 0;
|
|
|
|
CString strResult;
|
|
|
|
if (!m_strPattern.IsEmpty())
|
|
{
|
|
strResult.Format(m_strPattern, dValue);
|
|
|
|
int nIndex = strResult.Find(_T("{V}"));
|
|
if (nIndex != -1)
|
|
{
|
|
CString str = DoubleToString(dValue);
|
|
|
|
strResult.Replace(_T("{V}"), str);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
strResult = DoubleToString(dValue);
|
|
}
|
|
|
|
return strResult;
|
|
}
|
|
|
|
CString CXTPChartNumberFormat::FormatString(LPCTSTR lpsz) const
|
|
{
|
|
if (m_strPattern.IsEmpty())
|
|
return lpsz;
|
|
|
|
|
|
CXTPChartString strResult;
|
|
strResult.Format(m_strPattern, lpsz);
|
|
|
|
int nIndex = strResult.Find(_T("{V}"));
|
|
if (nIndex != -1)
|
|
{
|
|
strResult.Replace(_T("{V}"), lpsz);
|
|
}
|
|
|
|
return strResult;
|
|
}
|
|
|
|
CString CXTPChartNumberFormat::FormatPoint(CXTPChartSeriesPoint* pSeriesPoint, double dValue) const
|
|
{
|
|
if (CXTPMathUtils::Compare(dValue, 0) == 0)
|
|
dValue = 0;
|
|
|
|
CString strResult;
|
|
|
|
if (!m_strPattern.IsEmpty())
|
|
{
|
|
strResult.Format(m_strPattern, dValue);
|
|
|
|
int nIndex = strResult.Find(_T("{V}"));
|
|
if (nIndex != -1)
|
|
{
|
|
CString str = DoubleToString(dValue);
|
|
|
|
strResult.Replace(_T("{V}"), str);
|
|
}
|
|
|
|
nIndex = strResult.Find(_T("{A}"));
|
|
if (nIndex != -1)
|
|
{
|
|
CString strArgument = pSeriesPoint->GetArgument();
|
|
|
|
if (pSeriesPoint->GetSeries()->GetArgumentScaleType() == xtpChartScaleDateTime)
|
|
{
|
|
COleDateTime dt((DATE)pSeriesPoint->GetArgumentValue());
|
|
strArgument = FormatDate(dt);
|
|
}
|
|
|
|
strResult.Replace(_T("{A}"), strArgument);
|
|
}
|
|
|
|
strResult.Replace(_T("{S}"), pSeriesPoint->GetSeries()->GetName());
|
|
}
|
|
else
|
|
{
|
|
strResult = DoubleToString(dValue);
|
|
}
|
|
|
|
return strResult;
|
|
}
|
|
|
|
void CXTPChartNumberFormat::CreateDateTimeFormat()
|
|
{
|
|
m_strActiveDateTimeFormat = m_strDateTimeFormat;
|
|
|
|
if (m_nDateTimeCategory == xtpChartDateTimeLongDate)
|
|
{
|
|
m_strActiveDateTimeFormat = GetLocaleString(LOCALE_SLONGDATE, 255);
|
|
}
|
|
else if (m_nDateTimeCategory == xtpChartDateTimeShortDate)
|
|
{
|
|
m_strActiveDateTimeFormat = GetLocaleString(LOCALE_SSHORTDATE, 255);
|
|
}
|
|
else if (m_nDateTimeCategory == xtpChartDateTimeMonthAndDay)
|
|
{
|
|
BOOL bDayMonth = GetLocaleLong(LOCALE_ILDATE) == 1;
|
|
|
|
if (bDayMonth)
|
|
m_strActiveDateTimeFormat = _T("d MMMM ");
|
|
else
|
|
m_strActiveDateTimeFormat = _T("MMMM d");
|
|
}
|
|
else if (m_nDateTimeCategory == xtpChartDateTimeMonthAndYear)
|
|
{
|
|
m_strActiveDateTimeFormat = GetLocaleString(LOCALE_SYEARMONTH, 255);
|
|
}
|
|
else if (m_nDateTimeCategory == xtpChartDateTimeLongTime || m_nDateTimeCategory == xtpChartDateTimeShortTime)
|
|
{
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// LOCALE_STIME // time separator
|
|
//
|
|
// LOCALE_ITLZERO //leading zeros in time field
|
|
// 0 No leading zeros for hours.
|
|
// 1 Leading zeros for hours.
|
|
//
|
|
// LOCALE_ITIME // time format specifier
|
|
// 0 AM / PM 12-hour format.
|
|
// 1 24-hour format.
|
|
//
|
|
// LOCALE_ITIMEMARKPOSN // time marker position
|
|
// 0 Use as suffix.
|
|
// 1 Use as prefix.
|
|
//
|
|
// LOCALE_S1159 // AM designator
|
|
// LOCALE_S2359 // PM designator
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
CString strTmp;
|
|
|
|
CString strTimeSeparator = GetLocaleString(LOCALE_STIME, 16);
|
|
|
|
BOOL b24HFormat = GetLocaleLong(LOCALE_ITIME) == 1;
|
|
|
|
BOOL bHLZero = GetLocaleLong(LOCALE_ITLZERO) == 1;
|
|
|
|
BOOL bAMPMPrefix = GetLocaleLong(LOCALE_ITIMEMARKPOSN) == 1;
|
|
|
|
//---------------------------------------------------------------------------
|
|
CString strTimeFormat;
|
|
strTimeFormat += strTimeSeparator;
|
|
strTimeFormat += _T("mm");
|
|
|
|
if (b24HFormat)
|
|
{
|
|
strTmp = bHLZero ? _T("HH") : _T("H");
|
|
strTimeFormat = strTmp + strTimeFormat;
|
|
}
|
|
else //12 AM/PM Format
|
|
{
|
|
strTmp = bHLZero ? _T("hh") : _T("h");
|
|
strTimeFormat = strTmp + strTimeFormat;
|
|
|
|
}
|
|
|
|
if (m_nDateTimeCategory == xtpChartDateTimeLongTime)
|
|
strTimeFormat = strTimeFormat + strTimeSeparator + _T("ss");
|
|
|
|
if (!b24HFormat)
|
|
{
|
|
if (bAMPMPrefix)
|
|
{
|
|
strTimeFormat = _T("tt ") + strTimeFormat;
|
|
}
|
|
else
|
|
{
|
|
strTimeFormat = strTimeFormat + _T(" tt");
|
|
}
|
|
}
|
|
|
|
m_strActiveDateTimeFormat = strTimeFormat;
|
|
}
|
|
}
|
|
|
|
CString CXTPChartNumberFormat::FormatDate(COleDateTime& dt) const
|
|
{
|
|
CString strResult;
|
|
|
|
if (m_nDateTimeCategory == xtpChartDateTimeGeneral)
|
|
{
|
|
return dt.Format((DWORD)0, m_nLocale);
|
|
}
|
|
else if (m_nDateTimeCategory != xtpChartDateTimeCustom)
|
|
{
|
|
SYSTEMTIME st;
|
|
if (dt.GetAsSystemTime(st))
|
|
{
|
|
if (m_nDateTimeCategory == xtpChartDateTimeLongTime || m_nDateTimeCategory == xtpChartDateTimeShortTime)
|
|
::GetTimeFormat(m_nLocale, 0, &st, m_strActiveDateTimeFormat, strResult.GetBufferSetLength(255), 255);
|
|
else
|
|
::GetDateFormat(m_nLocale, 0, &st, m_strActiveDateTimeFormat, strResult.GetBufferSetLength(255), 255);
|
|
strResult.ReleaseBuffer();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (m_strActiveDateTimeFormat.IsEmpty())
|
|
{
|
|
return dt.Format(VAR_DATEVALUEONLY);
|
|
}
|
|
else
|
|
{
|
|
if (m_strActiveDateTimeFormat.Find(_T("%")) >= 0)
|
|
return dt.Format(m_strActiveDateTimeFormat);
|
|
|
|
SYSTEMTIME st;
|
|
if (dt.GetAsSystemTime(st))
|
|
{
|
|
CString strPattern;
|
|
|
|
::GetTimeFormat(m_nLocale, 0, &st, m_strActiveDateTimeFormat, strPattern.GetBufferSetLength(255), 255);
|
|
strPattern.ReleaseBuffer();
|
|
|
|
::GetDateFormat(m_nLocale, 0, &st, strPattern, strResult.GetBufferSetLength(255), 255);
|
|
strResult.ReleaseBuffer();
|
|
}
|
|
}
|
|
}
|
|
|
|
return strResult;
|
|
}
|
|
|
|
#ifdef _XTP_ACTIVEX
|
|
|
|
BEGIN_DISPATCH_MAP(CXTPChartNumberFormat, CCmdTarget)
|
|
DISP_PROPERTY_EX_ID(CXTPChartNumberFormat, "Pattern", DISPID_VALUE, OleGetPattern, OleSetPattern, VT_BSTR)
|
|
DISP_PROPERTY_EX_ID(CXTPChartNumberFormat, "Category", 2, GetCategory, SetCategory, VT_I4)
|
|
DISP_PROPERTY_EX_ID(CXTPChartNumberFormat, "DecimalPlaces", 3, GetDecimalPlaces, SetDecimalPlaces, VT_I4)
|
|
DISP_PROPERTY_EX_ID(CXTPChartNumberFormat, "UseThousandSeparator", 4, GetUseThousandSeparator, SetUseThousandSeparator, VT_BOOL)
|
|
DISP_PROPERTY_EX_ID(CXTPChartNumberFormat, "Locale", 5, GetLocale, SetLocale, VT_I4)
|
|
DISP_PROPERTY_EX_ID(CXTPChartNumberFormat, "CurrencySymbol", 6, OleGetCurrencySymbol, OleSetCurrencySymbol, VT_BSTR)
|
|
DISP_PROPERTY_EX_ID(CXTPChartNumberFormat, "DateTimeCategory", 7, GetDateTimeCategory, SetDateTimeCategory, VT_I4)
|
|
DISP_PROPERTY_EX_ID(CXTPChartNumberFormat, "DateTimeFormat", 8, OleGetDateDateTimeFormat, SetDateTimeFormat, VT_BSTR)
|
|
END_DISPATCH_MAP()
|
|
|
|
|
|
// {A90BCC77-27BF-4cb1-9ABF-4558D9835223}
|
|
static const GUID IID_IChartNumberFormat =
|
|
{ 0xa90bcc77, 0x27bf, 0x4cb1, { 0x9a, 0xbf, 0x45, 0x58, 0xd9, 0x83, 0x52, 0x23 } };
|
|
|
|
BEGIN_INTERFACE_MAP(CXTPChartNumberFormat, CCmdTarget)
|
|
INTERFACE_PART(CXTPChartNumberFormat, IID_IChartNumberFormat, Dispatch)
|
|
END_INTERFACE_MAP()
|
|
|
|
IMPLEMENT_OLETYPELIB_EX(CXTPChartNumberFormat, IID_IChartNumberFormat)
|
|
|
|
|
|
BSTR CXTPChartNumberFormat::OleGetPattern()
|
|
{
|
|
return m_strPattern.AllocSysString();
|
|
}
|
|
|
|
void CXTPChartNumberFormat::OleSetPattern(LPCTSTR lpszValue)
|
|
{
|
|
SetPattern(lpszValue);
|
|
}
|
|
|
|
|
|
BSTR CXTPChartNumberFormat::OleGetCurrencySymbol()
|
|
{
|
|
return m_strCurrencySymbol.AllocSysString();
|
|
}
|
|
|
|
void CXTPChartNumberFormat::OleSetCurrencySymbol(LPCTSTR lpszValue)
|
|
{
|
|
SetCurrencySymbol(lpszValue);
|
|
}
|
|
|
|
BSTR CXTPChartNumberFormat::OleGetDateDateTimeFormat()
|
|
{
|
|
return m_strDateTimeFormat.AllocSysString();
|
|
}
|
|
|
|
|
|
#endif
|