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 638a69d1c533b8276bac056f6b396876dcd21783
Author:     Jaume Pujantell <jaume.pujant...@collabora.com>
AuthorDate: Mon Feb 3 11:06:28 2025 +0100
Commit:     Xisco Fauli <xiscofa...@libreoffice.org>
CommitDate: Tue Feb 4 15:46:59 2025 +0100

    tdf#165036: 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
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/181070
    Tested-by: Jenkins
    Reviewed-by: Jaume Pujantell <jaume.pujant...@collabora.com>
    Signed-off-by: Xisco Fauli <xiscofa...@libreoffice.org>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/181109

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 74862adca919..4cf8e852267b 100644
--- a/sd/qa/unit/export-tests-ooxml4.cxx
+++ b/sd/qa/unit/export-tests-ooxml4.cxx
@@ -1311,6 +1311,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 dbc12fac58e7..054d116e095e 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 single 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 written later
+                if (mLayoutInfo[nLayout].mnFileIdArray.size() < mnMasterPages)
+                    mLayoutInfo[nLayout].mnFileIdArray.resize(mnMasterPages);
+                mLayoutInfo[nLayout].mnFileIdArray[i] = mnLayoutFileIdMax;
+                mnLayoutFileIdMax++;
+
+                AddLayoutIdAndRelation(pFS, GetLayoutFileId(nLayout, i));
+            }
         }
     }
 

Reply via email to