summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sw/inc/calc.hxx1
-rw-r--r--sw/inc/usrfld.hxx14
-rw-r--r--sw/qa/extras/layout/data/user-field-type-language.fodt21
-rw-r--r--sw/qa/extras/layout/layout.cxx24
-rw-r--r--sw/source/core/bastyp/calc.cxx5
-rw-r--r--sw/source/core/fields/usrfld.cxx31
6 files changed, 92 insertions, 4 deletions
diff --git a/sw/inc/calc.hxx b/sw/inc/calc.hxx
index c6f3380cceee..125c5e2f6ab9 100644
--- a/sw/inc/calc.hxx
+++ b/sw/inc/calc.hxx
@@ -197,6 +197,7 @@ public:
bool Push(const SwUserFieldType* pUserFieldType);
void Pop();
+ CharClass* GetCharClass();
void SetCalcError( SwCalcError eErr ) { m_eError = eErr; }
bool IsCalcError() const { return SwCalcError::NONE != m_eError; }
diff --git a/sw/inc/usrfld.hxx b/sw/inc/usrfld.hxx
index 9d241df8a118..a439a3a7412f 100644
--- a/sw/inc/usrfld.hxx
+++ b/sw/inc/usrfld.hxx
@@ -26,12 +26,20 @@ class SfxPoolItem;
class SwCalc;
class SwDoc;
+/**
+ * The shared part of a user field.
+ *
+ * Tracks the value, but conversion between the float and string representation
+ * always happens with the system locale.
+ */
class SW_DLLPUBLIC SwUserFieldType : public SwValueFieldType
{
bool bValidValue : 1;
bool bDeleted : 1;
+ /// Float value type.
double nValue;
OUString aName;
+ /// String value type.
OUString aContent;
sal_uInt16 nType;
@@ -83,6 +91,12 @@ inline void SwUserFieldType::SetType(sal_uInt16 nSub)
EnableFormat(!(nSub & nsSwGetSetExpType::GSE_STRING));
}
+/**
+ * The non-shared part of a user field.
+ *
+ * Tracks the number format and the language, conversion between the float and
+ * string representation is independent from the system locale.
+ */
class SW_DLLPUBLIC SwUserField : public SwValueField
{
sal_uInt16 nSubType;
diff --git a/sw/qa/extras/layout/data/user-field-type-language.fodt b/sw/qa/extras/layout/data/user-field-type-language.fodt
new file mode 100644
index 000000000000..f741add7ddd7
--- /dev/null
+++ b/sw/qa/extras/layout/data/user-field-type-language.fodt
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<office:document xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" office:version="1.2" office:mimetype="application/vnd.oasis.opendocument.text">
+ <office:styles>
+ <style:default-style style:family="paragraph">
+ <style:text-properties fo:language="en" fo:country="GB"/>
+ </style:default-style>
+ </office:styles>
+ <office:automatic-styles>
+ <number:number-style style:name="N10004" number:language="en" number:country="GB">
+ <number:number number:decimal-places="2" number:min-integer-digits="1" number:grouping="true"/>
+ </number:number-style>
+ </office:automatic-styles>
+ <office:body>
+ <office:text text:use-soft-page-breaks="true">
+ <text:user-field-decls>
+ <text:user-field-decl office:value-type="float" office:value="1234.56" text:name="user-field-decl-name-example"/>
+ </text:user-field-decls>
+ <text:p>Before <text:user-field-get style:data-style-name="N10004" text:name="user-field-decl-name-example">1,234.56</text:user-field-get> after.</text:p>
+ </office:text>
+ </office:body>
+</office:document>
diff --git a/sw/qa/extras/layout/layout.cxx b/sw/qa/extras/layout/layout.cxx
index 9a73e2025147..7167647ac93b 100644
--- a/sw/qa/extras/layout/layout.cxx
+++ b/sw/qa/extras/layout/layout.cxx
@@ -9,6 +9,8 @@
#include <swmodeltestbase.hxx>
#include <test/mtfxmldump.hxx>
+#include <comphelper/scopeguard.hxx>
+#include <unotools/syslocaleoptions.hxx>
static char const DATA_DIRECTORY[] = "/sw/qa/extras/layout/data/";
@@ -19,11 +21,13 @@ public:
void testTdf116830();
void testTdf116925();
void testTdf117028();
+ void testUserFieldTypeLanguage();
CPPUNIT_TEST_SUITE(SwLayoutWriter);
CPPUNIT_TEST(testTdf116830);
CPPUNIT_TEST(testTdf116925);
CPPUNIT_TEST(testTdf117028);
+ CPPUNIT_TEST(testUserFieldTypeLanguage);
CPPUNIT_TEST_SUITE_END();
private:
@@ -108,6 +112,26 @@ void SwLayoutWriter::testTdf117028()
assertXPathContent(pXmlDoc, "//textarray/text", "Hello");
}
+void SwLayoutWriter::testUserFieldTypeLanguage()
+{
+ // Set the system locale to German, the document will be English.
+ SvtSysLocaleOptions aOptions;
+ aOptions.SetLocaleConfigString("de-DE");
+ aOptions.Commit();
+ comphelper::ScopeGuard g([&aOptions] {
+ aOptions.SetLocaleConfigString(OUString());
+ aOptions.Commit();
+ });
+
+ SwDoc* pDoc = createDoc("user-field-type-language.fodt");
+ SwViewShell* pViewShell = pDoc->getIDocumentLayoutAccess().GetCurrentViewShell();
+ pViewShell->UpdateFields();
+ xmlDocPtr pXmlDoc = parseLayoutDump();
+ // This was "123,456.00", via a buggy 1234.56 -> 1234,56 -> 123456 ->
+ // 123,456.00 transform chain.
+ assertXPath(pXmlDoc, "/root/page/body/txt/Special[@nType='POR_FLD']", "rText", "1,234.56");
+}
+
CPPUNIT_TEST_SUITE_REGISTRATION(SwLayoutWriter);
CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/core/bastyp/calc.cxx b/sw/source/core/bastyp/calc.cxx
index 0edb21517878..1532a3a898b7 100644
--- a/sw/source/core/bastyp/calc.cxx
+++ b/sw/source/core/bastyp/calc.cxx
@@ -637,6 +637,11 @@ void SwCalc::Pop()
m_aRekurStack.pop_back();
}
+CharClass* SwCalc::GetCharClass()
+{
+ return m_pCharClass;
+}
+
SwCalcOper SwCalc::GetToken()
{
if( m_nCommandPos >= m_sCommand.getLength() )
diff --git a/sw/source/core/fields/usrfld.cxx b/sw/source/core/fields/usrfld.cxx
index 080dcfc77bd1..0b25a940802a 100644
--- a/sw/source/core/fields/usrfld.cxx
+++ b/sw/source/core/fields/usrfld.cxx
@@ -39,6 +39,18 @@
using namespace ::com::sun::star;
+namespace
+{
+/**
+ * Returns the language used for float <-> string conversions in
+ * SwUserFieldType.
+ */
+LanguageType GetFieldTypeLanguage()
+{
+ return LANGUAGE_SYSTEM;
+}
+}
+
// Userfields
SwUserField::SwUserField(SwUserFieldType* pTyp, sal_uInt16 nSub, sal_uInt32 nFormat)
@@ -222,7 +234,21 @@ double SwUserFieldType::GetValue( SwCalc& rCalc )
rCalc.SetCalcError( SwCalcError::Syntax );
return 0;
}
+
+ // 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;
+ if (bSwitchLanguage)
+ pCharClass->setLanguageTag(aFieldTypeLanguage);
+
nValue = rCalc.Calculate( aContent ).GetDouble();
+
+ if (bSwitchLanguage)
+ pCharClass->setLanguageTag(aCalcLanguage);
+
rCalc.Pop();
if( !rCalc.IsCalcError() )
@@ -306,10 +332,7 @@ bool SwUserFieldType::PutValue( const uno::Any& rAny, sal_uInt16 nWhichId )
rAny >>= fVal;
nValue = fVal;
- // The following line is in fact wrong, since the language is unknown (is part of the
- // field) and, thus, aContent should also belong to the field. Each field can have a
- // different language, but the same content with just different formatting.
- aContent = DoubleToString(nValue, static_cast<sal_uInt16>(LANGUAGE_SYSTEM));
+ aContent = DoubleToString(nValue, static_cast<sal_uInt16>(GetFieldTypeLanguage()));
}
break;
case FIELD_PROP_PAR2: