diff --git a/oox/inc/drawingml/textliststyle.hxx b/oox/inc/drawingml/textliststyle.hxx index 88de4621de13..282391452456 100644 --- a/oox/inc/drawingml/textliststyle.hxx +++ b/oox/inc/drawingml/textliststyle.hxx @@ -61,7 +61,7 @@ public: /// Set properties on xNumRules based on maListStyle, for all levels except nIgnoreLevel. void pushToNumberingRules(const css::uno::Reference& xNumRules, - size_t nIgnoreLevel); + std::optional nIgnoreLevel); #ifdef DBG_UTIL void dump() const; diff --git a/oox/qa/unit/drawingml.cxx b/oox/qa/unit/drawingml.cxx index 8b443970f691..2c38faff9285 100644 --- a/oox/qa/unit/drawingml.cxx +++ b/oox/qa/unit/drawingml.cxx @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -786,7 +787,7 @@ CPPUNIT_TEST_FIXTURE(OoxDrawingmlTest, testDOCXVerticalLineRotation) CPPUNIT_ASSERT_EQUAL(static_cast(0), nRotateAngle); } -CPPUNIT_TEST_FIXTURE(OoxDrawingmlTest, testPPTXImportOutlinerListStyleDirectFormat) +CPPUNIT_TEST_FIXTURE(OoxDrawingmlTest, testPPTXImportOutlinerListStyle) { // Given a PPTX file with a slide with an outline shape: // When loading that document: @@ -818,6 +819,27 @@ CPPUNIT_TEST_FIXTURE(OoxDrawingmlTest, testPPTXImportOutlinerListStyleDirectForm // - Actual : -800 CPPUNIT_ASSERT_EQUAL(static_cast(-889), nFirstLineOffset); // i.e. the sum of these two were 2800, not 1499, the indent was larger than expected. + + // Also check that the master slide's outliner has the correct numbering rules: + uno::Reference xMasterPagesSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference xMasterPage( + xMasterPagesSupplier->getMasterPages()->getByIndex(0), uno::UNO_QUERY); + // First would be the title shape. + uno::Reference xMasterShape(xMasterPage->getByIndex(1), uno::UNO_QUERY); + xShapeText.set(xMasterShape->getText(), uno::UNO_QUERY); + xParagraphs = xShapeText->createEnumeration(); + // As a sample, check the 2nd paragraph's level 3 left margin. + xParagraphs->nextElement(); + xParagraph.set(xParagraphs->nextElement(), uno::UNO_QUERY); + xParagraph->getPropertyValue(u"NumberingRules"_ustr) >>= xNumberingRules; + aMap = comphelper::SequenceAsHashMap(xNumberingRules->getByIndex(2)); + nLeftMargin = 0; + aMap["LeftMargin"] >>= nLeftMargin; + // Without the accompanying fix in place, this test would have failed with: + // - Expected: 2388 + // - Actual : 3600 + // i.e. the master was wrong, re-export to PPTX could not write the correct numbering rules. + CPPUNIT_ASSERT_EQUAL(static_cast(2388), nLeftMargin); } CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/oox/source/drawingml/shape.cxx b/oox/source/drawingml/shape.cxx index 8caf552a7ceb..dedfffde0f48 100644 --- a/oox/source/drawingml/shape.cxx +++ b/oox/source/drawingml/shape.cxx @@ -71,6 +71,7 @@ #include #include #include +#include #include #include #include @@ -914,6 +915,45 @@ Degree100 lcl_MSORotateAngleToAPIAngle(const sal_Int32 nMSORotationAngle) // API RotateAngle has opposite direction than nMSORotationAngle, thus 'minus'. return NormAngle36000(-nAngle); } + +void PushMasterTextListStyleToMasterShapeParagraphs(TextListStyle& rMasterTextListStyle, const uno::Reference& xShape) +{ + uno::Reference xShapeText(xShape, UNO_QUERY); + if (!xShapeText.is()) + { + return; + } + + uno::Reference xText(xShapeText->getText(), uno::UNO_QUERY); + if (!xText.is()) + { + return; + } + + uno::Reference xParagraphs = xText->createEnumeration(); + if (!xParagraphs.is()) + { + return; + } + + while (xParagraphs->hasMoreElements()) + { + uno::Reference xParagraph(xParagraphs->nextElement(), uno::UNO_QUERY); + if (!xParagraph.is()) + { + continue; + } + + uno::Reference xNumberingRules; + if (!(xParagraph->getPropertyValue("NumberingRules") >>= xNumberingRules)) + { + continue; + } + + rMasterTextListStyle.pushToNumberingRules(xNumberingRules, std::nullopt); + xParagraph->setPropertyValue("NumberingRules", uno::Any(xNumberingRules)); + } +} } Reference< XShape > const & Shape::createAndInsert( @@ -1286,6 +1326,7 @@ Reference< XShape > const & Shape::createAndInsert( } Reference< XPropertySet > xSet( mxShape, UNO_QUERY ); + bool bPlaceholderWithCustomPrompt = pPlaceholder && pPlaceholder->getCustomPrompt(); if (xSet.is()) { if (bTopWriterLine && !maSize.Width) @@ -2209,6 +2250,13 @@ Reference< XShape > const & Shape::createAndInsert( } } } + else if (mpTextBody && aServiceName == "com.sun.star.presentation.OutlinerShape" + && mpMasterTextListStyle && !bPlaceholderWithCustomPrompt) + { + // If mpTextBody is not empty, then the insertAt() above inserts formatted text. If it's + // empty, then we format the existing text of the outliner shape here. + PushMasterTextListStyleToMasterShapeParagraphs(*mpMasterTextListStyle, mxShape); + } else if (mbTextBox) { // No drawingML text, but WPS text is expected: save the theme diff --git a/oox/source/drawingml/textliststyle.cxx b/oox/source/drawingml/textliststyle.cxx index ee695908d48a..0ad0b5108b27 100644 --- a/oox/source/drawingml/textliststyle.cxx +++ b/oox/source/drawingml/textliststyle.cxx @@ -70,7 +70,7 @@ void TextListStyle::apply( const TextListStyle& rTextListStyle ) } void TextListStyle::pushToNumberingRules(const uno::Reference& xNumRules, - size_t nIgnoreLevel) + std::optional oIgnoreLevel) { TextParagraphPropertiesArray& rListStyle = getListStyle(); size_t nLevels = xNumRules->getCount(); @@ -81,7 +81,7 @@ void TextListStyle::pushToNumberingRules(const uno::Reference 0) + { + // The opposite of this would be exported as to ODF, where negative values are not allowed. + nFirstLineIndentation = 0; + } + aMap["FirstLineOffset"] <<= nFirstLineIndentation; bChanged = true; }