From 7c339186b4b41ce22229a591cb8fb14ec3120567 Mon Sep 17 00:00:00 2001 From: Szabolcs Toth Date: Fri, 24 Jan 2020 10:40:01 +0100 Subject: tdf#95495 DOCX import: fix inherited list level of custom styles MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit in DOCX export of MSO 2003, 2007 and 2010, where ilvl and outlinelvl settings are missing, based on the settings of the parent styles. Change-Id: I01d239db505d46a89d7f3b9118ef0b55697bc7fc CO-Author: Balázs Nádasdy (NISZ) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/87328 Tested-by: László Németh Reviewed-by: László Németh Signed-off-by: Xisco Fauli Reviewed-on: https://gerrit.libreoffice.org/c/core/+/89216 Tested-by: Jenkins --- sw/qa/extras/ooxmlexport/data/tdf95495.docx | Bin 0 -> 102240 bytes sw/qa/extras/ooxmlexport/ooxmlexport3.cxx | 10 ++++++ writerfilter/source/dmapper/StyleSheetTable.cxx | 44 ++++++++++++++++++------ 3 files changed, 44 insertions(+), 10 deletions(-) create mode 100644 sw/qa/extras/ooxmlexport/data/tdf95495.docx diff --git a/sw/qa/extras/ooxmlexport/data/tdf95495.docx b/sw/qa/extras/ooxmlexport/data/tdf95495.docx new file mode 100644 index 000000000000..21f534b11223 Binary files /dev/null and b/sw/qa/extras/ooxmlexport/data/tdf95495.docx differ diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport3.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport3.cxx index a87a0b2919f3..c85b8a7f932f 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport3.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport3.cxx @@ -1061,6 +1061,16 @@ DECLARE_OOXMLEXPORT_TEST(testBottomBorders, "tdf129452_BottomBorders.docx") assertXPath(pXmlDocument, "/w:document/w:body/w:tbl/w:tr[4]/w:tc[2]/w:tcPr/w:tcBorders/w:bottom [@w:val = 'nil']", 0); } +DECLARE_OOXMLEXPORT_TEST(testNumberingLevels, "tdf95495.docx") +{ + xmlDocPtr pXmlDocument = parseExport("word/document.xml"); + if (!pXmlDocument) + return; + + // tdf#95495: set list level of the custom style based on the setting of the parent style + assertXPath(pXmlDocument, "/w:document/w:body/w:p[2]/w:pPr/w:numPr/w:ilvl [@w:val = '1']", 1); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/StyleSheetTable.cxx b/writerfilter/source/dmapper/StyleSheetTable.cxx index 08881a93a9fe..e4f970dbcd0e 100644 --- a/writerfilter/source/dmapper/StyleSheetTable.cxx +++ b/writerfilter/source/dmapper/StyleSheetTable.cxx @@ -892,6 +892,12 @@ uno::Sequence< OUString > PropValVector::getNames() return comphelper::containerToSequence(aRet); } +static bool lcl_IsOutLineStyle(const OUString& sPrefix, const OUString& sStyleName) +{ + OUString sSuffix; + return sStyleName.getLength() == (sPrefix.getLength() + 2) && sStyleName.startsWith(sPrefix + " ", &sSuffix) && sSuffix.toInt32() > 0; +} + void StyleSheetTable::ApplyStyleSheets( const FontTablePtr& rFontTable ) { try @@ -1049,13 +1055,39 @@ void StyleSheetTable::ApplyStyleSheets( const FontTablePtr& rFontTable ) } // Set the outline levels - const StyleSheetPropertyMap* pStyleSheetProperties = dynamic_cast(pEntry ? pEntry->pProperties.get() : nullptr); + StyleSheetPropertyMap* pStyleSheetProperties = dynamic_cast(pEntry ? pEntry->pProperties.get() : nullptr); + if ( pStyleSheetProperties ) { beans::PropertyValue aLvlVal( getPropertyName( PROP_OUTLINE_LEVEL ), 0, uno::makeAny( sal_Int16( pStyleSheetProperties->GetOutlineLevel( ) + 1 ) ), beans::PropertyState_DIRECT_VALUE ); aPropValues.push_back(aLvlVal); + + // tdf#95495 missing list level settings in custom styles in old DOCX: apply settings of the parent style + if (pStyleSheetProperties->GetListLevel() == -1 && pStyleSheetProperties->GetOutlineLevel() == -1) + { + const beans::PropertyValues aPropGrabBag = pEntry->GetInteropGrabBagSeq(); + for (const auto& rVal : aPropGrabBag) + { + if (rVal.Name == "customStyle" && rVal.Value == true) + { + OUString sBaseId = pEntry->sBaseStyleIdentifier; + for (const auto& aSheetProps : m_pImpl->m_aStyleSheetEntries) + { + if (aSheetProps->sStyleIdentifierD == sBaseId) + { + StyleSheetPropertyMap* aStyleSheetProps + = dynamic_cast(aSheetProps->pProperties.get()); + pStyleSheetProperties->SetListLevel(aStyleSheetProps->GetListLevel()); + pStyleSheetProperties->SetOutlineLevel(aStyleSheetProps->GetOutlineLevel()); + pStyleSheetProperties->SetNumId(aStyleSheetProps->GetNumId()); + break; + } + } + } + } + } } uno::Reference< beans::XPropertyState >xState( xStyle, uno::UNO_QUERY_THROW ); @@ -1069,15 +1101,7 @@ void StyleSheetTable::ApplyStyleSheets( const FontTablePtr& rFontTable ) } else if ( sConvertedStyleName == "Text body" ) xState->setPropertyToDefault(getPropertyName( PROP_PARA_BOTTOM_MARGIN )); - else if( sConvertedStyleName == "Heading 1" || - sConvertedStyleName == "Heading 2" || - sConvertedStyleName == "Heading 3" || - sConvertedStyleName == "Heading 4" || - sConvertedStyleName == "Heading 5" || - sConvertedStyleName == "Heading 6" || - sConvertedStyleName == "Heading 7" || - sConvertedStyleName == "Heading 8" || - sConvertedStyleName == "Heading 9" ) + else if( lcl_IsOutLineStyle("Heading", sConvertedStyleName) ) { xState->setPropertyToDefault(getPropertyName( PROP_CHAR_WEIGHT )); xState->setPropertyToDefault(getPropertyName( PROP_CHAR_WEIGHT_ASIAN )); -- cgit