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 f57cfddb51
"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 <nemeth@numbertext.org>
Reviewed-by: László Németh <nemeth@numbertext.org>
This commit is contained in:
Attila Bakos (NISZ) 2022-05-26 17:04:54 +02:00 committed by László Németh
parent b94275f6d2
commit 445d4ce232
5 changed files with 95 additions and 14 deletions

View file

@ -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; }

View file

@ -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 );

View file

@ -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;

Binary file not shown.

View file

@ -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(