24#include <config_features.h>
47#include <rtl/character.hxx>
48#include <rtl/math.hxx>
64static bool ImpStrChr( std::u16string_view str,
sal_Unicode c ) {
return str.find(c) != std::u16string_view::npos; }
72 sal_uInt16* pLen,
bool bOnlyIntntl )
74 sal_Unicode cIntntlDecSep, cIntntlGrpSep, cIntntlDecSepAlt;
79 cNonIntntlDecSep = cIntntlDecSep;
81 if (cIntntlDecSepAlt && cIntntlDecSepAlt == cNonIntntlDecSep)
86 cIntntlDecSep = cNonIntntlDecSep;
93 OUStringBuffer
aBuf( rWSrc.getLength());
98 while( *
p ==
' ' || *
p ==
'\t' )
107 if( rtl::isAsciiDigit( *
p ) || ((*
p == cNonIntntlDecSep || *
p == cIntntlDecSep ||
108 (cIntntlDecSep && *
p == cIntntlGrpSep) || (cIntntlDecSepAlt && *
p == cIntntlDecSepAlt)) &&
109 rtl::isAsciiDigit( *(
p+1) )))
117 OUStringBuffer aSearchStr(OUString::Concat(
"0123456789DEde") + OUStringChar(cNonIntntlDecSep));
118 if( cIntntlDecSep != cNonIntntlDecSep )
119 aSearchStr.append(cIntntlDecSep);
120 if( cIntntlDecSepAlt && cIntntlDecSepAlt != cNonIntntlDecSep )
121 aSearchStr.append(cIntntlDecSepAlt);
123 aSearchStr.append(cIntntlGrpSep);
124 const OUString pSearchStr = aSearchStr.makeStringAndClear();
125 static constexpr OUStringLiteral pDdEe =
u"DdEe";
129 if( bOnlyIntntl && *
p == cIntntlGrpSep )
134 if( *
p == cNonIntntlDecSep || *
p == cIntntlDecSep || (cIntntlDecSepAlt && *
p == cIntntlDecSepAlt) )
137 aBuf[
p - pDigitsStart] = cIntntlDecSep;
149 if( *
p ==
'D' || *
p ==
'd' )
151 aBuf[
p - pDigitsStart] =
'E';
171 if( decsep > 1 || exp > 1 )
174 rtl_math_ConversionStatus eStatus = rtl_math_ConversionStatus_Ok;
175 sal_Int32 nParseEnd = 0;
176 nVal = rtl::math::stringToDouble(
aBuf, cIntntlDecSep, cIntntlGrpSep, &eStatus, &nParseEnd );
177 if( eStatus != rtl_math_ConversionStatus_Ok || nParseEnd !=
aBuf.getLength() )
180 if( !decsep && !exp )
188 ndig = ndig - decsep;
190 if( ndig > 15 || ncdig > 6 )
194 static constexpr OUStringLiteral pTypes =
u"%!&#";
203 OUString aCmp(
"0123456789ABCDEF" );
220 while( rtl::isAsciiAlphanumeric( *
p ) )
229 OUString aBufStr(
aBuf.makeStringAndClear());
231 for(
const sal_Unicode* q = aBufStr.getStr(); bRes && *q; q++ )
236 l = ( l *
base ) +
i;
242 nVal =
static_cast<double>(l);
246#if HAVE_FEATURE_SCRIPTING
253 while (*
p ==
' ' || *
p ==
'\t')
256 *pLen =
static_cast<sal_uInt16
>(
p - pStart );
273 if( nRetError ==
ERRCODE_NONE && nLen != rSrc.getLength() )
290void ImpCvtNum(
double nNum,
short nPrec, OUString& rRes,
bool bCoreString )
292 sal_Unicode cDecimalSep, cThousandSep, cDecimalSepAlt;
298 rRes = rtl::math::doubleToUString(nNum, rtl_math_StringFormat_Automatic, nPrec, cDecimalSep,
true);
303 bool bChanged =
false;
307 switch( eTargetType )
314 sal_Unicode cDecimalSep, cThousandSep, cDecimalSepAlt;
318 if( cDecimalSep !=
'.' || (cDecimalSepAlt && cDecimalSepAlt !=
'.') )
320 sal_Int32
nPos = aNewString.indexOf( cDecimalSep );
321 if(
nPos == -1 && cDecimalSepAlt )
322 nPos = aNewString.indexOf( cDecimalSepAlt );
336 if( rSrc.equalsIgnoreAsciiCase(
"true") )
338 aNewString = OUString::number(
SbxTRUE );
341 else if( rSrc.equalsIgnoreAsciiCase(
"false") )
343 aNewString = OUString::number(
SbxFALSE );
361static sal_uInt16
printfmtstr(
const OUString& rStr, OUString& rRes,
const OUString& rFmt )
363 OUStringBuffer aTemp;
371 aTemp.append(*pStr++);
377 aTemp.append( *pStr ? *pStr++ :
u' ');
380 while( *pFmt && *pFmt !=
'\\' );
381 aTemp.append(*pStr ? *pStr++ :
u' ');
390 rRes = aTemp.makeStringAndClear();
391 return static_cast<sal_uInt16
>( pFmt - pFmtStart );
440enum class VbaFormatType
447#if HAVE_FEATURE_SCRIPTING
452 std::u16string_view mpVbaFormat;
454 const char* mpOOoFormat;
457const VbaFormatInfo pFormatInfoTable[] =
459 { VbaFormatType::Offset, std::u16string_view(u
"Long Date"),
NF_DATE_SYSTEM_LONG,
nullptr },
460 { VbaFormatType::UserDefined, std::u16string_view(u
"Medium Date"),
NF_NUMBER_STANDARD,
"DD-MMM-YY" },
462 { VbaFormatType::UserDefined, std::u16string_view(u
"Long Time"),
NF_NUMBER_STANDARD,
"H:MM:SS AM/PM" },
463 { VbaFormatType::Offset, std::u16string_view(u
"Medium Time"),
NF_TIME_HHMMAMPM,
nullptr },
464 { VbaFormatType::Offset, std::u16string_view(u
"Short Time"),
NF_TIME_HHMM,
nullptr },
467 { VbaFormatType::UserDefined, std::u16string_view(u
"ttttt"),
NF_NUMBER_STANDARD,
"H:MM:SS AM/PM" },
468 { VbaFormatType::Offset, std::u16string_view(u
"ww"),
NF_DATE_WW,
nullptr },
472const VbaFormatInfo* getFormatInfo( std::u16string_view rFmt )
474 const VbaFormatInfo* pInfo = pFormatInfoTable;
475 while( pInfo->meType != VbaFormatType::Null )
487#if HAVE_FEATURE_SCRIPTING
488constexpr OUStringLiteral VBAFORMAT_GENERALDATE =
u"General Date";
489constexpr OUStringLiteral VBAFORMAT_C =
u"c";
490constexpr OUStringLiteral VBAFORMAT_N =
u"n";
491constexpr OUStringLiteral VBAFORMAT_NN =
u"nn";
492constexpr OUStringLiteral VBAFORMAT_W =
u"w";
493constexpr OUStringLiteral VBAFORMAT_Y =
u"y";
494constexpr OUStringLiteral VBAFORMAT_LOWERCASE =
u"<";
495constexpr OUStringLiteral VBAFORMAT_UPPERCASE =
u">";
506#if HAVE_FEATURE_SCRIPTING
514 if( pFmt->equalsIgnoreAsciiCase( VBAFORMAT_LOWERCASE ) )
519 if( pFmt->equalsIgnoreAsciiCase( VBAFORMAT_UPPERCASE ) )
526 std::shared_ptr<SvNumberFormatter> pFormatter;
539 sal_uInt32
nIndex = pFormatter->GetStandardIndex( eLangType);
543 bool bSuccess = pFormatter->IsNumberFormat(
aStr,
nIndex, nNumber );
548 sal_Int32 nCheckPos = 0;
550 OUString aFmtStr = *pFmt;
551 const VbaFormatInfo* pInfo = getFormatInfo( aFmtStr );
552 if( pInfo->meType != VbaFormatType::Null )
554 if( pInfo->meType == VbaFormatType::Offset )
556 nIndex = pFormatter->GetFormatIndex( pInfo->meOffset, eLangType );
560 aFmtStr = OUString::createFromAscii(pInfo->mpOOoFormat);
563 pFormatter->GetOutputString( nNumber,
nIndex, rRes, &pCol );
565 else if( aFmtStr.equalsIgnoreAsciiCase( VBAFORMAT_GENERALDATE )
566 || aFmtStr.equalsIgnoreAsciiCase( VBAFORMAT_C ))
568 if( nNumber <=-1.0 || nNumber >= 1.0 )
572 pFormatter->GetOutputString( nNumber,
nIndex, rRes, &pCol );
575 if( floor( nNumber ) != nNumber )
577 aFmtStr =
"H:MM:SS AM/PM";
580 pFormatter->GetOutputString( nNumber,
nIndex, aTime, &pCol );
587 aFmtStr =
"H:MM:SS AM/PM";
589 pFormatter->GetOutputString( nNumber,
nIndex, rRes, &pCol );
592 else if( aFmtStr.equalsIgnoreAsciiCase( VBAFORMAT_N ) ||
593 aFmtStr.equalsIgnoreAsciiCase( VBAFORMAT_NN ))
596 if( nMin < 10 && aFmtStr.equalsIgnoreAsciiCase( VBAFORMAT_NN ))
601 aBuf[1] =
'0' + nMin;
602 rRes = OUString(
aBuf, std::size(
aBuf));
606 rRes = OUString::number(nMin);
609 else if( aFmtStr.equalsIgnoreAsciiCase( VBAFORMAT_W ))
612 rRes = OUString::number(nWeekDay);
614 else if( aFmtStr.equalsIgnoreAsciiCase( VBAFORMAT_Y ))
619 sal_Int32 nYear32 = 1 + sal_Int32( nNumber - dBaseDate );
620 rRes = OUString::number(nYear32);
625 pFormatter->GetOutputString( nNumber,
nIndex, rRes, &pCol );
645 nComma = 0;
goto cvt;
647 nComma = 6;
goto cvt;
684 OUString aOnStrg =
BasResId(STR_BASICKEY_FORMAT_ON);
685 OUString aOffStrg =
BasResId(STR_BASICKEY_FORMAT_OFF);
686 OUString aYesStrg =
BasResId(STR_BASICKEY_FORMAT_YES);
687 OUString aNoStrg =
BasResId(STR_BASICKEY_FORMAT_NO);
688 OUString aTrueStrg =
BasResId(STR_BASICKEY_FORMAT_TRUE);
689 OUString aFalseStrg =
BasResId(STR_BASICKEY_FORMAT_FALSE);
690 OUString aCurrencyFormatStrg =
BasResId(STR_BASICKEY_FORMAT_CURRENCY);
693 cComma,c1000,aOnStrg,aOffStrg,
694 aYesStrg,aNoStrg,aTrueStrg,aFalseStrg,
695 aCurrencyStrg,aCurrencyFormatStrg );
SbxAppData & GetSbxData_Impl()
const LanguageTag & GetLanguageTag() const
static const AllSettings & GetSettings()
OUString uppercase(const OUString &rStr, sal_Int32 nPos, sal_Int32 nCount) const
OUString lowercase(const OUString &rStr, sal_Int32 nPos, sal_Int32 nCount) const
LanguageType getLanguageType(bool bResolveSystem=true) const
const OUString & getNumThousandSep() const
const OUString & getCurrSymbol() const
const OUString & getNumDecimalSepAlt() const
const OUString & getNumDecimalSep() const
static std::shared_ptr< SvNumberFormatter > PrepareNumberFormatter(sal_uInt32 &rnStdDateIdx, sal_uInt32 &rnStdTimeIdx, sal_uInt32 &rnStdDateTimeIdx, LanguageType const *peFormatterLangType=nullptr, DateOrder const *peFormatterDateOrder=nullptr)
std::shared_ptr< SvNumberFormatter > const & GetNumberFormatter()
static bool isVBAEnabled()
static void SetError(ErrCode)
OUString GetOUString() const
virtual bool IsFixed() const override
static ErrCode ScanNumIntnl(const OUString &rSrc, double &nVal, bool bSingle=false)
bool SetType(SbxDataType)
bool IsNumericRTL() const
bool Scan(const OUString &, sal_uInt16 *)
void Format(OUString &, const OUString *=nullptr) const
virtual SbxDataType GetType() const override
const LocaleDataWrapper & GetLocaleData() const
const CharClass & GetCharClass() const
bool implDateSerial(sal_Int16 nYear, sal_Int16 nMonth, sal_Int16 nDay, bool bUseTwoDigitYear, SbDateCorrection eCorr, double &rdRet)
sal_Int16 implGetWeekDay(double aDate, bool bFirstDayParam=false, sal_Int16 nFirstDay=0)
sal_Int16 implGetDateYear(double aDate)
sal_Int16 implGetMinute(double dDate)
#define LANGUAGE_ENGLISH_US
std::locale Create(std::string_view aPrefixName, const LanguageTag &rLocale)
OUString get(TranslateId sContextAndId, const std::locale &loc)
bool equalsIgnoreAsciiCase(std::u16string_view s1, std::u16string_view s2)
bool LibreOffice6FloatingPointMode()
#define ERRCODE_BASIC_PROP_READONLY
#define ERRCODE_BASIC_CONVERSION
float ImpGetSingle(const SbxValues *)
constexpr sal_Int32 SbxMINLNG
OUString BasResId(TranslateId aId)
ErrCode ImpScan(const OUString &rWSrc, double &nVal, SbxDataType &rType, sal_uInt16 *pLen, bool bOnlyIntntl)
static bool ImpStrChr(std::u16string_view str, sal_Unicode c)
bool ImpConvStringExt(OUString &rSrc, SbxDataType eTargetType)
void ImpCvtNum(double nNum, short nPrec, OUString &rRes, bool bCoreString)
static sal_uInt16 printfmtstr(const OUString &rStr, OUString &rRes, const OUString &rFmt)
void ImpGetIntntlSep(sal_Unicode &rcDecimalSep, sal_Unicode &rcThousandSep, sal_Unicode &rcDecimalSepAlt)
std::locale BasResLocale()
std::unique_ptr< SbxBasicFormater > pBasicFormater
LanguageType eBasicFormaterLangType