diff options
author | kirchhoffb <bjoern.kirchhoff@escriba.de> | 2020-06-20 17:34:46 +0200 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.com> | 2020-11-10 09:16:22 +0100 |
commit | abfee0d2517195dfe49be8d538a48b31f4fb0eef (patch) | |
tree | 3d5e403c36c061a00d815df45caa27aed507f4ea | |
parent | 0afba07a597bf1d361624e10968855a802b859a0 (diff) |
sw user field type: fix failing string to double conversion
For converting a string to a double, we need to know the language of the
string. We should not assume, that this language is always the system locale,
because the system locale can change during a session.
Change-Id: Ic851d7430bba7392c7e2c8b36912467eee935f9c
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/96776
Tested-by: Jenkins
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
-rw-r--r-- | sw/inc/usrfld.hxx | 2 | ||||
-rw-r--r-- | sw/qa/extras/layout/layout2.cxx | 29 | ||||
-rw-r--r-- | sw/source/core/fields/usrfld.cxx | 24 |
3 files changed, 48 insertions, 7 deletions
diff --git a/sw/inc/usrfld.hxx b/sw/inc/usrfld.hxx index c297ef013409..589c379a5d1c 100644 --- a/sw/inc/usrfld.hxx +++ b/sw/inc/usrfld.hxx @@ -41,6 +41,8 @@ class SW_DLLPUBLIC SwUserFieldType final : public SwValueFieldType OUString m_aName; /// String value type. OUString m_aContent; + /// Language used by m_aContents + OUString m_aContentLang; sal_uInt16 m_nType; public: diff --git a/sw/qa/extras/layout/layout2.cxx b/sw/qa/extras/layout/layout2.cxx index 1107f3cff20e..d0cbeaa7ced6 100644 --- a/sw/qa/extras/layout/layout2.cxx +++ b/sw/qa/extras/layout/layout2.cxx @@ -1274,7 +1274,7 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter2, testUserFieldTypeLanguage) OUString sLocaleConfigString = aOptions.GetLanguageTag().getBcp47(); aOptions.SetLocaleConfigString("de-DE"); aOptions.Commit(); - comphelper::ScopeGuard g([&aOptions, &sLocaleConfigString] { + comphelper::ScopeGuard g1([&aOptions, &sLocaleConfigString] { aOptions.SetLocaleConfigString(sLocaleConfigString); aOptions.Commit(); }); @@ -1287,6 +1287,33 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter2, testUserFieldTypeLanguage) // 123,456.00 transform chain. assertXPath(pXmlDoc, "/root/page/body/txt/Special[@nType='PortionType::Field']", "rText", "1,234.56"); + + discardDumpedLayout(); + // Now change the system locale to English (before this was failing, 1234,56 -> 0.00) + aOptions.SetLocaleConfigString("en-GB"); + aOptions.Commit(); + comphelper::ScopeGuard g2([&aOptions, &sLocaleConfigString] { + aOptions.SetLocaleConfigString(sLocaleConfigString); + aOptions.Commit(); + }); + pViewShell->UpdateFields(); + pXmlDoc = parseLayoutDump(); + // We expect, that the field value is not changed. Otherwise there is a problem: + assertXPath(pXmlDoc, "/root/page/body/txt/Special[@nType='PortionType::Field']", "rText", + "1,234.56"); + discardDumpedLayout(); + // Now change the system locale to German + aOptions.SetLocaleConfigString("de-DE"); + aOptions.Commit(); + comphelper::ScopeGuard g3([&aOptions, &sLocaleConfigString] { + aOptions.SetLocaleConfigString(sLocaleConfigString); + aOptions.Commit(); + }); + pViewShell->UpdateFields(); + pXmlDoc = parseLayoutDump(); + // We expect, that the field value is not changed. Otherwise there is a problem: + assertXPath(pXmlDoc, "/root/page/body/txt/Special[@nType='PortionType::Field']", "rText", + "1,234.56"); } CPPUNIT_TEST_FIXTURE(SwLayoutWriter2, testTdf109137) diff --git a/sw/source/core/fields/usrfld.cxx b/sw/source/core/fields/usrfld.cxx index d2dca51b98d5..9730c5afe722 100644 --- a/sw/source/core/fields/usrfld.cxx +++ b/sw/source/core/fields/usrfld.cxx @@ -199,6 +199,7 @@ std::unique_ptr<SwFieldType> SwUserFieldType::Copy() const { std::unique_ptr<SwUserFieldType> pTmp(new SwUserFieldType( GetDoc(), m_aName )); pTmp->m_aContent = m_aContent; + pTmp->m_aContentLang = m_aContentLang; pTmp->m_nType = m_nType; pTmp->m_bValidValue = m_bValidValue; pTmp->m_nValue = m_nValue; @@ -242,16 +243,23 @@ double SwUserFieldType::GetValue( SwCalc& rCalc ) // See if we need to temporarily switch rCalc's language: in case it // differs from the field type locale. CharClass* pCharClass = rCalc.GetCharClass(); - LanguageTag aCalcLanguage = pCharClass->getLanguageTag(); - LanguageTag aFieldTypeLanguage(GetFieldTypeLanguage()); - bool bSwitchLanguage = aCalcLanguage != aFieldTypeLanguage; + LanguageTag aCharClassLanguage = pCharClass->getLanguageTag(); + LanguageTag aContentLang(m_aContentLang); + + // for the call of calulate we need the language that was used for putting/setting + // the m_aContent string, otherwise the aContent could be interpreted wrongly, + + bool bSwitchLanguage = m_aContentLang != aCharClassLanguage.getBcp47(); + if (bSwitchLanguage) - pCharClass->setLanguageTag(aFieldTypeLanguage); + pCharClass->setLanguageTag(aContentLang); m_nValue = rCalc.Calculate( m_aContent ).GetDouble(); + // we than have to set the propper char class languageTag again + if (bSwitchLanguage) - pCharClass->setLanguageTag(aCalcLanguage); + pCharClass->setLanguageTag(aCharClassLanguage); rCalc.Pop(); @@ -293,6 +301,8 @@ void SwUserFieldType::SetContent( const OUString& rStr, sal_uInt32 nFormat ) if (GetDoc()->IsNumberFormat(rStr, nFormat, fValue)) { SetValue(fValue); + LanguageTag aContentLanguage(GetFieldTypeLanguage()); + m_aContentLang = aContentLanguage.getBcp47(); m_aContent = DoubleToString(fValue, nFormat); } } @@ -332,7 +342,8 @@ void SwUserFieldType::PutValue( const uno::Any& rAny, sal_uInt16 nWhichId ) double fVal = 0; rAny >>= fVal; m_nValue = fVal; - + LanguageTag aContentLanguage(GetFieldTypeLanguage()); + m_aContentLang = aContentLanguage.getBcp47(); m_aContent = DoubleToString(m_nValue, static_cast<sal_uInt16>(GetFieldTypeLanguage())); } break; @@ -361,6 +372,7 @@ void SwUserFieldType::dumpAsXml(xmlTextWriterPtr pWriter) const xmlTextWriterStartElement(pWriter, BAD_CAST("SwUserFieldType")); xmlTextWriterWriteAttribute(pWriter, BAD_CAST("nValue"), BAD_CAST(OString::number(m_nValue).getStr())); xmlTextWriterWriteAttribute(pWriter, BAD_CAST("aContent"), BAD_CAST(m_aContent.toUtf8().getStr())); + xmlTextWriterWriteAttribute(pWriter, BAD_CAST("aContentLang"), BAD_CAST(m_aContentLang.toUtf8().getStr())); SwFieldType::dumpAsXml(pWriter); xmlTextWriterEndElement(pWriter); } |