21 #include <boost/property_tree/json_parser.hpp>
38 #include <rtl/math.hxx>
39 #include <rtl/ustrbuf.hxx>
42 #include <osl/diagnose.h>
71 for (
sal_Unicode aChar =
'0'; aChar <=
'9'; ++aChar )
72 _rRow.insert(
Transition( aChar, eNextState ) );
180 while (
END != eCurrentState )
183 TransitionTable::const_iterator aRow =
m_aTransitions.find( eCurrentState );
185 "NumberValidator::implValidateNormalized: invalid transition table (row not found)!" );
190 StateTransitions::const_iterator aTransition = aRow->second.find( *pCheckPos );
191 if ( aRow->second.end() != aTransition )
194 eCurrentState = aTransition->second;
205 "NumberValidator::implValidateNormalized: inconsistency!" );
211 return (
END == eCurrentState );
216 if ( _rText.empty() )
221 OUString sNormalized = OUString::Concat(
"_") + _rText +
"_";
250 if (--s_nReferences == 0)
253 s_cFormatter =
nullptr;
296 "FormattedField::SetTextFormatted : valid only with text formats !");
301 double dNumber = 0.0;
303 sal_uInt32 nTempFormatKey =
static_cast< sal_uInt32
>(
m_nFormatKey );
321 sal_Int32 nNewLen = sFormatted.getLength();
323 if ((nNewLen > nCurrentLen) && (aNewSel.
Max() == nCurrentLen))
325 if (aNewSel.
Min() == 0)
327 aNewSel.
Max() = nNewLen;
333 aNewSel.
Min() = aNewSel.
Max();
338 else if (aNewSel.
Max() == aNewSel.
Min())
340 aNewSel.
Max() = nNewLen;
341 aNewSel.
Min() = nNewLen;
344 else if (aNewSel.
Max() > nNewLen)
345 aNewSel.
Max() = nNewLen;
421 sal_Int32 nNewLen = rNew.getLength();
424 if ((nNewLen > nCurrentLen) && (aSel.
Max() == nCurrentLen))
434 aSel.
Max() = nNewLen;
437 else if (aSel.
Max() == aSel.
Min())
439 aSel.
Max() = nNewLen;
440 aSel.
Min() = nNewLen;
443 else if (aSel.
Max() > nNewLen)
444 aSel.
Max() = nNewLen;
454 bool bNeedFormatter = (
m_pFormatter ==
nullptr) && (nFormatKey != 0);
497 OUString sOldFormat =
GetFormat(aOldLang);
509 pFormatter->
PutandConvertEntry(sOldFormat, nCheckPos, nType, nDestKey, aOldLang, aNewLang,
true);
521 DBG_ASSERT(pFormatEntry !=
nullptr,
"FormattedField::GetFormat: no number format for the given format key.");
522 OUString sFormatString = pFormatEntry ? pFormatEntry->
GetFormatstring() : OUString();
525 return sFormatString;
535 OUString rFormat(rFormatString);
549 "FormattedField::GetThousandsSep : Are you sure what you are doing when setting the precision of a text format?");
551 bool bThousand, IsRed;
552 sal_uInt16 nPrecision, nLeadingCnt;
561 "FormattedField::SetThousandsSep : Are you sure what you are doing when setting the precision of a text format?");
564 bool bThousand, IsRed;
565 sal_uInt16 nPrecision, nLeadingCnt;
567 if (bThousand == _bUseSeparator)
577 sal_Int32 nCheckPos = 0;
590 "FormattedField::GetDecimalDigits : Are you sure what you are doing when setting the precision of a text format?");
592 bool bThousand, IsRed;
593 sal_uInt16 nPrecision, nLeadingCnt;
602 "FormattedField::SetDecimalDigits : Are you sure what you are doing when setting the precision of a text format?");
605 bool bThousand, IsRed;
606 sal_uInt16 nPrecision, nLeadingCnt;
608 if (nPrecision == _nPrecision)
618 sal_Int32 nCheckPos = 0;
751 if (!bForce && (dVal ==
GetValue()))
782 DBG_ASSERT(
CheckText(sNewText),
"FormattedField::ImplSetValue : formatted string doesn't match the criteria !");
799 bool bUseExternalFormatterValue =
false;
805 if (bUseExternalFormatterValue)
817 if (!bUseExternalFormatterValue)
835 sal_uInt32 nTempFormat = nStandardNumericFormat;
888 : m_rSpinButton(rSpinButton)
900 return m_rSpinButton.
GetText();
905 m_rSpinButton.SpinField::SetText(rText, rSel);
923 m_rSpinButton.SpinField::Modify();
927 class DoubleNumericFormatter :
public FieldFormatter
930 DoubleNumericField& m_rNumericSpinButton;
932 DoubleNumericFormatter(DoubleNumericField& rNumericSpinButton)
933 : FieldFormatter(rNumericSpinButton)
934 , m_rNumericSpinButton(rNumericSpinButton)
938 virtual bool CheckText(
const OUString& sText)
const override
943 return m_rNumericSpinButton.GetNumberValidator().isValidNumericFragment(sText);
948 m_rNumericSpinButton.ResetConformanceTester();
949 FieldFormatter::FormatChanged(nWhat);
953 class DoubleCurrencyFormatter :
public FieldFormatter
956 DoubleCurrencyField& m_rCurrencySpinButton;
957 bool m_bChangingFormat;
959 DoubleCurrencyFormatter(DoubleCurrencyField& rNumericSpinButton)
960 : FieldFormatter(rNumericSpinButton)
961 , m_rCurrencySpinButton(rNumericSpinButton)
962 , m_bChangingFormat(
false)
968 if (m_bChangingFormat)
970 FieldFormatter::FormatChanged(nWhat);
981 m_rCurrencySpinButton.UpdateCurrencyFormat();
984 OSL_FAIL(
"DoubleCurrencyField::FormatChanged : somebody modified my key !");
991 FieldFormatter::FormatChanged(nWhat);
994 void GuardSetFormat(
const OUString& rString,
LanguageType eLanguage)
997 m_bChangingFormat =
true;
999 m_bChangingFormat =
false;
1008 m_xOwnFormatter.reset(
new DoubleNumericFormatter(*
this));
1010 ResetConformanceTester();
1013 DoubleNumericField::~DoubleNumericField() =
default;
1015 void DoubleNumericField::ResetConformanceTester()
1027 OUString sSeparator = aLocaleInfo.getNumThousandSep();
1028 if (!sSeparator.isEmpty())
1029 cSeparatorThousand = sSeparator[0];
1031 sSeparator = aLocaleInfo.getNumDecimalSep();
1032 if (!sSeparator.isEmpty())
1033 cSeparatorDecimal = sSeparator[0];
1043 m_xOwnFormatter.reset(
new DoubleCurrencyFormatter(*
this));
1046 m_bPrependCurrSym =
false;
1050 UpdateCurrencyFormat();
1053 void DoubleCurrencyField::setCurrencySymbol(
const OUString& rSymbol)
1055 if (m_sCurrencySymbol == rSymbol)
1058 m_sCurrencySymbol = rSymbol;
1059 UpdateCurrencyFormat();
1063 void DoubleCurrencyField::setPrependCurrSym(
bool _bPrepend)
1065 if (m_bPrependCurrSym == _bPrepend)
1068 m_bPrependCurrSym = _bPrepend;
1069 UpdateCurrencyFormat();
1073 void DoubleCurrencyField::UpdateCurrencyFormat()
1077 m_pFormatter->GetFormat(eLanguage);
1078 bool bThSep = m_pFormatter->GetThousandsSep();
1079 sal_uInt16 nDigits = m_pFormatter->GetDecimalDigits();
1090 OUStringBuffer sNewFormat;
1093 sNewFormat.append(
'#');
1094 sNewFormat.append(aLocaleInfo.getNumThousandSep());
1095 sNewFormat.append(
"##0");
1098 sNewFormat.append(
'0');
1102 sNewFormat.append(aLocaleInfo.getNumDecimalSep());
1106 if (getPrependCurrSym())
1108 OUString sSymbol = getCurrencySymbol();
1111 OUStringBuffer sTemp(
"[$");
1112 sTemp.append(sSymbol);
1114 sTemp.append(sNewFormat);
1120 sTemp.append(
";[$");
1121 sTemp.append(sSymbol);
1122 sTemp.append(
"] -");
1123 sTemp.append(sNewFormat);
1129 OUString sTemp = getCurrencySymbol();
1132 sNewFormat.append(
" [$");
1133 sNewFormat.append(sTemp);
1134 sNewFormat.append(
']');
1138 static_cast<DoubleCurrencyFormatter*
>(m_pFormatter)->GuardSetFormat(sNewFormat.makeStringAndClear(), eLanguage);
1143 , m_pFormatter(nullptr)
1167 if (rKey ==
"digits")
1169 else if (rKey ==
"wrap")
1182 sal_Int64 nSpinSize = std::round(rFormatter.
GetSpinSize() * nScale);
1185 nValue = (nRemainder == 0) ? nValue + nSpinSize : nValue + nSpinSize - nRemainder;
1187 nValue = (nRemainder == 0) ? nValue + nSpinSize : nValue - nRemainder;
1190 rFormatter.
SetValue(static_cast<double>(nValue) / nScale);
1203 sal_Int64 nSpinSize = std::round(rFormatter.
GetSpinSize() * nScale);
1206 nValue = (nRemainder == 0) ? nValue - nSpinSize : nValue - nRemainder;
1208 nValue = (nRemainder == 0) ? nValue - nSpinSize : nValue - nSpinSize - nRemainder;
1211 rFormatter.
SetValue(static_cast<double>(nValue) / nScale);
1324 rtl_math_ConversionStatus eStatus;
1326 double fValue = ::rtl::math::stringToDouble(rStr,
'.', rFormatter.
GetDecimalDigits(), &eStatus, &nEnd );
1328 if (eStatus == rtl_math_ConversionStatus_Ok &&
1329 nEnd == rStr.getLength())
1340 SAL_WARN(
"vcl",
"fail to convert the value: " << rStr);
static bool toBool(std::string_view rValue)
static void lcl_insertStopTransition(StateTransitions &_rRow)
static void lcl_insertStartExponentTransition(StateTransitions &_rRow)
const CommandEvent * GetCommandEvent() const
LanguageType getLanguageType(bool bResolveSystem=true) const
std::unique_ptr< sal_Int32[]> pData
SelectionOptions GetSelectionOptions() const
#define SAL_INFO_IF(condition, area, stream)
const StyleSettings & GetStyleSettings() const
std::function< std::unique_ptr< UIObject >vcl::Window *)> FactoryFunction
::std::map< sal_Unicode, State > StateTransitions
sal_uInt16 GetCode() const
const KeyEvent * GetKeyEvent() const
virtual void DumpAsPropertyTree(tools::JsonWriter &rJsonWriter) override
Dumps itself and potentially its children to a property tree, to be written easily to JSON...
const sal_Int16 FORMATTEDFIELD
virtual bool set_property(const OString &rKey, const OUString &rValue) override
const CommandWheelData * GetWheelData() const
TransitionTable m_aTransitions
constexpr sal_uInt16 KEY_UP
const LocaleDataWrapper & GetLocaleData() const
virtual void dispose() override
This is intended to be used to clear any locally held references to other Window-subclass objects...
StateTransitions::value_type Transition
static void lcl_insertSignTransitions(StateTransitions &_rRow, const State eNextState)
constexpr sal_uInt32 NUMBERFORMAT_ENTRY_NOT_FOUND
constexpr sal_uInt16 KEY_PAGEUP
virtual void SetModifyFlag()
virtual const Selection & GetSelection() const
sal_uInt16 GetModifier() const
virtual void SetSelection(const Selection &rSelection)
constexpr sal_uInt16 KEY_DOWN
virtual bool EventNotify(NotifyEvent &rNEvt) override
#define DBG_ASSERT(sCon, aError)
void SetControlForeground()
CommandWheelMode GetMode() const
virtual OUString GetText() const override
const AllSettings & GetSettings() const
CommandEventId GetCommand() const
constexpr sal_uInt16 KEY_PAGEDOWN
#define LANGUAGE_DONTKNOW
MouseNotifyEvent GetType() const
bool implValidateNormalized(const OUString &_rText)
const OUString & getCurrSymbol() const
static void lcl_insertDigitTransitions(StateTransitions &_rRow, const State eNextState)
const vcl::KeyCode & GetKeyCode() const
NumberValidator(const sal_Unicode _cThSep, const sal_Unicode _cDecSep)
OString strip(const OString &rIn, char c)
Reference< XComponentContext > getProcessComponentContext()
virtual bool PreNotify(NotifyEvent &rNEvt) override
const LanguageTag & GetLanguageTag() const
#define SAL_WARN(area, stream)
virtual bool IsReadOnly() const
NF_EVALDATEFORMAT_FORMAT_INTL
bool isValidNumericFragment(std::u16string_view _rText)
bool m_bDetectedRangeSegmentation false
static void lcl_insertCommonPreCommaTransitions(StateTransitions &_rRow, const sal_Unicode _cThSep, const sal_Unicode _cDecSep)
OStringBuffer & padToLength(OStringBuffer &rBuffer, sal_Int32 nLength, char cFill= '\0')