summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkirchhoffb <bjoern.kirchhoff@escriba.de>2020-06-20 17:34:46 +0200
committerMiklos Vajna <vmiklos@collabora.com>2020-11-10 09:16:22 +0100
commitabfee0d2517195dfe49be8d538a48b31f4fb0eef (patch)
tree3d5e403c36c061a00d815df45caa27aed507f4ea
parent0afba07a597bf1d361624e10968855a802b859a0 (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.hxx2
-rw-r--r--sw/qa/extras/layout/layout2.cxx29
-rw-r--r--sw/source/core/fields/usrfld.cxx24
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);
}