summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSarper Akdemir <sarper.akdemir.extern@allotropia.de>2024-03-06 13:48:14 +0300
committerChristian Lohmaier <lohmaier+LibreOffice@googlemail.com>2024-03-19 18:03:07 +0100
commita20c366364bdfea41bd9063bd8801d5bb59c0092 (patch)
tree1f5538b5af84e42ebffc457866fccb6c02ad931a
parenttdf#159373: band-aid for crash in: ScTable::HasAttrib (diff)
downloadcore-a20c366364bdfea41bd9063bd8801d5bb59c0092.tar.gz
core-a20c366364bdfea41bd9063bd8801d5bb59c0092.zip
tdf#159931: pptx export: export each used slide layout for a master
attempts to fix the slideLayout reference related regression from Idb6b88ebe87a83818d8eb27a1fa087652a002c0c. To correctly export the all used slideLayout instances for a given master, iterate through sdr::PageUsers of that master and figure out all used layouts. Change-Id: I0f58befac1ba4d5ec01aeedbb5f611c83683dcf8 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/164468 Tested-by: Jenkins Reviewed-by: Balazs Varga <balazs.varga.extern@allotropia.de> Reviewed-by: Sarper Akdemir <sarper.akdemir.extern@allotropia.de> (cherry picked from commit a35831becee3781daf8628c48944660d31d84d8b) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/164542 (cherry picked from commit a8f058e8ab02643ac2c8d6b6d8fcb3ab45fcf79f) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/164670 Reviewed-by: Michael Stahl <michael.stahl@allotropia.de> Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org> Reviewed-by: Michael Weghorn <m.weghorn@posteo.de> Tested-by: Christian Lohmaier <lohmaier+LibreOffice@googlemail.com> Reviewed-by: Christian Lohmaier <lohmaier+LibreOffice@googlemail.com>
-rw-r--r--include/svx/sdrmasterpagedescriptor.hxx3
-rw-r--r--include/svx/sdrpageuser.hxx3
-rw-r--r--include/svx/svdpage.hxx1
-rw-r--r--sd/qa/unit/export-tests-ooxml3.cxx47
-rw-r--r--sd/source/filter/eppt/pptx-epptooxml.cxx38
5 files changed, 84 insertions, 8 deletions
diff --git a/include/svx/sdrmasterpagedescriptor.hxx b/include/svx/sdrmasterpagedescriptor.hxx
index d7eac22a1b5c..9be1e663bcff 100644
--- a/include/svx/sdrmasterpagedescriptor.hxx
+++ b/include/svx/sdrmasterpagedescriptor.hxx
@@ -22,6 +22,7 @@
#include <svx/sdrpageuser.hxx>
#include <svx/svdsob.hxx>
+#include <svx/svxdllapi.h>
#include <memory>
class SdrPageProperties;
@@ -30,7 +31,7 @@ namespace sdr::contact { class ViewContact; }
namespace sdr
{
- class MasterPageDescriptor final : public sdr::PageUser
+ class SVXCORE_DLLPUBLIC MasterPageDescriptor final : public sdr::PageUser
{
private:
SdrPage& maOwnerPage;
diff --git a/include/svx/sdrpageuser.hxx b/include/svx/sdrpageuser.hxx
index 8c31a2936c7e..5557b2729777 100644
--- a/include/svx/sdrpageuser.hxx
+++ b/include/svx/sdrpageuser.hxx
@@ -21,6 +21,7 @@
#define INCLUDED_SVX_SDRPAGEUSER_HXX
#include <vector>
+#include <svx/svxdllapi.h>
class SdrPage;
@@ -30,7 +31,7 @@ class SdrPage;
namespace sdr
{
- class PageUser
+ class SVXCORE_DLLPUBLIC PageUser
{
public:
// this method is called from the destructor of the referenced page.
diff --git a/include/svx/svdpage.hxx b/include/svx/svdpage.hxx
index 6a65712719f1..76ab049055ca 100644
--- a/include/svx/svdpage.hxx
+++ b/include/svx/svdpage.hxx
@@ -398,6 +398,7 @@ private:
public:
void AddPageUser(sdr::PageUser& rNewUser);
void RemovePageUser(sdr::PageUser& rOldUser);
+ const sdr::PageUserVector& GetPageUsers() const { return maPageUsers; };
// SdrModel access on SdrPage level
SdrModel& getSdrModelFromSdrPage() const { return mrSdrModelFromSdrPage; }
diff --git a/sd/qa/unit/export-tests-ooxml3.cxx b/sd/qa/unit/export-tests-ooxml3.cxx
index 6a66e59af884..a0f36fe0688a 100644
--- a/sd/qa/unit/export-tests-ooxml3.cxx
+++ b/sd/qa/unit/export-tests-ooxml3.cxx
@@ -2011,6 +2011,53 @@ CPPUNIT_TEST_FIXTURE(SdOOXMLExportTest3, testTableCellVerticalPropertyRoundtrip)
assertXPath(pXml, "(//a:tcPr)[3]", "vert", "wordArtVert");
}
+CPPUNIT_TEST_FIXTURE(SdOOXMLExportTest3, testTdf159931_slideLayouts)
+{
+ createSdImpressDoc("odp/repeatBitmapMode.odp");
+ save("Impress Office Open XML");
+
+ xmlDocUniquePtr pXmlDocRels1 = parseExport("ppt/slides/_rels/slide1.xml.rels");
+ xmlDocUniquePtr pXmlDocRels2 = parseExport("ppt/slides/_rels/slide2.xml.rels");
+
+ assertXPath(pXmlDocRels1, "(/rels:Relationships/rels:Relationship[@Type='http://"
+ "schemas.openxmlformats.org/officeDocument/2006/relationships/"
+ "slideLayout'])");
+
+ // the relative target e.g. "../slideLayouts/slideLayout2.xml"
+ OUString sRelativeLayoutPath1
+ = getXPathContent(pXmlDocRels1, "(/rels:Relationships/rels:Relationship[@Type='http://"
+ "schemas.openxmlformats.org/officeDocument/2006/"
+ "relationships/slideLayout'])/@Target");
+
+ assertXPath(pXmlDocRels2, "(/rels:Relationships/rels:Relationship[@Type='http://"
+ "schemas.openxmlformats.org/officeDocument/2006/relationships/"
+ "slideLayout'])");
+
+ // the relative target e.g. "../slideLayouts/slideLayout1.xml"
+ OUString sRelativeLayoutPath2
+ = getXPathContent(pXmlDocRels2, "(/rels:Relationships/rels:Relationship[@Type='http://"
+ "schemas.openxmlformats.org/officeDocument/2006/"
+ "relationships/slideLayout'])/@Target");
+
+ uno::Reference<packages::zip::XZipFileAccess2> xNameAccess
+ = packages::zip::ZipFileAccess::createWithURL(comphelper::getComponentContext(m_xSFactory),
+ maTempFile.GetURL());
+
+ // 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 sSlideLayoutName1 = sRelativeLayoutPath1.getToken(2, '/');
+ OUString sSlideLayoutName2 = sRelativeLayoutPath2.getToken(2, '/');
+
+ CPPUNIT_ASSERT_EQUAL(true,
+ bool(xNameAccess->hasByName("ppt/slideLayouts/" + sSlideLayoutName1)));
+ CPPUNIT_ASSERT_EQUAL(true,
+ bool(xNameAccess->hasByName("ppt/slideLayouts/" + sSlideLayoutName2)));
+}
+
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 0967b6a3b34e..2bf374c3d216 100644
--- a/sd/source/filter/eppt/pptx-epptooxml.cxx
+++ b/sd/source/filter/eppt/pptx-epptooxml.cxx
@@ -63,6 +63,7 @@
#include "../ppt/pptanimations.hxx"
#include <i18nlangtag/languagetag.hxx>
+#include <svx/sdrmasterpagedescriptor.hxx>
#include <svx/svdpage.hxx>
#include <svx/unoapi.hxx>
#include <svx/svdogrp.hxx>
@@ -1515,23 +1516,48 @@ void PowerPointExport::ImplWriteSlideMaster(sal_uInt32 nPageNum, Reference< XPro
// use master's id type as they have same range, mso does that as well
pFS->startElementNS(XML_p, XML_sldLayoutIdLst);
- sal_Int32 nLayout = 0;
- OUString aSlideName;
- css::uno::Reference< css::beans::XPropertySet >xPagePropSet;
+ auto getLayoutsUsedForMaster = [](SdrPage* pMaster) -> std::unordered_set<sal_Int32>
+ {
+ if (!pMaster)
+ return {};
+
+ std::unordered_set<sal_Int32> aUsedLayouts{};
+ for (const auto* pPageUser : pMaster->GetPageUsers())
+ {
+ const auto* pMasterPageDescriptor
+ = dynamic_cast<const sdr::MasterPageDescriptor*>(pPageUser);
+
+ if (!pMasterPageDescriptor)
+ continue;
+
+ AutoLayout eLayout
+ = static_cast<SdPage&>(pMasterPageDescriptor->GetOwnerPage()).GetAutoLayout();
+ aUsedLayouts.insert(eLayout);
+ }
+ return aUsedLayouts;
+ };
+
+ std::unordered_set<sal_Int32> aLayouts = getLayoutsUsedForMaster(pMasterPage);
+
+ css::uno::Reference< css::beans::XPropertySet > xPagePropSet;
xPagePropSet.set(mXDrawPage, UNO_QUERY);
if (xPagePropSet.is())
{
uno::Any aAny;
if (GetPropertyValue(aAny, xPagePropSet, "SlideLayout"))
- aAny >>= nLayout;
+ aLayouts.insert(aAny.get<sal_Int32>());
}
+ OUString aSlideName;
Reference< XNamed > xNamed(mXDrawPage, UNO_QUERY);
if (xNamed.is())
aSlideName = xNamed->getName();
- ImplWritePPTXLayout(nLayout, nPageNum, aSlideName);
- AddLayoutIdAndRelation(pFS, GetLayoutFileId(nLayout, nPageNum));
+ for (auto nLayout : aLayouts)
+ {
+ ImplWritePPTXLayout(nLayout, nPageNum, aSlideName);
+ AddLayoutIdAndRelation(pFS, GetLayoutFileId(nLayout, nPageNum));
+ }
pFS->endElementNS(XML_p, XML_sldLayoutIdLst);