From 6ce8e5ac1425f4a5dd8e1d46d97d060a5bb4784f Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Thu, 19 Mar 2020 17:54:26 +0100 Subject: sw pad-to-3 numbering: add DOCX filter There is no NS_ooxml::LN_Value_ST_NumberFormat_foo code for this on the import side, rather the number format code is set to NS_ooxml::LN_Value_ST_NumberFormat_custom, then a separate NS_ooxml::LN_CT_NumFmt_format contains the number format string. Declare w14 as an XML namespace on the export side, even if we write no elements. This is needed by , which refers to an XML namespace in the OOXML markup. (Interestingly officeotron doesn't check for this, though.) (cherry picked from commit 52ed1091be05d5a07a021403095c52f0f3986ed6) Conflicts: sw/qa/extras/ooxmlexport/ooxmlexport14.cxx sw/source/filter/ww8/docxattributeoutput.cxx sw/source/filter/ww8/docxexport.cxx Change-Id: If5fbcea4f163bd4d1a1ed820e15ceb61dc9c0519 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/91636 Tested-by: Jenkins CollaboraOffice Reviewed-by: Miklos Vajna --- .../ooxmlexport/data/arabic-zero3-numbering.docx | Bin 0 -> 5934 bytes sw/qa/extras/ooxmlexport/ooxmlexport13.cxx | 13 ++++++++ sw/source/filter/ww8/docxattributeoutput.cxx | 34 ++++++++++++++++++--- sw/source/filter/ww8/docxexport.cxx | 3 ++ writerfilter/source/dmapper/ConversionHelper.cxx | 12 ++++++++ writerfilter/source/dmapper/ConversionHelper.hxx | 1 + writerfilter/source/dmapper/NumberingManager.cxx | 25 +++++++++++++-- writerfilter/source/dmapper/NumberingManager.hxx | 3 ++ 8 files changed, 83 insertions(+), 8 deletions(-) create mode 100644 sw/qa/extras/ooxmlexport/data/arabic-zero3-numbering.docx diff --git a/sw/qa/extras/ooxmlexport/data/arabic-zero3-numbering.docx b/sw/qa/extras/ooxmlexport/data/arabic-zero3-numbering.docx new file mode 100644 index 000000000000..bd95186a6091 Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/arabic-zero3-numbering.docx differ diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx index f40d0cf0a111..a4ad95ff7901 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx @@ -613,6 +613,19 @@ CPPUNIT_TEST_FIXTURE(Test, testChicagoNumberingFootnote) assertXPath(pXmlDoc, "/w:document/w:body/w:sectPr/w:footnotePr/w:numFmt", "val", "chicago"); } +DECLARE_ODFEXPORT_TEST(testArabicZero3Numbering, "arabic-zero3-numbering.docx") +{ + auto xNumberingRules + = getProperty>(getParagraph(1), "NumberingRules"); + comphelper::SequenceAsHashMap aMap(xNumberingRules->getByIndex(0)); + // Without the accompanying fix in place, this test would have failed with: + // - Expected: 65 + // - Actual : 4 + // i.e. numbering type was ARABIC, not ARABIC_ZERO3. + CPPUNIT_ASSERT_EQUAL(static_cast(style::NumberingType::ARABIC_ZERO3), + aMap["NumberingType"].get()); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx index f17af3b3544f..9ae8d551668e 100644 --- a/sw/source/filter/ww8/docxattributeoutput.cxx +++ b/sw/source/filter/ww8/docxattributeoutput.cxx @@ -6439,7 +6439,7 @@ static OString impl_NumberingType( sal_uInt16 nNumberingType ) } // Converting Level Numbering Format Code to string -static OString impl_LevelNFC( sal_uInt16 nNumberingType , const SfxItemSet *pOutSet) +static OString impl_LevelNFC(sal_uInt16 nNumberingType, const SfxItemSet* pOutSet, OString& rFormat) { OString aType; @@ -6492,6 +6492,10 @@ static OString impl_LevelNFC( sal_uInt16 nNumberingType , const SfxItemSet *pOut case style::NumberingType::TEXT_ORDINAL: aType="ordinalText"; break; case style::NumberingType::SYMBOL_CHICAGO: aType="chicago"; break; case style::NumberingType::ARABIC_ZERO: aType = "decimalZero"; break; + case style::NumberingType::ARABIC_ZERO3: + aType = "custom"; + rFormat = "001, 002, 003, ..."; + break; /* Fallback the rest to decimal. case style::NumberingType::NATIVE_NUMBERING: @@ -6849,12 +6853,32 @@ void DocxAttributeOutput::NumberingLevel( sal_uInt8 nLevel, FSEND ); } // format - OString aFormat( impl_LevelNFC( nNumberingType ,pOutSet) ); + OString aCustomFormat; + OString aFormat(impl_LevelNFC(nNumberingType, pOutSet, aCustomFormat)); if ( !aFormat.isEmpty() ) - m_pSerializer->singleElementNS( XML_w, XML_numFmt, - FSNS( XML_w, XML_val ), aFormat.getStr(), - FSEND ); + { + if (aCustomFormat.isEmpty()) + { + m_pSerializer->singleElementNS( XML_w, XML_numFmt, + FSNS( XML_w, XML_val ), aFormat.getStr(), + FSEND ); + } + else + { + m_pSerializer->startElementNS(XML_mc, XML_AlternateContent, FSEND); + m_pSerializer->startElementNS(XML_mc, XML_Choice, XML_Requires, "w14", FSEND); + + m_pSerializer->singleElementNS(XML_w, XML_numFmt, FSNS(XML_w, XML_val), aFormat, + FSNS(XML_w, XML_format), aCustomFormat, FSEND); + + m_pSerializer->endElementNS(XML_mc, XML_Choice); + m_pSerializer->startElementNS(XML_mc, XML_Fallback, FSEND); + m_pSerializer->singleElementNS(XML_w, XML_numFmt, FSNS(XML_w, XML_val), "decimal", FSEND); + m_pSerializer->endElementNS(XML_mc, XML_Fallback); + m_pSerializer->endElementNS(XML_mc, XML_AlternateContent); + } + } // suffix const char *pSuffix = nullptr; diff --git a/sw/source/filter/ww8/docxexport.cxx b/sw/source/filter/ww8/docxexport.cxx index 0956b563a15f..54ff88361c80 100644 --- a/sw/source/filter/ww8/docxexport.cxx +++ b/sw/source/filter/ww8/docxexport.cxx @@ -777,6 +777,9 @@ void DocxExport::WriteNumbering() FSNS( XML_xmlns, XML_o ), OUStringToOString(m_pFilter->getNamespaceURL(OOX_NS(vmlOffice)), RTL_TEXTENCODING_UTF8).getStr(), FSNS( XML_xmlns, XML_r ), OUStringToOString(m_pFilter->getNamespaceURL(OOX_NS(officeRel)), RTL_TEXTENCODING_UTF8).getStr(), FSNS( XML_xmlns, XML_v ), OUStringToOString(m_pFilter->getNamespaceURL(OOX_NS(vml)), RTL_TEXTENCODING_UTF8).getStr(), + FSNS( XML_xmlns, XML_mc ), m_pFilter->getNamespaceURL(OOX_NS(mce)).toUtf8(), + FSNS( XML_xmlns, XML_w14 ), m_pFilter->getNamespaceURL(OOX_NS(w14)).toUtf8(), + FSNS( XML_mc, XML_Ignorable ), "w14", FSEND ); BulletDefinitions(); diff --git a/writerfilter/source/dmapper/ConversionHelper.cxx b/writerfilter/source/dmapper/ConversionHelper.cxx index c0eaf005d4dd..694bf956cc6e 100644 --- a/writerfilter/source/dmapper/ConversionHelper.cxx +++ b/writerfilter/source/dmapper/ConversionHelper.cxx @@ -614,6 +614,18 @@ sal_Int16 ConvertNumberingType(sal_Int32 nFmt) return nRet; } +sal_Int16 ConvertCustomNumberFormat(const OUString& rFormat) +{ + sal_Int16 nRet = -1; + + if (rFormat == "001, 002, 003, ...") + { + nRet = style::NumberingType::ARABIC_ZERO3; + } + + return nRet; +} + util::DateTime ConvertDateStringToDateTime( const OUString& rDateTime ) { util::DateTime aDateTime; diff --git a/writerfilter/source/dmapper/ConversionHelper.hxx b/writerfilter/source/dmapper/ConversionHelper.hxx index 25ca7f8b8ce9..fd7a85870d2b 100644 --- a/writerfilter/source/dmapper/ConversionHelper.hxx +++ b/writerfilter/source/dmapper/ConversionHelper.hxx @@ -51,6 +51,7 @@ namespace ConversionHelper{ sal_Int16 convertTableJustification( sal_Int32 nIntValue ); css::text::RubyAdjust convertRubyAlign( sal_Int32 nIntValue ); sal_Int16 ConvertNumberingType(sal_Int32 nFmt); + sal_Int16 ConvertCustomNumberFormat(const OUString& rFormat); css::util::DateTime ConvertDateStringToDateTime(const OUString& rDateTime); } // namespace ConversionHelper diff --git a/writerfilter/source/dmapper/NumberingManager.cxx b/writerfilter/source/dmapper/NumberingManager.cxx index efbbf4efaea2..905f22a47f22 100644 --- a/writerfilter/source/dmapper/NumberingManager.cxx +++ b/writerfilter/source/dmapper/NumberingManager.cxx @@ -125,6 +125,8 @@ void ListLevel::SetValue( Id nId, sal_Int32 nValue ) m_bHasValues = true; } +void ListLevel::SetCustomNumberFormat(const OUString& rValue) { m_aCustomNumberFormat = rValue; } + bool ListLevel::HasValues() const { return m_bHasValues; @@ -234,7 +236,15 @@ uno::Sequence ListLevel::GetLevelProperties(bool bDefaults if( m_nIStartAt >= 0) aNumberingProperties.push_back(lcl_makePropVal(PROP_START_WITH, m_nIStartAt) ); - sal_Int16 nNumberFormat = ConversionHelper::ConvertNumberingType(m_nNFC); + sal_Int16 nNumberFormat = -1; + if (m_nNFC == NS_ooxml::LN_Value_ST_NumberFormat_custom) + { + nNumberFormat = ConversionHelper::ConvertCustomNumberFormat(m_aCustomNumberFormat); + } + else + { + nNumberFormat = ConversionHelper::ConvertNumberingType(m_nNFC); + } if( m_nNFC >= 0) { if (m_xGraphicBitmap.is()) @@ -724,8 +734,17 @@ void ListsManager::lcl_attribute( Id nName, Value& rVal ) case NS_ooxml::LN_CT_Lvl_isLgl: case NS_ooxml::LN_CT_Lvl_legacy: if ( pCurrentLvl.get( ) ) - pCurrentLvl->SetValue( nName, sal_Int32( nIntValue ) ); - break; + { + if (nName == NS_ooxml::LN_CT_NumFmt_format) + { + pCurrentLvl->SetCustomNumberFormat(rVal.getString()); + } + else + { + pCurrentLvl->SetValue(nName, sal_Int32(nIntValue)); + } + } + break; case NS_ooxml::LN_CT_Num_numId: m_pCurrentDefinition->SetId( rVal.getString().toInt32( ) ); break; diff --git a/writerfilter/source/dmapper/NumberingManager.hxx b/writerfilter/source/dmapper/NumberingManager.hxx index f8e67f0fd638..664e34860259 100644 --- a/writerfilter/source/dmapper/NumberingManager.hxx +++ b/writerfilter/source/dmapper/NumberingManager.hxx @@ -44,6 +44,8 @@ class ListLevel : public PropertyMap { sal_Int32 m_nIStartAt; //LN_CT_Lvl_start sal_Int32 m_nNFC; //LN_CT_Lvl_numFmt + /// LN_CT_NumFmt_format, in case m_nNFC is custom. + OUString m_aCustomNumberFormat; sal_Int16 m_nXChFollow; //LN_IXCHFOLLOW OUString m_sBulletChar; css::awt::Size m_aGraphicSize; @@ -67,6 +69,7 @@ public: // Setters for the import void SetValue( Id nId, sal_Int32 nValue ); + void SetCustomNumberFormat(const OUString& rValue); void SetBulletChar( const OUString& sValue ) { m_sBulletChar = sValue; }; void SetGraphicSize( const css::awt::Size& aValue ) { m_aGraphicSize = aValue; }; -- cgit v1.2.3