Resolves: tdf#134455 Let TIMEVALUE() use lax time recognition
... to accept minutes or seconds >59 Prepare SvNumInputOptions as enum class in case further options would be needed for anything else. Change-Id: Ie9ae62adf68f9948e23f55ac32c09a6b992a36e2 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/97784 Reviewed-by: Eike Rathke <erack@redhat.com> Tested-by: Jenkins
This commit is contained in:
@@ -377,6 +377,16 @@ public:
|
||||
|
||||
typedef std::vector< OUString > NfWSStringsDtor;
|
||||
|
||||
/** Input options to be used with IsNumberFormat() */
|
||||
enum class SvNumInputOptions : sal_uInt16
|
||||
{
|
||||
NONE = 0,
|
||||
LAX_TIME = 1 ///< allow input of minutes or seconds >59
|
||||
};
|
||||
namespace o3tl {
|
||||
template<> struct typed_flags<SvNumInputOptions> : is_typed_flags<SvNumInputOptions, 0x0001> {};
|
||||
}
|
||||
|
||||
class SvNumberFormatterRegistry_Impl;
|
||||
class NfCurrencyTable;
|
||||
|
||||
@@ -536,7 +546,8 @@ public:
|
||||
returned in fOutNumber
|
||||
<FALSE/> if input is not a number
|
||||
*/
|
||||
bool IsNumberFormat( const OUString& sString, sal_uInt32& F_Index, double& fOutNumber );
|
||||
bool IsNumberFormat( const OUString& sString, sal_uInt32& F_Index, double& fOutNumber,
|
||||
SvNumInputOptions eInputOptions = SvNumInputOptions::NONE );
|
||||
|
||||
/// Format a number according to a format index, return string and color
|
||||
void GetOutputString( const double& fOutNumber, sal_uInt32 nFIndex,
|
||||
|
||||
@@ -935,7 +935,7 @@ void ScInterpreter::ScGetTimeValue()
|
||||
OUString aInputString = GetString().getString();
|
||||
sal_uInt32 nFIndex = 0; // damit default Land/Spr.
|
||||
double fVal;
|
||||
if (pFormatter->IsNumberFormat(aInputString, nFIndex, fVal))
|
||||
if (pFormatter->IsNumberFormat(aInputString, nFIndex, fVal, SvNumInputOptions::LAX_TIME))
|
||||
{
|
||||
SvNumFormatType eType = pFormatter->GetType(nFIndex);
|
||||
if (eType == SvNumFormatType::TIME || eType == SvNumFormatType::DATETIME)
|
||||
|
||||
@@ -956,7 +956,9 @@ inline bool ImpSvNumberInputScan::GetNextNumber( sal_uInt16& i, sal_uInt16& j )
|
||||
|
||||
bool ImpSvNumberInputScan::GetTimeRef( double& fOutNumber,
|
||||
sal_uInt16 nIndex, // j-value of the first numeric time part of input, default 0
|
||||
sal_uInt16 nCnt ) const // count of numeric time parts
|
||||
sal_uInt16 nCnt, // count of numeric time parts
|
||||
SvNumInputOptions eInputOptions
|
||||
) const
|
||||
{
|
||||
bool bRet = true;
|
||||
sal_uInt16 nHour;
|
||||
@@ -1005,13 +1007,15 @@ bool ImpSvNumberInputScan::GetTimeRef( double& fOutNumber,
|
||||
else if (nIndex - nStartIndex < nCnt)
|
||||
{
|
||||
nMinute = static_cast<sal_uInt16>(sStrArray[nNums[nIndex++]].toInt32());
|
||||
if (nIndex > 1 && nMinute > 59)
|
||||
if (!(eInputOptions & SvNumInputOptions::LAX_TIME)
|
||||
&& nIndex > 1 && nMinute > 59)
|
||||
bRet = false; // 1:60 or 1:123 is invalid, 123:1 is valid
|
||||
}
|
||||
if (nIndex - nStartIndex < nCnt)
|
||||
{
|
||||
nSecond = static_cast<sal_uInt16>(sStrArray[nNums[nIndex++]].toInt32());
|
||||
if (nIndex > 1 && nSecond > 59 && !(nHour == 23 && nMinute == 59 && nSecond == 60))
|
||||
if (!(eInputOptions & SvNumInputOptions::LAX_TIME)
|
||||
&& nIndex > 1 && nSecond > 59 && !(nHour == 23 && nMinute == 59 && nSecond == 60))
|
||||
bRet = false; // 1:60 or 1:123 or 1:1:123 is invalid, 123:1 or 123:1:1 is valid, or leap second
|
||||
}
|
||||
if (nIndex - nStartIndex < nCnt)
|
||||
@@ -3659,9 +3663,10 @@ void ImpSvNumberInputScan::ChangeNullDate( const sal_uInt16 Day,
|
||||
* Does rString represent a number (also date, time et al)
|
||||
*/
|
||||
bool ImpSvNumberInputScan::IsNumberFormat( const OUString& rString, // string to be analyzed
|
||||
SvNumFormatType& F_Type, // IN: old type, OUT: new type
|
||||
SvNumFormatType& F_Type, // IN: old type, OUT: new type
|
||||
double& fOutNumber, // OUT: number if convertible
|
||||
const SvNumberformat* pFormat ) // maybe a number format to match against
|
||||
const SvNumberformat* pFormat, // maybe a number format to match against
|
||||
SvNumInputOptions eInputOptions )
|
||||
{
|
||||
OUString aString;
|
||||
bool res; // return value
|
||||
@@ -4062,7 +4067,7 @@ bool ImpSvNumberInputScan::IsNumberFormat( const OUString& rString, // s
|
||||
break;
|
||||
|
||||
case SvNumFormatType::TIME:
|
||||
res = GetTimeRef(fOutNumber, 0, nNumericsCnt);
|
||||
res = GetTimeRef(fOutNumber, 0, nNumericsCnt, eInputOptions);
|
||||
if ( nSign < 0 )
|
||||
{
|
||||
fOutNumber = -fOutNumber;
|
||||
@@ -4078,7 +4083,7 @@ bool ImpSvNumberInputScan::IsNumberFormat( const OUString& rString, // s
|
||||
if ( res )
|
||||
{
|
||||
double fTime;
|
||||
res = GetTimeRef( fTime, k, nNumericsCnt - k );
|
||||
res = GetTimeRef( fTime, k, nNumericsCnt - k, eInputOptions);
|
||||
fOutNumber += fTime;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -46,9 +46,10 @@ public:
|
||||
|
||||
/// convert input string to number
|
||||
bool IsNumberFormat( const OUString& rString, /// input string
|
||||
SvNumFormatType& F_Type, /// format type (in + out)
|
||||
SvNumFormatType& F_Type, /// format type (in + out)
|
||||
double& fOutNumber, /// value determined (out)
|
||||
const SvNumberformat* pFormat); /// number format to which compare against
|
||||
const SvNumberformat* pFormat, /// number format to which compare against
|
||||
SvNumInputOptions eInputOptions);
|
||||
|
||||
/// after IsNumberFormat: get decimal position
|
||||
short GetDecPos() const { return nDecPos; }
|
||||
@@ -321,7 +322,8 @@ private:
|
||||
*/
|
||||
bool GetTimeRef( double& fOutNumber, // result as double
|
||||
sal_uInt16 nIndex, // Index of hour in input
|
||||
sal_uInt16 nCnt ) const; // Count of time substrings in input
|
||||
sal_uInt16 nCnt, // Count of time substrings in input
|
||||
SvNumInputOptions eInputOptions ) const;
|
||||
sal_uInt16 ImplGetDay ( sal_uInt16 nIndex ) const; // Day input, 0 if no match
|
||||
sal_uInt16 ImplGetMonth( sal_uInt16 nIndex ) const; // Month input, zero based return, NumberOfMonths if no match
|
||||
sal_uInt16 ImplGetYear ( sal_uInt16 nIndex ); // Year input, 0 if no match
|
||||
|
||||
@@ -1126,7 +1126,8 @@ SvNumberFormatTable& SvNumberFormatter::GetEntryTable(
|
||||
|
||||
bool SvNumberFormatter::IsNumberFormat(const OUString& sString,
|
||||
sal_uInt32& F_Index,
|
||||
double& fOutNumber)
|
||||
double& fOutNumber,
|
||||
SvNumInputOptions eInputOptions)
|
||||
{
|
||||
::osl::MutexGuard aGuard( GetInstanceMutex() );
|
||||
|
||||
@@ -1164,7 +1165,7 @@ bool SvNumberFormatter::IsNumberFormat(const OUString& sString,
|
||||
}
|
||||
else
|
||||
{
|
||||
res = pStringScanner->IsNumberFormat(sString, RType, fOutNumber, pFormat);
|
||||
res = pStringScanner->IsNumberFormat(sString, RType, fOutNumber, pFormat, eInputOptions);
|
||||
}
|
||||
if (res && !IsCompatible(FType, RType)) // non-matching type
|
||||
{
|
||||
|
||||
@@ -809,7 +809,7 @@ SvNumberformat::SvNumberformat(OUString& rString,
|
||||
{
|
||||
sal_Int32 nDecPos;
|
||||
SvNumFormatType F_Type = SvNumFormatType::UNDEFINED;
|
||||
if (!pISc->IsNumberFormat(sStr, F_Type, fNumber, nullptr) ||
|
||||
if (!pISc->IsNumberFormat(sStr, F_Type, fNumber, nullptr, SvNumInputOptions::NONE) ||
|
||||
( F_Type != SvNumFormatType::NUMBER &&
|
||||
F_Type != SvNumFormatType::SCIENTIFIC) )
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user