sd/qa/unit/data/odp/dupmastermultlayouts.odp |binary sd/qa/unit/export-tests-ooxml4.cxx | 35 +++++++++++++++++++++++ sd/source/filter/eppt/pptx-epptooxml.cxx | 40 ++++++++++++++++----------- 3 files changed, 60 insertions(+), 15 deletions(-)
New commits: commit b766b917517b95982002abe8eb034ca9c55a2a5b Author: Jaume Pujantell <jaume.pujant...@collabora.com> AuthorDate: Mon Feb 3 11:06:28 2025 +0100 Commit: Miklos Vajna <vmik...@collabora.com> CommitDate: Mon Feb 3 12:58:06 2025 +0100 sd: pptx export every layout used Regression from commit 9205b4eb09dcb4c91539e092db521154fc4e9523. On conversion from odp or ppt to pptx, some slide layouts were not saved if their masters were seen as equivalent. When reducing duplicated masters, only the layouts used in the Impress masters were saved for each duplicated masters. But when converting from other formats that handle masters/layouts differently it's necessary to search for all used layouts in each Impress slide that uses each duplicated master. Change-Id: Ie27852e7c0ff0b160a4e2415669f5e615c46e2f9 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/181030 Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com> Reviewed-by: Miklos Vajna <vmik...@collabora.com> diff --git a/sd/qa/unit/data/odp/dupmastermultlayouts.odp b/sd/qa/unit/data/odp/dupmastermultlayouts.odp new file mode 100644 index 000000000000..c68ade8a08e1 Binary files /dev/null and b/sd/qa/unit/data/odp/dupmastermultlayouts.odp differ diff --git a/sd/qa/unit/export-tests-ooxml4.cxx b/sd/qa/unit/export-tests-ooxml4.cxx index ada03b88a2dc..d60946adb451 100644 --- a/sd/qa/unit/export-tests-ooxml4.cxx +++ b/sd/qa/unit/export-tests-ooxml4.cxx @@ -1198,6 +1198,41 @@ CPPUNIT_TEST_FIXTURE(SdOOXMLExportTest4, testDeduplicateMasters) CPPUNIT_ASSERT_EQUAL(Color(0x000000), nColor); } +CPPUNIT_TEST_FIXTURE(SdOOXMLExportTest4, testConvertWithMasterDeduplication) +{ + createSdImpressDoc("odp/dupmastermultlayouts.odp"); + save("Impress Office Open XML"); + + uno::Reference<packages::zip::XZipFileAccess2> xNameAccess + = packages::zip::ZipFileAccess::createWithURL(comphelper::getComponentContext(m_xSFactory), + maTempFile.GetURL()); + + // For each slide check that it's layout exists + for (int i = 1; i <= 4; ++i) + { + xmlDocUniquePtr pXmlDocRels + = parseExport("ppt/slides/_rels/slide" + OUString::number(i) + ".xml.rels"); + + assertXPath( + pXmlDocRels, + "(/rels:Relationships/rels:Relationship[@Type='http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout'])"_ostr); + // the relative target e.g. "../slideLayouts/slideLayout2.xml" + OUString sRelativeLayoutPath = getXPathContent( + pXmlDocRels, + "(/rels:Relationships/rels:Relationship[@Type='http://schemas.openxmlformats.org/officeDocument/2006/relationships/slideLayout'])/@Target"_ostr); + + // Check that the referenced slideLayout files exist + // Without the accompanying fix in place, this test would have failed with: + // equality assertion failed + // - Expected: 1 + // - Actual : 0 + // i.e. the referenced slideLayout file was missing on export. + OUString sSlideLayoutName = sRelativeLayoutPath.getToken(2, '/'); + CPPUNIT_ASSERT_EQUAL(true, + bool(xNameAccess->hasByName("ppt/slideLayouts/" + sSlideLayoutName))); + } +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sd/source/filter/eppt/pptx-epptooxml.cxx b/sd/source/filter/eppt/pptx-epptooxml.cxx index a9f2fa4603ab..1e4b10dde411 100644 --- a/sd/source/filter/eppt/pptx-epptooxml.cxx +++ b/sd/source/filter/eppt/pptx-epptooxml.cxx @@ -1569,15 +1569,18 @@ void PowerPointExport::ImplWriteSlideMaster(sal_uInt32 nPageNum, Reference< XPro if (nPageNum != GetEquivalentMasterPage(nPageNum) && GetEquivalentMasterPage(nPageNum) != SAL_MAX_UINT32) { - // It's equivalent to an already written master, write only the layout file - if (maMastersLayouts[nPageNum].second != -1) + // It's equivalent to an already written master, write only the layouts files + OUString aSlideName; + Reference<XNamed> xNamed(mXDrawPage, UNO_QUERY); + if (xNamed.is()) + aSlideName = xNamed->getName(); + for (int i = 0; i < OOXML_LAYOUT_SIZE; ++i) { - OUString aSlideName; - Reference<XNamed> xNamed(mXDrawPage, UNO_QUERY); - if (xNamed.is()) - aSlideName = xNamed->getName(); - ImplWritePPTXLayoutWithContent(maMastersLayouts[nPageNum].second, nPageNum, aSlideName, - aXBackgroundPropSet); + if (mLayoutInfo[i].mnFileIdArray.size() > nPageNum + && mLayoutInfo[i].mnFileIdArray[nPageNum] > 0) + { + ImplWritePPTXLayoutWithContent(i, nPageNum, aSlideName, aXBackgroundPropSet); + } } // Close the list tag if it was the last one @@ -1764,15 +1767,22 @@ void PowerPointExport::ImplWriteSlideMaster(sal_uInt32 nPageNum, Reference< XPro // Add layouts of other Impress masters that came from a sinlge pptx master with multiple layouts for (sal_uInt32 i = 0; i < mnMasterPages; i++) { - if (i != nPageNum && maEquivalentMasters[i] == nPageNum && maMastersLayouts[i].second != -1) + if (i != nPageNum && maEquivalentMasters[i] == nPageNum) { - // Reserve layout file Id to be writen later - if (mLayoutInfo[maMastersLayouts[i].second].mnFileIdArray.size() < mnMasterPages) - mLayoutInfo[maMastersLayouts[i].second].mnFileIdArray.resize(mnMasterPages); - mLayoutInfo[maMastersLayouts[i].second].mnFileIdArray[i] = mnLayoutFileIdMax; - mnLayoutFileIdMax++; + aLayouts = getLayoutsUsedForMaster(maMastersLayouts[i].first); + if (maMastersLayouts[i].second != -1) + aLayouts.insert(maMastersLayouts[i].second); - AddLayoutIdAndRelation(pFS, GetLayoutFileId(maMastersLayouts[i].second, i)); + for (auto nLayout : aLayouts) + { + // Reserve layout file Id to be writen later + if (mLayoutInfo[nLayout].mnFileIdArray.size() < mnMasterPages) + mLayoutInfo[nLayout].mnFileIdArray.resize(mnMasterPages); + mLayoutInfo[nLayout].mnFileIdArray[i] = mnLayoutFileIdMax; + mnLayoutFileIdMax++; + + AddLayoutIdAndRelation(pFS, GetLayoutFileId(nLayout, i)); + } } }