21 #include <boost/property_tree/json_parser.hpp>
37 #include <rtl/math.hxx>
38 #include <rtl/ustrbuf.hxx>
40 #include <osl/diagnose.h>
69 for (
sal_Unicode aChar =
'0'; aChar <=
'9'; ++aChar )
70 _rRow.insert(
Transition( aChar, eNextState ) );
178 while (
END != eCurrentState )
181 TransitionTable::const_iterator aRow =
m_aTransitions.find( eCurrentState );
183 "NumberValidator::implValidateNormalized: invalid transition table (row not found)!" );
188 StateTransitions::const_iterator aTransition = aRow->second.find( *pCheckPos );
189 if ( aRow->second.end() != aTransition )
192 eCurrentState = aTransition->second;
203 "NumberValidator::implValidateNormalized: inconsistency!" );
209 return (
END == eCurrentState );
214 if ( _rText.empty() )
219 OUString sNormalized = OUString::Concat(
"_") + _rText +
"_";
248 if (--s_nReferences == 0)
251 s_cFormatter =
nullptr;
294 "FormattedField::SetTextFormatted : valid only with text formats !");
299 double dNumber = 0.0;
301 sal_uInt32 nTempFormatKey =
static_cast< sal_uInt32
>(
m_nFormatKey );
319 sal_Int32 nNewLen = sFormatted.getLength();
321 if ((nNewLen > nCurrentLen) && (aNewSel.
Max() == nCurrentLen))
323 if (aNewSel.
Min() == 0)
325 aNewSel.
Max() = nNewLen;
331 aNewSel.
Min() = aNewSel.
Max();
336 else if (aNewSel.
Max() == aNewSel.
Min())
338 aNewSel.
Max() = nNewLen;
339 aNewSel.
Min() = nNewLen;
342 else if (aNewSel.
Max() > nNewLen)
343 aNewSel.
Max() = nNewLen;
419 sal_Int32 nNewLen = rNew.getLength();
422 if ((nNewLen > nCurrentLen) && (aSel.
Max() == nCurrentLen))
432 aSel.
Max() = nNewLen;
435 else if (aSel.
Max() == aSel.
Min())
437 aSel.
Max() = nNewLen;
438 aSel.
Min() = nNewLen;
441 else if (aSel.
Max() > nNewLen)
442 aSel.
Max() = nNewLen;
452 bool bNeedFormatter = (
m_pFormatter ==
nullptr) && (nFormatKey != 0);
495 OUString sOldFormat =
GetFormat(aOldLang);
507 pFormatter->
PutandConvertEntry(sOldFormat, nCheckPos, nType, nDestKey, aOldLang, aNewLang,
true);
519 DBG_ASSERT(pFormatEntry !=
nullptr,
"FormattedField::GetFormat: no number format for the given format key.");
520 OUString sFormatString = pFormatEntry ? pFormatEntry->
GetFormatstring() : OUString();
523 return sFormatString;
533 OUString rFormat(rFormatString);
547 "FormattedField::GetThousandsSep : Are you sure what you are doing when setting the precision of a text format?");
549 bool bThousand, IsRed;
550 sal_uInt16 nPrecision, nLeadingCnt;
559 "FormattedField::SetThousandsSep : Are you sure what you are doing when setting the precision of a text format?");
562 bool bThousand, IsRed;
563 sal_uInt16 nPrecision, nLeadingCnt;
565 if (bThousand == _bUseSeparator)
575 sal_Int32 nCheckPos = 0;
588 "FormattedField::GetDecimalDigits : Are you sure what you are doing when setting the precision of a text format?");
590 bool bThousand, IsRed;
591 sal_uInt16 nPrecision, nLeadingCnt;
600 "FormattedField::SetDecimalDigits : Are you sure what you are doing when setting the precision of a text format?");
603 bool bThousand, IsRed;
604 sal_uInt16 nPrecision, nLeadingCnt;
606 if (nPrecision == _nPrecision)
616 sal_Int32 nCheckPos = 0;
749 if (!bForce && (dVal ==
GetValue()))
780 DBG_ASSERT(
CheckText(sNewText),
"FormattedField::ImplSetValue : formatted string doesn't match the criteria !");
797 bool bUseExternalFormatterValue =
false;
803 if (bUseExternalFormatterValue)
815 if (!bUseExternalFormatterValue)
833 sal_uInt32 nTempFormat = nStandardNumericFormat;
865 ::rtl::math::setNan(&dValue);
893 : m_rSpinButton(rSpinButton)
905 return m_rSpinButton.
GetText();
910 m_rSpinButton.SpinField::SetText(rText, rSel);
928 m_rSpinButton.SpinField::Modify();
932 class DoubleNumericFormatter :
public FieldFormatter
935 DoubleNumericField& m_rNumericSpinButton;
937 DoubleNumericFormatter(DoubleNumericField& rNumericSpinButton)
938 : FieldFormatter(rNumericSpinButton)
939 , m_rNumericSpinButton(rNumericSpinButton)
943 virtual bool CheckText(
const OUString& sText)
const override
948 return m_rNumericSpinButton.GetNumberValidator().isValidNumericFragment(sText);
953 m_rNumericSpinButton.ResetConformanceTester();
954 FieldFormatter::FormatChanged(nWhat);
958 class DoubleCurrencyFormatter :
public FieldFormatter
961 DoubleCurrencyField& m_rCurrencySpinButton;
962 bool m_bChangingFormat;
964 DoubleCurrencyFormatter(DoubleCurrencyField& rNumericSpinButton)
965 : FieldFormatter(rNumericSpinButton)
966 , m_rCurrencySpinButton(rNumericSpinButton)
967 , m_bChangingFormat(false)
973 if (m_bChangingFormat)
975 FieldFormatter::FormatChanged(nWhat);
986 m_rCurrencySpinButton.UpdateCurrencyFormat();
989 OSL_FAIL(
"DoubleCurrencyField::FormatChanged : somebody modified my key !");
996 FieldFormatter::FormatChanged(nWhat);
999 void GuardSetFormat(
const OUString& rString,
LanguageType eLanguage)
1002 m_bChangingFormat =
true;
1004 m_bChangingFormat =
false;
1013 m_xOwnFormatter.reset(
new DoubleNumericFormatter(*
this));
1015 ResetConformanceTester();
1018 DoubleNumericField::~DoubleNumericField() =
default;
1020 void DoubleNumericField::ResetConformanceTester()
1032 OUString sSeparator = aLocaleInfo.getNumThousandSep();
1033 if (!sSeparator.isEmpty())
1034 cSeparatorThousand = sSeparator[0];
1036 sSeparator = aLocaleInfo.getNumDecimalSep();
1037 if (!sSeparator.isEmpty())
1038 cSeparatorDecimal = sSeparator[0];
1048 m_xOwnFormatter.reset(
new DoubleCurrencyFormatter(*
this));
1051 m_bPrependCurrSym =
false;
1055 UpdateCurrencyFormat();
1058 void DoubleCurrencyField::setCurrencySymbol(
const OUString& rSymbol)
1060 if (m_sCurrencySymbol == rSymbol)
1063 m_sCurrencySymbol = rSymbol;
1064 UpdateCurrencyFormat();
1068 void DoubleCurrencyField::setPrependCurrSym(
bool _bPrepend)
1070 if (m_bPrependCurrSym == _bPrepend)
1073 m_bPrependCurrSym = _bPrepend;
1074 UpdateCurrencyFormat();
1078 void DoubleCurrencyField::UpdateCurrencyFormat()
1082 m_pFormatter->GetFormat(eLanguage);
1083 bool bThSep = m_pFormatter->GetThousandsSep();
1084 sal_uInt16 nDigits = m_pFormatter->GetDecimalDigits();
1095 OUStringBuffer sNewFormat;
1098 sNewFormat.append(
'#');
1099 sNewFormat.append(aLocaleInfo.getNumThousandSep());
1100 sNewFormat.append(
"##0");
1103 sNewFormat.append(
'0');
1107 sNewFormat.append(aLocaleInfo.getNumDecimalSep());
1109 OUStringBuffer sTemp;
1111 sNewFormat.append(sTemp);
1114 if (getPrependCurrSym())
1116 OUString sSymbol = getCurrencySymbol();
1120 OUStringBuffer sTemp(
"[$");
1121 sTemp.append(sSymbol);
1123 sTemp.append(sNewFormat);
1129 sTemp.append(
";[$");
1130 sTemp.append(sSymbol);
1131 sTemp.append(
"] -");
1132 sTemp.append(sNewFormat);
1138 OUString sTemp = getCurrencySymbol();
1142 sNewFormat.append(
" [$");
1143 sNewFormat.append(sTemp);
1144 sNewFormat.append(
']');
1148 static_cast<DoubleCurrencyFormatter*
>(m_pFormatter)->GuardSetFormat(sNewFormat.makeStringAndClear(), eLanguage);
1153 , m_pFormatter(nullptr)
1177 if (rKey ==
"digits")
1179 else if (rKey ==
"wrap")
1192 sal_Int64 nSpinSize = std::round(rFormatter.
GetSpinSize() * nScale);
1195 nValue = (nRemainder == 0) ? nValue + nSpinSize : nValue + nSpinSize - nRemainder;
1197 nValue = (nRemainder == 0) ? nValue + nSpinSize : nValue - nRemainder;
1200 rFormatter.
SetValue(static_cast<double>(nValue) / nScale);
1213 sal_Int64 nSpinSize = std::round(rFormatter.
GetSpinSize() * nScale);
1216 nValue = (nRemainder == 0) ? nValue - nSpinSize : nValue - nRemainder;
1218 nValue = (nRemainder == 0) ? nValue - nSpinSize : nValue - nSpinSize - nRemainder;
1221 rFormatter.
SetValue(static_cast<double>(nValue) / nScale);
1334 rtl_math_ConversionStatus eStatus;
1336 double fValue = ::rtl::math::stringToDouble(rStr,
'.', rFormatter.
GetDecimalDigits(), &eStatus, &nEnd );
1338 if (eStatus == rtl_math_ConversionStatus_Ok &&
1339 nEnd == rStr.getLength())
1350 SAL_WARN(
"vcl",
"fail to convert the value: " << rStr);
static bool toBool(std::string_view rValue)
OString stripEnd(const OString &rIn, char c)
static void lcl_insertStopTransition(StateTransitions &_rRow)
static void lcl_insertStartExponentTransition(StateTransitions &_rRow)
const CommandEvent * GetCommandEvent() const
std::unique_ptr< ContentProperties > pData
LanguageType getLanguageType(bool bResolveSystem=true) const
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
CommandEventId GetCommand() const
constexpr sal_uInt16 KEY_PAGEDOWN
#define LANGUAGE_DONTKNOW
MouseNotifyEvent GetType() const
bool implValidateNormalized(const OUString &_rText)
const AllSettings & GetSettings() const
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)
Reference< XComponentContext > getProcessComponentContext()
OString stripStart(const OString &rIn, char c)
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)
static void lcl_insertCommonPreCommaTransitions(StateTransitions &_rRow, const sal_Unicode _cThSep, const sal_Unicode _cDecSep)
OStringBuffer & padToLength(OStringBuffer &rBuffer, sal_Int32 nLength, char cFill= '\0')