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(

Reply via email to