include/oox/export/drawingml.hxx | 5 ++- oox/source/export/drawingml.cxx | 53 ++++++++++++++++++++++++--------- oox/source/export/shapes.cxx | 13 ++++++++ sd/qa/unit/data/odp/testZeroIndent.odp |binary sd/qa/unit/export-tests-ooxml3.cxx | 38 +++++++++++++++++++++++ 5 files changed, 95 insertions(+), 14 deletions(-)
New commits: commit 445d4ce232b8e8efaeb2605533fede1b71f52f30 Author: Attila Bakos (NISZ) <bakos.attilakar...@nisz.hu> AuthorDate: Thu May 26 17:04:54 2022 +0200 Commit: László Németh <nem...@numbertext.org> CommitDate: Tue May 31 13:00:38 2022 +0200 tdf#147991 PPTX export: fix bullet indent regression Instead of exporting the inherited master slide indent values of the placeholders, export 0 indent value for removed/disabled bullets to fix interoperability. Regression from commit f57cfddb51b7d7409b7b425dc200aa73406a13bd "tdf#145162 PPTX export: fix extra bullet regression". Change-Id: Icbf823adc07f19fd10d1a60da9cff17616a2aef6 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/135025 Tested-by: László Németh <nem...@numbertext.org> Reviewed-by: László Németh <nem...@numbertext.org> diff --git a/include/oox/export/drawingml.hxx b/include/oox/export/drawingml.hxx index 294319cf43af..455676e9c262 100644 --- a/include/oox/export/drawingml.hxx +++ b/include/oox/export/drawingml.hxx @@ -163,6 +163,9 @@ protected: css::uno::Reference<css::drawing::XShape> m_xParent; bool mbIsBackgroundDark; + /// True when exporting presentation placeholder shape. + bool mbPlaceholder; + bool GetProperty( const css::uno::Reference< css::beans::XPropertySet >& rXPropSet, const OUString& aName ); bool GetPropertyAndState( const css::uno::Reference< css::beans::XPropertySet >& rXPropSet, const css::uno::Reference< css::beans::XPropertyState >& rXPropState, @@ -210,7 +213,7 @@ protected: public: DrawingML( ::sax_fastparser::FSHelperPtr pFS, ::oox::core::XmlFilterBase* pFB, DocumentType eDocumentType = DOCUMENT_PPTX, DMLTextExport* pTextExport = nullptr ) - : meDocumentType( eDocumentType ), mpTextExport(pTextExport), mpFS( pFS ), mpFB( pFB ), mbIsBackgroundDark( false ) {} + : meDocumentType( eDocumentType ), mpTextExport(pTextExport), mpFS( pFS ), mpFB( pFB ), mbIsBackgroundDark( false ), mbPlaceholder(false) {} void SetFS( ::sax_fastparser::FSHelperPtr pFS ) { mpFS = pFS; } const ::sax_fastparser::FSHelperPtr& GetFS() const { return mpFS; } ::oox::core::XmlFilterBase* GetFB() { return mpFB; } diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx index 18e6e2723e89..eea8394aef36 100644 --- a/oox/source/export/drawingml.cxx +++ b/oox/source/export/drawingml.cxx @@ -122,6 +122,7 @@ #include <editeng/unoprnms.hxx> #include <editeng/flditem.hxx> #include <editeng/escapementitem.hxx> +#include <editeng/unonrule.hxx> #include <svx/svdoashp.hxx> #include <svx/svdomedia.hxx> #include <svx/unoshape.hxx> @@ -2705,13 +2706,7 @@ static OUString GetAutoNumType(SvxNumType nNumberingType, bool bSDot, bool bPBeh void DrawingML::WriteParagraphNumbering(const Reference< XPropertySet >& rXPropSet, float fFirstCharHeight, sal_Int16 nLevel ) { if (nLevel < 0 || !GetProperty(rXPropSet, "NumberingRules")) - { - if (GetDocumentType() == DOCUMENT_PPTX) - { - mpFS->singleElementNS(XML_a, XML_buNone); - } return; - } Reference< XIndexAccess > rXIndexAccess; @@ -3015,6 +3010,32 @@ bool DrawingML::WriteParagraphProperties( const Reference< XTextContent >& rPara if (GetProperty(rXPropSet, "NumberingLevel")) mAny >>= nLevel; + bool bWriteNumbering = true; + bool bForceZeroIndent = false; + if (mbPlaceholder) + { + Reference< text::XTextRange > xParaText(rParagraph, UNO_QUERY); + if (xParaText) + { + bool bNumberingOnThisLevel = false; + if (nLevel > -1) + { + Reference< XIndexAccess > xNumberingRules(rXPropSet->getPropertyValue("NumberingRules"), UNO_QUERY); + const PropertyValues& rNumRuleOfLevel = xNumberingRules->getByIndex(nLevel).get<PropertyValues>(); + for (const PropertyValue& rRule : rNumRuleOfLevel) + if (rRule.Name == "NumberingType" && rRule.Value.hasValue()) + bNumberingOnThisLevel = rRule.Value.get<sal_uInt16>() != style::NumberingType::NUMBER_NONE; + } + + const bool bIsNumberingVisible = rXPropSet->getPropertyValue("NumberingIsNumber").get<bool>(); + const bool bIsLineEmpty = !xParaText->getString().getLength(); + + bWriteNumbering = !bIsLineEmpty && bIsNumberingVisible && (nLevel != -1); + bForceZeroIndent = (!bIsNumberingVisible || bIsLineEmpty || !bNumberingOnThisLevel); + } + + } + sal_Int16 nTmp = sal_Int16(style::ParagraphAdjust_LEFT); if (GetProperty(rXPropSet, "ParaAdjust")) mAny >>= nTmp; @@ -3058,23 +3079,26 @@ bool DrawingML::WriteParagraphProperties( const Reference< XTextContent >& rPara sal_Int32 nLeftMargin = getBulletMarginIndentation ( rXPropSet, nLevel,u"LeftMargin"); sal_Int32 nLineIndentation = getBulletMarginIndentation ( rXPropSet, nLevel,u"FirstLineOffset"); - if( !(nLevel != -1 - || nAlignment != style::ParagraphAdjust_LEFT - || bHasLinespacing) ) - return false; + if (bWriteNumbering && !bForceZeroIndent) + { + if (!(nLevel != -1 + || nAlignment != style::ParagraphAdjust_LEFT + || bHasLinespacing)) + return false; + } if (nParaLeftMargin) // For Paragraph mpFS->startElementNS( XML_a, nElement, XML_lvl, sax_fastparser::UseIf(OString::number(nLevel), nLevel > 0), XML_marL, sax_fastparser::UseIf(OString::number(oox::drawingml::convertHmmToEmu(nParaLeftMargin)), nParaLeftMargin > 0), - XML_indent, sax_fastparser::UseIf(OString::number(oox::drawingml::convertHmmToEmu(nParaFirstLineIndent)), nParaFirstLineIndent != 0), + XML_indent, sax_fastparser::UseIf(OString::number(!bForceZeroIndent ? oox::drawingml::convertHmmToEmu(nParaFirstLineIndent) : 0), (bForceZeroIndent || (nParaFirstLineIndent != 0))), XML_algn, GetAlignment( nAlignment ), XML_rtl, sax_fastparser::UseIf(ToPsz10(bRtl), bRtl)); else mpFS->startElementNS( XML_a, nElement, XML_lvl, sax_fastparser::UseIf(OString::number(nLevel), nLevel > 0), XML_marL, sax_fastparser::UseIf(OString::number(oox::drawingml::convertHmmToEmu(nLeftMargin)), nLeftMargin > 0), - XML_indent, sax_fastparser::UseIf(OString::number(oox::drawingml::convertHmmToEmu(nLineIndentation)), nLineIndentation != 0), + XML_indent, sax_fastparser::UseIf(OString::number(!bForceZeroIndent ? oox::drawingml::convertHmmToEmu(nLineIndentation) : 0), (bForceZeroIndent || ( nLineIndentation != 0))), XML_algn, GetAlignment( nAlignment ), XML_rtl, sax_fastparser::UseIf(ToPsz10(bRtl), bRtl)); @@ -3106,7 +3130,10 @@ bool DrawingML::WriteParagraphProperties( const Reference< XTextContent >& rPara mpFS->endElementNS( XML_a, XML_spcAft ); } - WriteParagraphNumbering( rXPropSet, fFirstCharHeight, nLevel ); + if (!bWriteNumbering) + mpFS->singleElementNS(XML_a, XML_buNone); + else + WriteParagraphNumbering( rXPropSet, fFirstCharHeight, nLevel ); WriteParagraphTabStops( rXPropSet ); diff --git a/oox/source/export/shapes.cxx b/oox/source/export/shapes.cxx index 9854c98a584e..305bc2e78f53 100644 --- a/oox/source/export/shapes.cxx +++ b/oox/source/export/shapes.cxx @@ -1949,6 +1949,9 @@ static const NameToConvertMapType& lcl_GetConverters() ShapeExport& ShapeExport::WriteShape( const Reference< XShape >& xShape ) { + if (!xShape) + throw lang::IllegalArgumentException(); + OUString sShapeType = xShape->getShapeType(); SAL_INFO("oox.shape", "write shape: " << sShapeType); NameToConvertMapType::const_iterator aConverter @@ -1958,6 +1961,16 @@ ShapeExport& ShapeExport::WriteShape( const Reference< XShape >& xShape ) SAL_INFO("oox.shape", "unknown shape"); return WriteUnknownShape( xShape ); } + + if (GetDocumentType() == DOCUMENT_PPTX) + { + Reference< XPropertySet > xShapeProperties(xShape, UNO_QUERY); + if (xShapeProperties && xShapeProperties->getPropertySetInfo() + && xShapeProperties->getPropertySetInfo()->hasPropertyByName("IsPresentationObject") + && xShapeProperties->getPropertyValue("IsPresentationObject").hasValue()) + mbPlaceholder = xShapeProperties->getPropertyValue("IsPresentationObject").get<bool>(); + } + (this->*(aConverter->second))( xShape ); return *this; diff --git a/sd/qa/unit/data/odp/testZeroIndent.odp b/sd/qa/unit/data/odp/testZeroIndent.odp new file mode 100644 index 000000000000..ead2c02687cc Binary files /dev/null and b/sd/qa/unit/data/odp/testZeroIndent.odp differ diff --git a/sd/qa/unit/export-tests-ooxml3.cxx b/sd/qa/unit/export-tests-ooxml3.cxx index 917142c61684..6100a9f64db6 100644 --- a/sd/qa/unit/export-tests-ooxml3.cxx +++ b/sd/qa/unit/export-tests-ooxml3.cxx @@ -56,6 +56,7 @@ public: void testTdf130058(); void testTdf111789(); void testTdf145162(); + void testZeroIndentExport(); void testTdf100348_convert_Fontwork2TextWarp(); void testTdf1225573_FontWorkScaleX(); void testTdf99497_keepAppearanceOfCircleKind(); @@ -139,6 +140,7 @@ public: CPPUNIT_TEST(testTdf130058); CPPUNIT_TEST(testTdf111789); CPPUNIT_TEST(testTdf145162); + CPPUNIT_TEST(testZeroIndentExport); CPPUNIT_TEST(testTdf100348_convert_Fontwork2TextWarp); CPPUNIT_TEST(testTdf1225573_FontWorkScaleX); CPPUNIT_TEST(testTdf99497_keepAppearanceOfCircleKind); @@ -662,6 +664,42 @@ void SdOOXMLExportTest3::testTdf145162() xDocShRef->DoClose(); } +void SdOOXMLExportTest3::testZeroIndentExport() +{ + // Load the bugdoc and save to pptx then. + sd::DrawDocShellRef xDocShRef + = loadURL(m_directories.getURLFromSrc(u"sd/qa/unit/data/odp/testZeroIndent.odp"), ODP); + utl::TempFile tempFile; + xDocShRef = saveAndReload(xDocShRef.get(), PPTX, &tempFile); + // There are 3 slides, get them + xmlDocUniquePtr pSlide1 = parseExport(tempFile, "ppt/slides/slide1.xml"); + xmlDocUniquePtr pSlide2 = parseExport(tempFile, "ppt/slides/slide2.xml"); + xmlDocUniquePtr pSlide3 = parseExport(tempFile, "ppt/slides/slide3.xml"); + + CPPUNIT_ASSERT(pSlide1); + CPPUNIT_ASSERT(pSlide2); + CPPUNIT_ASSERT(pSlide3); + + // Each slide has 3 paragraphs, one full line, an empty and a normal para. + // Check the indent and bullet. These have to match with PP. Before the fix, + // they were different. + assertXPath(pSlide1, "/p:sld/p:cSld/p:spTree/p:sp[2]/p:txBody/a:p[2]/a:pPr/a:buNone"); + + assertXPath(pSlide2, "/p:sld/p:cSld/p:spTree/p:sp[2]/p:txBody/a:p[1]/a:pPr/a:buNone"); + assertXPath(pSlide2, "/p:sld/p:cSld/p:spTree/p:sp[2]/p:txBody/a:p[1]/a:pPr", "indent", "0"); + assertXPath(pSlide2, "/p:sld/p:cSld/p:spTree/p:sp[2]/p:txBody/a:p[2]/a:pPr/a:buNone"); + assertXPath(pSlide2, "/p:sld/p:cSld/p:spTree/p:sp[2]/p:txBody/a:p[2]/a:pPr", "indent", "0"); + assertXPath(pSlide2, "/p:sld/p:cSld/p:spTree/p:sp[2]/p:txBody/a:p[3]/a:pPr/a:buNone"); + assertXPath(pSlide2, "/p:sld/p:cSld/p:spTree/p:sp[2]/p:txBody/a:p[3]/a:pPr", "indent", "0"); + + assertXPath(pSlide3, "/p:sld/p:cSld/p:spTree/p:sp[2]/p:txBody/a:p[1]/a:pPr", "indent", "0"); + assertXPath(pSlide3, "/p:sld/p:cSld/p:spTree/p:sp[2]/p:txBody/a:p[2]/a:pPr/a:buNone"); + assertXPath(pSlide3, "/p:sld/p:cSld/p:spTree/p:sp[2]/p:txBody/a:p[2]/a:pPr", "indent", "0"); + assertXPath(pSlide3, "/p:sld/p:cSld/p:spTree/p:sp[2]/p:txBody/a:p[3]/a:pPr", "indent", "0"); + + xDocShRef->DoClose(); +} + void SdOOXMLExportTest3::testTdf100348_convert_Fontwork2TextWarp() { ::sd::DrawDocShellRef xDocShRef = loadURL(