summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaxim Monastirsky <momonasmon@gmail.com>2020-06-10 22:01:24 +0300
committerMaxim Monastirsky <momonasmon@gmail.com>2020-06-11 23:07:46 +0200
commitcd0dc1bc592d7952c36659da33d99ab964fe2e93 (patch)
treedbeaac6db63f6c723ffca5b1300edec1eea7239e
parentcd47dba9aa4b91bb0edf0744561d29e2eef61cc9 (diff)
tdf#133459 Fix import of fields with user defined number formats
commit 59ace23c367f83491a37e844d16f7d716eff6346 ("tdf#101710 Fix invalid style:data-style-name attribute") had a side effect of exporting user defined number formats under <office:styles> instead of under <office:automatic-styles> (which is valid, and what Calc does since forever). As it turned out, this didn't work well for fields: - For fields inside headers or footers, their number format wasn't imported at all. The reason here is that fields use the XMLTextImportHelper::GetDataStyleKey method to resolve data styles, and that method checks only automatic styles. Actually it resolves also styles from <office:styles>, because SvXMLImport::SetAutoStyles has a special code that merges styles from <office:styles> into automatic styles during content.xml reading. The problem is that headers and footers have their contents stored inside styles.xml, and no merging happens at this stage (unless it's a flat odf file). One way to solve this could be to explicitly check for styles from <office:styles> in XMLTextImportHelper::GetDataStyleKey (e.g. see previous gerrit patchsets, or XMLTableStyleContext::GetNumberFormat) I chose to simply modify the condition in SvXMLImport::SetAutoStyles, so that merging happens anyway. - Fields whose format resolution depends on the merging of SvXMLImport::SetAutoStyles, did import the number format itself, but not its language setting. This can be in one of three ways: (a) Fields in the document and the header, when both use the same format. In this case the format is stored once in styles.xml, so at least the consumer from content.xml depends on merging. (b) Field in the document with a user defined format - a regression of the above commit. Now stored in styles.xml under <office:styles> instead of in content.xml under <office:automatic-styles>. (c) Field in a header with a user defined format - depends on merging as a result of the above fix. The reason here is that the merging isn't done with the original SvXMLNumFormatContext objects, but with a newly created fake ones, which only have the format id correct (with the assumption that those formats already imported, and calling code could just find them by the id). The problem is that the fields code uses XMLTextImportHelper::GetDataStyleKey to get the language setting from style objects, and set the IsFixedLanguage property according to it, while we know that those fake objects don't have the language correctly set. Try to fix that problem by setting the correct language on those fake objects. Change-Id: Ibb362df019921e040708d3bda83bf155535ec7af Reviewed-on: https://gerrit.libreoffice.org/c/core/+/95612 Tested-by: Jenkins Reviewed-by: Maxim Monastirsky <momonasmon@gmail.com>
-rw-r--r--include/xmloff/xmlnumfi.hxx2
-rw-r--r--sw/qa/extras/odfimport/data/tdf133459.odtbin0 -> 8061 bytes
-rw-r--r--sw/qa/extras/odfimport/odfimport.cxx30
-rw-r--r--xmloff/source/core/xmlimp.cxx5
-rw-r--r--xmloff/source/style/xmlnumfi.cxx16
5 files changed, 49 insertions, 4 deletions
diff --git a/include/xmloff/xmlnumfi.hxx b/include/xmloff/xmlnumfi.hxx
index 21eac93a3cd9..b337fad36832 100644
--- a/include/xmloff/xmlnumfi.hxx
+++ b/include/xmloff/xmlnumfi.hxx
@@ -91,6 +91,7 @@ public:
SvXMLNumImpData* getData() { return pData.get(); }
const SvXMLTokenMap& GetStylesElemTokenMap();
+ LanguageType GetLanguageForKey(sal_Int32 nKey);
// sal_uInt32 GetKeyForName( const OUString& rName );
};
@@ -164,6 +165,7 @@ public:
const OUString& rLName,
const css::uno::Reference< css::xml::sax::XAttributeList>& xAttrList,
const sal_Int32 nKey,
+ LanguageType nLang,
SvXMLStylesContext& rStyles );
virtual ~SvXMLNumFormatContext() override;
diff --git a/sw/qa/extras/odfimport/data/tdf133459.odt b/sw/qa/extras/odfimport/data/tdf133459.odt
new file mode 100644
index 000000000000..9468d7918a6c
--- /dev/null
+++ b/sw/qa/extras/odfimport/data/tdf133459.odt
Binary files differ
diff --git a/sw/qa/extras/odfimport/odfimport.cxx b/sw/qa/extras/odfimport/odfimport.cxx
index 30737c3454dd..70d5a158b22c 100644
--- a/sw/qa/extras/odfimport/odfimport.cxx
+++ b/sw/qa/extras/odfimport/odfimport.cxx
@@ -30,6 +30,9 @@
#include <com/sun/star/text/PageNumberType.hpp>
#include <com/sun/star/text/VertOrientation.hpp>
#include <com/sun/star/view/XControlAccess.hpp>
+#include <com/sun/star/util/XNumberFormatTypes.hpp>
+#include <com/sun/star/util/XNumberFormatsSupplier.hpp>
+#include <com/sun/star/lang/Locale.hpp>
#include <IDocumentSettingAccess.hxx>
#include <wrtsh.hxx>
@@ -1048,5 +1051,32 @@ DECLARE_ODFIMPORT_TEST(testTdf123968, "tdf123968.odt")
rStart.GetText());
}
+DECLARE_ODFIMPORT_TEST(testTdf133459, "tdf133459.odt")
+{
+ // Test that the number format was correctly imported, and used by both fields.
+ uno::Reference<text::XTextFieldsSupplier> xTextFieldsSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<container::XEnumeration> xFields(xTextFieldsSupplier->getTextFields()->createEnumeration());
+
+ // First Field
+ uno::Reference<text::XTextField> xField(xFields->nextElement(), uno::UNO_QUERY);
+ const OUString sPresentation(xField->getPresentation(false));
+ const sal_Int32 nFormat(getProperty<sal_Int32>(xField, "NumberFormat"));
+ CPPUNIT_ASSERT_EQUAL(sal_True, getProperty<sal_Bool>(xField, "IsFixedLanguage"));
+
+ // Second field
+ xField.set(xFields->nextElement(), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(sPresentation, xField->getPresentation(false));
+ CPPUNIT_ASSERT_EQUAL(nFormat, getProperty<sal_Int32>(xField, "NumberFormat"));
+ CPPUNIT_ASSERT_EQUAL(sal_True, getProperty<sal_Bool>(xField, "IsFixedLanguage"));
+
+ // Test the number format itself
+ uno::Reference<util::XNumberFormatsSupplier> xNumberFormatsSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<beans::XPropertySet> xFormat(xNumberFormatsSupplier->getNumberFormats()->getByKey(nFormat));
+ lang::Locale aLocale(getProperty<lang::Locale>(xFormat, "Locale"));
+ CPPUNIT_ASSERT_EQUAL(OUString("ru"), aLocale.Language);
+ CPPUNIT_ASSERT_EQUAL(OUString("RU"), aLocale.Country);
+ CPPUNIT_ASSERT_EQUAL(OUString("QQ YYYY"), getProperty<OUString>(xFormat, "FormatString"));
+}
+
CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/core/xmlimp.cxx b/xmloff/source/core/xmlimp.cxx
index 36550f1f8192..1e77eca85928 100644
--- a/xmloff/source/core/xmlimp.cxx
+++ b/xmloff/source/core/xmlimp.cxx
@@ -1625,7 +1625,7 @@ void SvXMLImport::SetStyles( SvXMLStylesContext *pStyles )
void SvXMLImport::SetAutoStyles( SvXMLStylesContext *pAutoStyles )
{
- if (pAutoStyles && mxNumberStyles.is() && (mnImportFlags & SvXMLImportFlags::CONTENT) )
+ if (pAutoStyles && mxNumberStyles.is())
{
uno::Reference<xml::sax::XAttributeList> xAttrList;
const uno::Sequence<OUString> aStyleNames = mxNumberStyles->getElementNames();
@@ -1636,7 +1636,8 @@ void SvXMLImport::SetAutoStyles( SvXMLStylesContext *pAutoStyles )
if (aAny >>= nKey)
{
SvXMLStyleContext* pContext = new SvXMLNumFormatContext(
- *this, XML_NAMESPACE_NUMBER, name, xAttrList, nKey, *pAutoStyles);
+ *this, XML_NAMESPACE_NUMBER, name, xAttrList, nKey,
+ GetDataStylesImport()->GetLanguageForKey(nKey), *pAutoStyles);
pAutoStyles->AddStyle(*pContext);
}
}
diff --git a/xmloff/source/style/xmlnumfi.cxx b/xmloff/source/style/xmlnumfi.cxx
index 79a68e424be8..61b6bc1cfb08 100644
--- a/xmloff/source/style/xmlnumfi.cxx
+++ b/xmloff/source/style/xmlnumfi.cxx
@@ -1470,7 +1470,7 @@ SvXMLNumFormatContext::SvXMLNumFormatContext( SvXMLImport& rImport,
SvXMLNumFormatContext::SvXMLNumFormatContext( SvXMLImport& rImport,
sal_uInt16 nPrfx, const OUString& rLName,
const uno::Reference<xml::sax::XAttributeList>& xAttrList,
- const sal_Int32 nTempKey,
+ const sal_Int32 nTempKey, LanguageType nLang,
SvXMLStylesContext& rStyles ) :
SvXMLStyleContext( rImport, nPrfx, rLName, xAttrList, XmlStyleFamily::DATA_STYLE ),
pData( nullptr ),
@@ -1478,7 +1478,7 @@ SvXMLNumFormatContext::SvXMLNumFormatContext( SvXMLImport& rImport,
aMyConditions(),
nType( 0 ),
nKey(nTempKey),
- nFormatLang( LANGUAGE_SYSTEM ),
+ nFormatLang( nLang ),
bAutoOrder( false ),
bFromSystem( false ),
bTruncate( true ),
@@ -2302,4 +2302,16 @@ const SvXMLTokenMap& SvXMLNumFmtHelper::GetStylesElemTokenMap()
return pData->GetStylesElemTokenMap();
}
+LanguageType SvXMLNumFmtHelper::GetLanguageForKey(sal_Int32 nKey)
+{
+ if (pData->GetNumberFormatter())
+ {
+ const SvNumberformat* pEntry = pData->GetNumberFormatter()->GetEntry(nKey);
+ if (pEntry)
+ return pEntry->GetLanguage();
+ }
+
+ return LANGUAGE_SYSTEM;
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */